DNS over TLS in FreeBSD with Quad9

It has come to my attention that Quad9 have a blog post providing incorrect instructions for how to set up a FreeBSD system to use their service. I have attempted to get in touch with the author and get him to correct it but have received no response. So here, for the benefit of the Great Search Engine Gods, is the correct procedure; see my earlier post on the topic for more details on how it works.

# cat >/etc/rc.conf.d/local_unbound <<EOF
local_unbound_enable="yes"
local_unbound_tls="yes"
local_unbound_forwarders="9.9.9.9@853#dns.quad9.net 149.112.112.112@853#dns.quad9.net 2620:fe::fe@853#dns.quad9.net 2620:fe::9@853#dns.quad9.net"
EOF
# service local_unbound setup
# service local_unbound restart

No need to reboot.

Note that if you only have IPv4, you may experience slightly degraded performance unless you leave out the IPv6 addresses from the local_unbound_forwarders line (and vice versa in the unlikely scenario where you only have IPv6).

DNS over TLS in FreeBSD 12

With the arrival of OpenSSL 1.1.1, an upgraded Unbound, and some changes to the setup and init scripts, FreeBSD 12, currently in beta, now supports DNS over TLS out of the box. We show how to set it up and discuss its advantages and disadvantages.

With the arrival of OpenSSL 1.1.1, an upgraded Unbound, and some changes to the setup and init scripts, FreeBSD 12.0, currently in beta, now supports DNS over TLS out of the box.

DNS over TLS is just what it sounds like: DNS over TCP, but wrapped in a TLS session. It encrypts your requests and the server’s replies, and optionally allows you to verify the identity of the server. The advantages are protection against eavesdropping and manipulation of your DNS traffic; the drawbacks are a slight performance degradation and potential firewall traversal issues, as it runs over a non-standard port (TCP port 853) which may be blocked on some networks. Let’s take a look at how to set it up.

Continue reading “DNS over TLS in FreeBSD 12”

FreeBSD and CVE-2015-7547

As you have probably heard by now, a buffer overflow was recently discovered in GNU libc’s resolver code which can allow a malicious DNS server to inject code into a vulnerable client. This was announced yesterday as CVE-2015-7547. The best sources of information on the bug are currently Google’s Online Security Blog and Carlos O’Donnell’s in-depth analysis.

Naturally, people have started asking whether FreeBSD is affected. The FreeBSD Security Officer has not yet released an official statement, but in the meantime, here is a brief look at the issue as far as FreeBSD is concerned.

Continue reading “FreeBSD and CVE-2015-7547”

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.

Continue reading “DNS improvements in FreeBSD 11”

VerifyHostKeyDNS

The Internet Society likes my work. I aim to please…

One of the things I did in the process of importing LDNS and Unbound into FreeBSD 10 was to change the default value for VerifyHostKeyDNS from “no” to “yes” in our OpenSSH when compiled with LDNS support (which can be turned off by adding WITHOUT_LDNS=YES to /etc/src.conf before buildworld).

The announcement the ISOC blog post refers to briefly explains my reasons for doing so:

I consider this a lesser evil than “ask” (aka “train the user to type ‘yes’ and hit enter”) and “no” (aka “train the user to type ‘yes’ and hit enter without even the benefit of a second opinion”).

There were objections to this (which I’m too lazy to dig up and quote) along the lines of:

  • Shouldn’t OpenSSH tell you that it found and used an SSHFP record?
  • Shouldn’t known_hosts entries take precedence over SSHFP records?
  • Shouldn’t OpenSSH store the key in known_hosts after verifying it against an SSHFP record?

The answer to all of the above is “yes, but…”

Here is how host key verification should work, ideally:

  1. Obtain host key from server
  2. Gather cached host keys from various sources (known_hosts, SSHFP, LDAP…)
  3. If we found one or more cached keys:
    1. Check for and warn about inconsistencies between these sources
    2. Check for and warn about inconsistencies between the cached key and what the server sent us
    3. If we got a match from a trusted source, continue connecting
    4. Inform the user of any matches from untrusted sources
  4. Display the key’s fingerprint
  5. Ask the user whether to:
    1. Store the server’s key for future reference and continue connecting
    2. Continue connecting without storing the key
    3. Disconnect

The only configuration required here is a list of trusted and untrusted sources, the difference being that a match or mismatch from a trusted source is normative while a match or mismatch from an untrusted source is merely informative.

Unfortunately, in OpenSSH, SSHFP support seems to have been grafted onto the existing logic rather than integrated into it. Here’s how it actually works:

  1. Obtain host key from server
  2. If VerifyHostKeyDNS is “yes” or “ask”, look for SSHFP records in DNS
  3. If an SSHFP record was found:
    1. If it matches the server’s key:
      1. If it has a valid DNSSEC signature and VerifyHostKeyDNS is “yes”, continue connecting
      2. Otherwise, set a flag to indicate that a matching SSHFP record was found
    2. Otherwise, warn about the mismatch
  4. Look for cached keys in the user and system host key files
  5. If we got a match from the host key files, continue connecting
  6. If we did not find anything in the host key files:
    1. If we found a matching SSHFP record, tell the user
    2. Ask the user whether to:
      1. Store the server’s key for future reference and continue connecting
      2. Disconnect
  7. If we found a matching revoked key in the host key files, warn the user and terminate
  8. If we found a different key in the host key files, warn the user and terminate

Part of the problem is that at the point where we tell the user that we found a matching SSHFP record, we no longer know whether it was signed. By switching the default for VerifyHostKeyDNS to “yes”, I’m basically saying that I trust DNSSEC more than I trust the average user’s ability to understand the information they’re given and make an informed decision.