[Guide] Enabling DNS-over-TLS on an OpenWRT Router

Thursday, April 23, 2020

Traditional DNS queries (mapping a domain name to an IP address) are sent in plain-text and are not private. Enabling DNS-over-TLS on your router will help ensure the DNS queries remain private for all your devices at home.

Updates:

  • 2020-05-05: added command to increase dnsmasq cache-size
  • 2020-04-30: added more configurations to section 5

This can be done within 5 minutes by running some commands on your OpenWRT-based router.

Steps 2 and onward are largely a copy/paste from https://github.com/openwrt/packages/tree/master/net/stubby/files, feel free to read for more context/information, especially if you prefer to configure your router via the web interface.

1) Connect To Your Router

SSH into your router. You can use PuTTY for Windows, or your favourite SSH client. SSH stands for Secure Shell which allows you to run commands on the device you connect to, in this case your OpenWRT router.

The below command assumes your router IP address is 192.168.1.1, change it accordingly if yours is different:

ssh [email protected]

2) Install Stubby

Run the following commands:

opkg update
opkg install stubby
/etc/init.d/stubby start
/etc/init.d/stubby enable

These commands will install the latest version of Stubby and start/enable the service so Stubby automatically starts when your router boots up.

3) Set dnsmasq to forward DNS requests to Stubby

By default, OpenWRT uses dnsmasq as its DNS server.

Run the following commands to have dnsmasq pass DNS requests to Stubby:

uci add_list dhcp.@dnsmasq[-1].server='127.0.0.1#5453'
uci set dhcp.@dnsmasq[-1].noresolv=1
uci commit && reload_config

Unbound is another popular server, here is an example configuration of how to set it up with Stubby.

4) Disable sending DNS requests to ISP provided DNS servers

There is a chance some DNS queries can be sent to your ISP (Internet Service Provider) when the OpenWRT router is booted up.

Running the following commands will help ensure all DNS requests sent out to your ISP are via Stubby (therefore encrypted):

uci set network.wan.peerdns='0'
uci set network.wan.dns='127.0.0.1'
uci set network.wan6.peerdns='0'
uci set network.wan6.dns='0::1'
uci commit && reload_config

5) (recommended) Increase dnsmasq Cache Size

By default the maximum dnsmasq DNS cache size is 150. If you run into an issue where suddenly no domains resolve and your system log is spammed with “Maximum number of concurrent DNS queries reached (max: 150)” error messages, running the below commands to increase this limit to 1,000 may help:

uci set dhcp.@dnsmasq[0].dnsforwardmax=1000
uci commit dhcp
/etc/init.d/dnsmasq restart

6) (optional) Add Different DNS Providers

I always like to mix and match different DNS providers as primary/secondary DNS servers. This is because in case one experiences a widespread outage you have the other as a fallback.

My two preferred providers are Cloudflare and Quad9 based on their privacy policies. Honourable mention to CIRA’s Canadian Shield for having Canada-only servers.

By default Stubby uses Cloudflare (1.1.1.1 as primary and 1.0.0.1 as secondary).

Below are various configurations that users can pick/choose from to best suit their needs. For example, if you’re not in Canada you can probably skip the configurations with Canadian Shield. These configurations use the malware/phishing blocking variant of each DNS provider.

You’ll notice some configurations refer to “ECS” which stands for “EDNS Client-Subnet”. ECS-enabled servers transmit data on your IP address subnet in order to optimize routing to you from servers close to you. This has real-world impacts, such as streaming video from YouTube.

“While [ECS] is typically used to improve the performance of Content Distribution Networks, we have determined that Client-Subnet data falls into a grey area of personally identifiable information […]. In some circumstances, [not transmitting that data] may result in suboptimal routing between CDN origins and end users.” (source).

tl;dr: ECS enabled = less privacy but optimal routing. ECS disabled = more privacy but risk of less optimal routing.

Pro-tip: you can copy/paste the entire code-block of the configuration you like below into the SSH command prompt and press Enter to ensure all commands are executed.

If all the configurations in this section do not meet your needs you can definitely customize your own:

6a) Cloudflare (no ECS) + Quad9 (no ECS)

Configuration Summary: maximum privacy.

The below commands (modified from this page) change the Cloudflare DNS server to its malware-blocking variant (1.1.1.2) and replaces 1.0.0.1 with Quad9 which has built-in malware blocking (9.9.9.9):

