Encrypted DNS and how to use it in Linux

Advise: In Fedora 30, stubby is no longer part of the getdns default package. After updating from F29 to F30 your DNS resolution will no longer work.

To fix this issue, first temporarily add another DNS server to your /etc/resolv.conf, for example “nameserver <yourrouteraddress>”, then install the package getdns-stubby and reactivate the service.

It is the news of the day: “Google Public DNS gets DNS-over-TLS treatment” (ZDNet). For the consumer this means that secure DNS is being pushed forward by a tech giant and this technology should soon be a standard. With DNS-over-TLS your Domain Name requests will no longer be transmitted over the internet unencrypted. Instead they are sent to the DNS provider encrypted. In this article I will show how to set up Google’s DNS-over-TLS on Fedora Linux (29) using the Stubby DNS resolver.

Google is very often criticized for collecting too much of our data and I do not dare to advise my readers to trust them blindly. What they promise concerning the privacy of their public DNS, you can read on their Website: https://developers.google.com/speed/public-dns/privacy

DNS-over-TLS in Linux is relatively easy to set up using Stubby, a tiny DNS resolver that is running locally in the background. The network configuration has to be altered in a way that DNS requests are being sent to the local resolver and stubby itself has to be configured to use Google’s Servers.

Download stubby:

On Fedora 30

sudo dnf install getdns-stubby

On Fedora 29 and earlier:

sudo dnf install getdns


Modify stubby’s configuration:

sudo cp /etc/stubby/stubby.yml /etc/stubby/stubby.old
sudo vim /etc/stubby/stubby.yml

The example configuration file can be shortened like this:

resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private : 1
round_robin_upstreams: 1
idle_timeout: 10000
listen_addresses:
  - 127.0.0.1
  - 0::1
dnssec_trust_anchors: "/var/lib/unbound/root.key"
upstream_recursive_servers:
# Google Public DNS
  - address_data: 8.8.8.8
    tls_auth_name: "dns.google"
  - address_data: 2001:4860:4860::8888
    tls_auth_name: "dns.google"
  - address_data: 8.8.4.4
    tls_auth_name: "dns.google"
  - address_data: 2001:4860:4860::8844
    tls_auth_name: "dns.google"  

Start stubby and check it’s status:

sudo systemctl start stubby
sudo systemctl status stubby

● stubby.service - stubby DNS resolver
   Loaded: loaded (/usr/lib/systemd/system/stubby.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2019-01-11 18:52:25 CET; 2s ago
 Main PID: 15190 (stubby)
    Tasks: 1 (limit: 4915)
   Memory: 1.4M
   CGroup: /system.slice/stubby.service
           └─15190 /usr/bin/stubby

Jan 11 18:52:25 hostname systemd[1]: Started stubby DNS resolver.
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.190801] STUBBY: Read config from file /etc/stubby/stubby.yml
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191385] STUBBY: DNSSEC Validation is OFF
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191397] STUBBY: Transport list is:
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191400] STUBBY:   - TLS
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191403] STUBBY: Privacy Usage Profile is Strict (Authentication required)
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191406] STUBBY: (NOTE a Strict Profile only applies when TLS is the ONLY transport!!)
Jan 11 18:52:25 hostname stubby[15190]: [17:52:25.191409] STUBBY: Starting DAEMON....

To start stubby on boot:

sudo systemctl enable stubby

Change your network settings:

Set the DNS Server manually to 127.0.0.1 in your IPv4 settings and to ::1 in your IPv6 settings. Remember to restart your network and check your resolve.conf. It should look like this:

cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 127.0.0.1
nameserver ::1

Note: With every Wi-Fi you connect to, the DNS Settings are overwritten by NetworkManager. This often makes sense when using the “classic” DNS Servers, because often home routers and company networks offer additional internal or local host addresses. But if you always want to use DNS-over-TLS in any Wi-FI you are, you might want to turn off this feature. Add this to /etc/NetworkManager/NetworkManager.conf:

[main]
dns=none

Reboot and make sure your /etc/resolv.conf looks like this:

nameserver 127.0.0.1
nameserver ::1

Test your new setup:

You can use nslookup to test your DNS-settings.

nslookup google.com

Server:		127.0.0.1
Address:	127.0.0.1#53

Non-authoritative answer:
Name:	google.com
Address: 173.194.76.100
Name:	google.com
Address: 173.194.76.139
Name:	google.com
Address: 173.194.76.138
Name:	google.com
Address: 173.194.76.101
Name:	google.com
Address: 173.194.76.102
Name:	google.com
Address: 173.194.76.113
Name:	google.com
Address: 2a00:1450:400c:c02::64

If you want to be sure to use DNS-over-TLS, run Wireshark and observe the communication:

DNS-over-TLS example. Nothing to see here 🙂

Further reading:

Supplement

Configuration in systemd instead of stubby

In modern distributions the DNS-over-TLS functionality is already implemented in systemd. In the next days I will look into this and maybe publish a tutorial on this alternative solution.

Alternative: SecureDNS

There are other DNS-over-TLS providers out there. Here is the stubby.yml configuration if you want to use SecureDNS instead of Google DNS:

resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private : 1
round_robin_upstreams: 1
idle_timeout: 10000
listen_addresses:
  - 127.0.0.1
  - 0::1
dnssec_trust_anchors: "/var/lib/unbound/root.key"
upstream_recursive_servers:
# SecureDNS
   - address_data: 146.185.167.43
     tls_pubkey_pinset:
      - digest: "sha256"
        value: h3mufC43MEqRD6uE4lz6gAgULZ5/riqH/E+U+jE3H8g=

   - address_data: 2a03:b0c0:0:1010::e9a:3001
     tls_pubkey_pinset:
      - digest: "sha256"
        value: h3mufC43MEqRD6uE4lz6gAgULZ5/riqH/E+U+jE3H8g=
3 replies on “ Encrypted DNS and how to use it in Linux ”
  1. Thanks for this. I just modified the original stubby.yml file, commented out the default servers and added the Google ones. It didn’t work for me until I commented out:

    dnssec_trust_anchors: “/var/lib/unbound/root.key”

    …which is commented out by default, but I un-commented it as per your instructions. Once I made that a comment again though, everything is working perfectly.

    Thanks again,

    D

Comments are closed.