What is DNS Privacy and how to set it up for OpenWRT

The Domain Name System (DNS) enables your computer to find the actual addresses of other computers. So when you type fsfe.org in your browser, the DNS tells you that is the actual IP address for fsfe.org. It needs this real address to make a connection to that server and present the website hosted there to you.

DNS requests leak a lot of data to anybody who can read your network traffic, because they are typically not encrypted. Every server/site you visit will be leaked in a DNS request.

To solve this problem, there is DNS Privacy, a project dedicated to improve privacy around DNS. The most obvious solution is to encrypt the DNS requests, so someone looking at your internet traffic doesn’t see anymore which sites you visit just by looking into your DNS queries.

There’s many different ways to encrypt this information. I will focus on DNS over TLS as this seems to be the best solution at the moment and is relatively easy to set up.

Everything you own that is connected to the internet is making DNS requests. You could of course try to set all of these devices up for DNS over TLS individually, but that is mostly not even possible and a lot of work. If you just have one local desktop or laptop computer, you can use Stubby a local DNS Privacy stub resolver. The solution I recommend is to set up DNS Privacy directly on your router, so all devices entering the internet via this router (and using it for DNS queries) will benefit from it.

DNS over TLS for OpenWRT

OpenWRT (or LEDE) is a Free Software operating system for routers. The following assumes that you are running the latest version of OpenWRT (at the moment LEDE 17.01.4).

Log into your router via ssh and then run:

# Install unbound (System -> Software -> Find package: unbound -> Install)
opkg install unbound

Add some more privacy options to the unbound server config:

cat >> /etc/unbound/unbound_srv.conf <<UNBOUND_SERVER_CONF
do-tcp: yes
prefetch: yes
qname-minimisation: yes
rrset-roundrobin: yes
use-caps-for-id: yes

# Don't let each server know the next recursion.
uci set 'unbound.@unbound[0].query_minimize=1'

Now, the important part comes. It tells unbound to forward all (except local) DNS requests to special DNS resolvers that allow you to connect encrypted with TLS on port 853.

cat >> /etc/unbound/unbound_ext.conf <<UNBOUND_FORWARD_CONF
        name: "."
        forward-addr:         # quad9.net primary
        forward-addr: # quad9.net secondary
        forward-addr:  # Surfnet primary
        forward-addr:  # Surfnet secondary
        forward-addr:   # getdnsapi.net
        forward-ssl-upstream: yes

The last option turns on DNS over TLS.

Now, you just need to move the existing dnsmasq server aside, so unbound can answer your devices DNS queries.

# Move dnsmasq to port 53535 where it will still serve local DNS from DHCP
# Network -> DHCP & DNS -> Advanced Settings -> DNS server port to 53535
uci set 'dhcp.@dnsmasq[0].port=53535'

# Configure dnsmasq to send a DNS Server DHCP option with its LAN IP
# since it does not do this by default when port is configured.
uci add_list "dhcp.lan.dhcp_option=option:dns-server,$(uci get network.lan.ipaddr)"
uci set 'unbound.@unbound[0].dhcp_link=dnsmasq'

# Save & Apply (will restart dnsmasq, DNS unreachable until unbound is up)
uci commit

# Restart (or start) unbound (System -> Startup -> unbound -> Restart)
/etc/init.d/unbound restart

Now you can test your DNS queries:

nslookup fsfe.org

If this works, your DNS requests should now be made over TLS and even cached locally by unbound. If you have problems, try the¬†logread command to see what is going on. If you want to further tune the settings, checkout OpenWRT’s awesome unbound README.

Note: The DNS servers you use can of course still see your requests and the domains in them. Only passive network observers get locked out by using DNS over TLS.

Comments are closed.