while uci -q delete stubby.@resolver[0]; do :; done
uci set stubby.dns6a="resolver"
uci set stubby.dns6a.address="2606:4700:4700::1112"
uci set stubby.dns6a.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6b="resolver"
uci set stubby.dns6b.address="2606:4700:4700::1002"
uci set stubby.dns6b.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6c="resolver"
uci set stubby.dns6c.address="2620:fe::fe"
uci set stubby.dns6c.tls_auth_name="dns.quad9.net"
uci set stubby.dns6d="resolver"
uci set stubby.dns6d.address="2620:fe::9"
uci set stubby.dns6d.tls_auth_name="dns.quad9.net"
uci set stubby.dnsa="resolver"
uci set stubby.dnsa.address="1.1.1.2"
uci set stubby.dnsa.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsb="resolver"
uci set stubby.dnsb.address="1.0.0.2"
uci set stubby.dnsb.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsc="resolver"
uci set stubby.dnsc.address="9.9.9.9"
uci set stubby.dnsc.tls_auth_name="dns.quad9.net"
uci set stubby.dnsd="resolver"
uci set stubby.dnsd.address="149.112.112.112"
uci set stubby.dnsd.tls_auth_name="dns.quad9.net"
uci commit stubby
/etc/init.d/stubby restart

6b) Cloudflare (no ECS) + Quad9 (no ECS) + Canadian Shield (ECS enabled)

Configuration Summary: as much privacy as possible, with less optimal routing, for Canadians.

NOTE: Canadian Shield has ECS enabled while Cloudflare does not and Quad9 offers a choice – this configuration uses the Quad9 server with ECS disabled. This configuration may lead to inconsistent routing.

The below commands change the Cloudflare DNS server to its malware-blocking variant (1.1.1.2), replaces 1.0.0.1 with Quad9 which has built-in malware blocking (9.9.9.9) and adds CIRA’s Canadian Shield malware-blocking variant (149.112.121.20):

while uci -q delete stubby.@resolver[0]; do :; done
uci set stubby.dns6a="resolver"
uci set stubby.dns6a.address="2606:4700:4700::1112"
uci set stubby.dns6a.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6b="resolver"
uci set stubby.dns6b.address="2606:4700:4700::1002"
uci set stubby.dns6b.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6c="resolver"
uci set stubby.dns6c.address="2620:fe::fe"
uci set stubby.dns6c.tls_auth_name="dns.quad9.net"
uci set stubby.dns6d="resolver"
uci set stubby.dns6d.address="2620:fe::9"
uci set stubby.dns6d.tls_auth_name="dns.quad9.net"
uci set stubby.dns6e="resolver"
uci set stubby.dns6e.address="2620:10A:80BB::20"
uci set stubby.dns6e.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dns6f="resolver"
uci set stubby.dns6f.address="2620:10A:80BC::20"
uci set stubby.dns6f.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsa="resolver"
uci set stubby.dnsa.address="1.1.1.2"
uci set stubby.dnsa.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsb="resolver"
uci set stubby.dnsb.address="1.0.0.2"
uci set stubby.dnsb.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsc="resolver"
uci set stubby.dnsc.address="9.9.9.9"
uci set stubby.dnsc.tls_auth_name="dns.quad9.net"
uci set stubby.dnsd="resolver"
uci set stubby.dnsd.address="149.112.112.112"
uci set stubby.dnsd.tls_auth_name="dns.quad9.net"
uci set stubby.dnse="resolver"
uci set stubby.dnse.address="149.112.121.20"
uci set stubby.dnse.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsf="resolver"
uci set stubby.dnsf.address="149.112.122.20"
uci set stubby.dnsf.tls_auth_name="protected.canadianshield.cira.ca"
uci commit stubby
/etc/init.d/stubby restart

6c) Cloudflare (no ECS) + Quad9 (ECS enabled) + Canadian Shield (ECS enabled)

Configuration Summary: less privacy with slightly more optimal routing, for Canadians.

NOTE: Canadian Shield has ECS enabled while Cloudflare does not and Quad9 offers a choice – this configuration uses the Quad9 server with ECS enabled. This configuration may lead to inconsistent routing.

