DNS improvements in FreeBSD 11

Erwin Lansing just posted a summary of the DNS session at the FreeBSD DevSummit that was held in conjunction with BSDCan 2014 in May. It gives a good overview of the current state of affairs, including known bugs and plans for the future.

I’ve been working on some of these issues recently (in between $dayjob and other projects). I fixed two issues in the last 48 hours, and am working on two more.

Reverse lookups in private networks

Fixed in 11.

In its default configuration, Unbound 1.4.22 does not allow reverse lookups for private addresses (RFC 1918 and the like). NLNet backported a patch from the development version of Unbound which adds a configuration option, unblock-lan-zones, which disables this filtering. But that alone is not enough, because the reverse zones are actually signed (EDIT: the problem is more subtle than that, details in comments); Unbound will attempt to validate the reply, and will reject it because the zone is supposed to be empty. Thus, for reverse lookups to work, the reverse zones for all private address ranges must be declared as insecure:

server:
    # Unblock reverse lookups for LAN addresses
    unblock-lan-zones: yes
    domain-insecure:      10.in-addr.arpa.
    domain-insecure:     127.in-addr.arpa.
    domain-insecure: 254.169.in-addr.arpa.
    domain-insecure:  16.172.in-addr.arpa.
    # ...
    domain-insecure:  31.172.in-addr.arpa.
    domain-insecure: 168.192.in-addr.arpa.
    domain-insecure: 8.e.ip6.arpa.
    domain-insecure: 9.e.ip6.arpa.
    domain-insecure: a.e.ip6.arpa.
    domain-insecure: b.e.ip6.arpa.
    domain-insecure: d.f.ip6.arpa.

FreeBSD 11 now has both the unblock-lan-zones patch and an updated local-unbound-setup script which sets up the reverse zones. To take advantage of this, simply run the following command to regenerate your configuration:

# service local_unbound setup

This feature will be available in FreeBSD 10.1.

Building libunbound writes to /usr/src (#190739)

Fixed in 11.

The configuration lexer and parser were included in the source tree instead of being generated at build time. Under certain circumstances, make(1) would decide that they needed to be regenerated. At best, this inserted spurious changes into the source tree; at worst, it broke the build.

Part of the reason for this is that Unbound uses preprocessor macros to place the code generated by lex(1) and yacc(1) in its own separate namespace. FreeBSD’s lex(1) is actually Flex, which has a command-line option to achieve the same effect in a much simpler manner, but to take advantage of this, the lexer needed to be cleaned up a bit.

Allow local domain control sockets

Work in progress

An Unbound server can be controlled by sending commands (such as “reload your configuration file”, “flush your cache”, “give me usage statistics”) over a control socket. Currently, this can only be a TCP socket. Ilya Bakulin has developed a patch, which I am currently testing, that allows Unbound to use a local domain (aka “unix”) socket instead.

Allow unauthenticated control sockets

Work in progress

If the control socket is a local domain socket instead of a TCP socket, there is no need for encryption and little need for authentication. In the local resolver case, only root on the local machine needs access, and this can be enforced by the ownership and file permissions of the socket. A second patch by Ilya Bakulin makes encryption and authentication optional so there is no need to generate and store a client certificate in order to use unbound-control(8).

4 thoughts on “DNS improvements in FreeBSD 11”

  1. Hi,

    could you elaborate on the reverse private range lookups and with which forwarding mechanism this holds ? stub-zones or with a forwarder.

    Thanks :)

    1. Forwarding, of course. I’m talking about the local_unbound service in FreeBSD 10 / 11, which is always either forwarding or recursing, depending on what was in your /etc/resolv.conf when you enabled it. A recursing resolver should never encounter RFC 1918 addresses.

  2. Where is the signed RFC1918 zone coming from? It seems fairly clear from RFC 6303 that they shouldn’t be signed (publicly).

    1. With a cold cache, request a PTR record for “1.0.168.192.in-addr.arpa.”. Unbound forwards it, then tries to validate the answer:

      1. request DNSKEY record for “.”, get an answer
      2. request DS record for “arpa.”, get an answer
      3. request DNSKEY record for “arpa.”, get an answer
      4. request DS record for “in-addr.arpa.”, get an answer
      5. request DNSKEY record for “in-addr.arpa.”, get an answer
      6. request DS record for “192.in-addr.arpa.”, get an answer
      7. request DNSKEY record for “192.in-addr.arpa.”, get an answer
      8. request DS record for “168.192.in-addr.arpa.”, no answer

      at which point Unbound concludes that the answer it got to its initial query was invalid.

      So my statement that the reverse zone is signed is not quite correct. What seems to be the case is that the “192.in-addr.arpa.” zone is signed yet the answer Unbound gets for “168.192.in-addr.arpa.” is unsigned. I think this may be caused by server software that intercepts requests for RFC 1918 reverse zones, so that requests for “168.192.in-addr.arpa.” or anything below it get an unsigned, empty answer with a blackhole SOA, which is deemed invalid.

      This would explain why some people reported that reverse lookups of private addresses work fine, while they never worked for me: it depends on what’s upstream from you.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.