Configuring Unbound for Downstream DoT

Quite some time ago, I wrote some documentation on how to stand up a DNS-over-TLS server using a Nginx reverse streams proxy to terminate the SSL.

However, since then (in fact, back in 1.6.7) Unbound released support for directly terminating TLS connections.

This documentation details the (simple) config changes necessary to configure Unbound to service DNS over TLS (RFC 7858) queries.

 

You will need to have a copy of Unbound >= 1.6.7 installed (and, of course, you should really be running the latest release)

Within the config file (normally /etc/unbound/unbound.conf) you'll need to add the following within the server block

    interface: 0.0.0.0@853
    interface: ::0@853
    tls-port: 853

    tls-service-key: [path to your SSL Key]
    tls-service-pem: [path to your SSL cert]
 
    access-control: 0.0.0.0/0 allow

You then simply need to restart unbound and can then confirm it's listening

systemctl restart unbound
netstat -lnp | grep 853

As we only want to accept TCP connections (to reduce opportunity for us to be used in a reflection attack, we firewall UDP 853

iptables -I INPUT -p udp --dport 853 -j DROP

 

Important Notes

If, like me, you acquire the SSL cert via LetsEncrypt (or will otherwise automate it's deployment), unbound must be restarted - not reloaded - when the cert/key change. This is because it reads the key before dropping privileges, so reads do not happen during a simple config reload

 

Rate Limiting

Unbound itself contains various config keys to allow rate limiting, however, my preference is to also limit at the firewall.

iptables -N DOT-RATE-LIMIT
iptables -A DOT-RATE-LIMIT -m hashlimit --hashlimit-mode srcip --hashlimit-upto 30/sec --hashlimit-burst 20 --hashlimit-name dot_conn_rate_limit --jump ACCEPT
iptables -A DOT-RATE-LIMIT -m limit --limit 1/sec --jump LOG --log-prefix "IPTables-Ratelimited: "
iptables -A RATE-LIMIT -j DROP
iptables -I INPUT -p tcp --dport 853 -m conntrack --ctstate NEW -j DOT-RATE-LIMIT

This will limit new connections to 30 per sec, per client IP. Even this is probably set a little high.