The below commands change the Cloudflare DNS server to its malware-blocking variant (1.1.1.2), replaces 1.0.0.1 with Quad9 which has built-in malware blocking (9.9.9.11 – ECS enabled variant) and adds CIRA’s Canadian Shield malware-blocking variant (149.112.121.20):

while uci -q delete stubby.@resolver[0]; do :; done
uci set stubby.dns6a="resolver"
uci set stubby.dns6a.address="2606:4700:4700::1112"
uci set stubby.dns6a.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6b="resolver"
uci set stubby.dns6b.address="2606:4700:4700::1002"
uci set stubby.dns6b.tls_auth_name="cloudflare-dns.com"
uci set stubby.dns6c="resolver"
uci set stubby.dns6c.address="2620:fe::11"
uci set stubby.dns6c.tls_auth_name="dns.quad9.net"
uci set stubby.dns6d="resolver"
uci set stubby.dns6d.address="2620:fe::fe:11"
uci set stubby.dns6d.tls_auth_name="dns.quad9.net"
uci set stubby.dns6e="resolver"
uci set stubby.dns6e.address="2620:10A:80BB::20"
uci set stubby.dns6e.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dns6f="resolver"
uci set stubby.dns6f.address="2620:10A:80BC::20"
uci set stubby.dns6f.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsa="resolver"
uci set stubby.dnsa.address="1.1.1.2"
uci set stubby.dnsa.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsb="resolver"
uci set stubby.dnsb.address="1.0.0.2"
uci set stubby.dnsb.tls_auth_name="cloudflare-dns.com"
uci set stubby.dnsc="resolver"
uci set stubby.dnsc.address="9.9.9.11"
uci set stubby.dnsc.tls_auth_name="dns.quad9.net"
uci set stubby.dnsd="resolver"
uci set stubby.dnsd.address="149.112.112.11"
uci set stubby.dnsd.tls_auth_name="dns.quad9.net"
uci set stubby.dnse="resolver"
uci set stubby.dnse.address="149.112.121.20"
uci set stubby.dnse.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsf="resolver"
uci set stubby.dnsf.address="149.112.122.20"
uci set stubby.dnsf.tls_auth_name="protected.canadianshield.cira.ca"
uci commit stubby
/etc/init.d/stubby restart

6d) Quad9 (ECS enabled) + Canadian Shield (ECS enabled)

Configuration Summary: less privacy with optimal routing, for Canadians.

The below commands use ECS-enabled DNS servers for Quad9 and CIRA’s Canadian Shield:

while uci -q delete stubby.@resolver[0]; do :; done
uci set stubby.dns6a="resolver"
uci set stubby.dns6a.address="2620:fe::11"
uci set stubby.dns6a.tls_auth_name="dns.quad9.net"
uci set stubby.dns6b="resolver"
uci set stubby.dns6b.address="2620:fe::fe:11"
uci set stubby.dns6b.tls_auth_name="dns.quad9.net"
uci set stubby.dns6c="resolver"
uci set stubby.dns6c.address="2620:10A:80BB::20"
uci set stubby.dns6c.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dns6d="resolver"
uci set stubby.dns6d.address="2620:10A:80BC::20"
uci set stubby.dns6d.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsa="resolver"
uci set stubby.dnsa.address="9.9.9.11"
uci set stubby.dnsa.tls_auth_name="dns.quad9.net"
uci set stubby.dnsb="resolver"
uci set stubby.dnsb.address="149.112.112.11"
uci set stubby.dnsb.tls_auth_name="dns.quad9.net"
uci set stubby.dnsc="resolver"
uci set stubby.dnsc.address="149.112.121.20"
uci set stubby.dnsc.tls_auth_name="protected.canadianshield.cira.ca"
uci set stubby.dnsd="resolver"
uci set stubby.dnsd.address="149.112.122.20"
uci set stubby.dnsd.tls_auth_name="protected.canadianshield.cira.ca"
uci commit stubby
/etc/init.d/stubby restart

7) (optional) Enable DNSSEC

The above commands provide confidentiality to your DNS requests, but not integrity/authenticity. Enabling DNSSEC adds validation checks at the cost of some possible performance issues.

You can visit https://github.com/openwrt/packages/tree/master/net/stubby/files#enabling-dnssec for steps.

Personally I did not enable DNSSEC since Cloudflare, Quad9 and Canadian Shield provide this on their end.

8) Test

Some sites you can test with: