Recently I've implemented DNS over TLS for home network (using AsusWRT-Merlin
powered router). While exploring approaches to implement DoT for Linux workstations and servers (in the cloud - I mean someone else' computers lol) outside of home network, I found systemd-resolved
as recommended by the DNS Privacy Project.
While @opinion-no9 provided a Ubuntu 18.04 specific solution (limited by the systemd version shipped with the LTS), I'd like to share a more generic and close-to-upstream one:
A bit of background - timeline for DNS over TLS support in systemd
- 236 DNSSEC support for RFC 8080 (
ed25519
keys and signatures)
- 239
systemd-resolved
now supports opportunistic
DNS-over-TLS, Off
by default
- 243
systemd-resolved
gained support for a new strict
DNS-over-TLS mode
Oh NO! Ubuntu 18.04 LTS ships systemd 237...
UPDATE - 23 April 2020 Ubuntu 20.04 LTS which ships systemd 245 (without systemd-homed
;-).
Use DNS Over TLS (DoT) on generic Linux systems
So for generic Linux distro with relative close-to-upstream kernel, systemd, glibc, toolchain, GNU utils, etc
- edit
/etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1 1.0.0.1 8.8.8.8
#FallbackDNS=1.1.1.1 9.9.9.10 8.8.8.8 2606:4700:4700::1111 2620:fe::10 2001:4860:4860::8888
#Domains=
#LLMNR=yes
#MulticastDNS=yes
#DNSSEC=allow-downgrade
#DNSOverTLS=opportunistic
DNSSEC=yes
DNSOverTLS=yes
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
Ubuntu 20.04 specific resolved.conf
[Resolve]
DNS=1.1.1.1 1.0.0.1 8.8.8.8
FallbackDNS=1.1.1.1 8.8.8.10 8.8.8.8
#Domains=
#LLMNR=no
#MulticastDNS=no
DNSSEC=yes
DNSOverTLS=yes
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
- Assume
systemd-resolved
is enabled, restart the service
systemctl restart systemd-resolved.service
- Use local stub resolver
systemd-resolved
provides a local DNS stub listener on IP address 127.0.0.53 on the local loopback interface, so to use the DNS over TLS capable stub resolver, we'll need to somehow manage /etc/resolv.conf
and make sure 127.0.0.53
is used as nameserver.
NOTE: systemd maintains /run/systemd/resolve/stub-resolv.conf
for compatibility with traditional Linux programs. We can simply symlink to this file ;-)
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
NOTE: For Arch Linux, I have to replace openresolvconf
with systemd-resolvconf
.
Done.
Validation
Generate DNS query, then check TCP connection to specified upstream DNS server via port 853, in the following example we explicitly used Cloudflare's 1.1.1.1
.
root@netbook:/etc# uname -a
Linux netbook 5.4.5-arch1-1 #1 SMP PREEMPT Wed, 18 Dec 2019 19:48:51 +0000 x86_64 GNU/Linux
root@netbook:~# kdig -d github.com
;; DEBUG: Querying for owner(github.com.), class(1), type(1), server(127.0.0.53), port(53), protocol(UDP)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 55366
;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 0
;; QUESTION SECTION:
;; github.com. IN A
;; ANSWER SECTION:
github.com. 58 IN A 13.236.229.21
;; Received 44 B
;; Time 2019-12-21 22:55:13 AEDT
;; From 127.0.0.53@53(UDP) in 58.0 ms
root@netbook:~# ss -tuna | grep :853
tcp ESTAB 0 0 192.168.1.150:50504 1.1.1.1:853
tcp ESTAB 0 0 192.168.1.150:50506 1.1.1.1:853
Or, if you want to be simple and rough, use tcpdump
;-)
tcpdump -tttt -nn -XX -vv -i <interface> dst 1.1.1.1 and port 853
Conclusion
Last but not least: This is a generic guide to enable DNS over TLS on a Linux host, it is not specific to distro or Desktop Environment (as we haven't even touched NetworkManager or alternatives ;-). Adjustments may be needed for different distros and different DEs/WMs.
Reference
resolvectl
say? Are you actually using systemd-resolved? Flip yourDNSOverTLS
setting toyes
. You should also flipDNSSEC
validation toyes
. Few DNS over TLS implementation support reusing connections and will open one connection per request.