02-07-2020, 11:52 AM
When I was trying to deploy my own DoH (DNS-over-HTTPS) server, I did have to rethink my DNS caching solution and finally settle for systemd-resolved as my VPS's default resolver.
A Little Background
systemd-resolved is a stub resolver that is part of systemd; that's to say that it's already installed -by default- on your system if it's systemd-based. However, I can only attest that it's the case for RedHat-based systems (RHEL, CentOS and Fedora.)
This little jewel of software implements a caching and validating DNS/DNSSEC stub resolver, as well as an LLMNR (Link-Local Multicast Name Resolution) and MulticastDNS resolver and responder. Referring to it as a stub resolver means that it does not support recursive mode.
As part of systemd, it integrates with the system's NetworkManager, so that it will automatically use the network-assigned DNS servers, unless overridden in its configuration file. This said, what has most tilted the balance in its favour for my use case, was its supports for DNS-over-TLS (DoT) out-of-the-box.
Unfortunately, although my VPS is using the latest release and packages from CentOS repos (ie, CentOS Linux release 8.1.1911), the systemd version is still 239:
.. which makes it only able to run DoT in an opportunistic mode.
Compare this to Fedora 31:
.. which makes possible running DoT in the strict mode.
A mini-timeline of systemd's supports for DNS over TLS:
Configuration Tips
systemd-resolved configuration file is located in /etc/systemd/resolved.conf and, for my use case, looks like this:
By setting the DNS directive, I'm overriding the DHCP's assigned DNS server, and I've disabled LLMNR for its uselessness and potential vulnerabilities in my case. The next big thing to note is that the Cache directive is activated (not set by default) and the DNSStubListener must be set to udp to activate the local DNS stub listener on the local loopback interface's IP address 127.0.0.53.
To be clear, systemd-resolved's DoT in the opportunistic mode is unreliable, as both 53 and 853 traffics are used; so NO confidentiality assurance here!
Now is the time to activate our DNS resolver:
Testing using the deprecated netstat:
testing using the new ss command:
Now, to let our local programs issuing DNS requests to this local DNS stub listener, we have to override the default /etc/resolv.conf
The content of this static resolv.conf is:
That should be it; all local clients that bypass local DNS APIs are connected to systemd-resolved.
Next post will expand on the monitoring, operations and troubleshooting issues of systemd-resolved.
last Edited on 8/02/2020
Fixed few typos, rephrased few sentences and added new content as code snippets.
A Little Background
systemd-resolved is a stub resolver that is part of systemd; that's to say that it's already installed -by default- on your system if it's systemd-based. However, I can only attest that it's the case for RedHat-based systems (RHEL, CentOS and Fedora.)
This little jewel of software implements a caching and validating DNS/DNSSEC stub resolver, as well as an LLMNR (Link-Local Multicast Name Resolution) and MulticastDNS resolver and responder. Referring to it as a stub resolver means that it does not support recursive mode.
As part of systemd, it integrates with the system's NetworkManager, so that it will automatically use the network-assigned DNS servers, unless overridden in its configuration file. This said, what has most tilted the balance in its favour for my use case, was its supports for DNS-over-TLS (DoT) out-of-the-box.
Unfortunately, although my VPS is using the latest release and packages from CentOS repos (ie, CentOS Linux release 8.1.1911), the systemd version is still 239:
Code: (Select All)
[root@vps ~]# systemctl --version
systemd 239
(....)
Compare this to Fedora 31:
Code: (Select All)
[root@vps ~]# systemctl --version
systemd 243 (v243.5-1.fc31)
(....)
A mini-timeline of systemd's supports for DNS over TLS:
- version 236 DNSSEC support for RFC 8080 (ed25519 keys and signatures)
- version 239 systemd-resolved now supports opportunistic DNS-over-TLS, Off by default
- version 243 systemd-resolved gained support for a new strict DNS-over-TLS mode
Configuration Tips
systemd-resolved configuration file is located in /etc/systemd/resolved.conf and, for my use case, looks like this:
Code: (Select All)
# This file is part of systemd.
# (..........)
[Resolve]
DNS=9.9.9.9
FallbackDNS=1.1.1.1 8.8.8.8
#Domains=
LLMNR=no
#MulticastDNS=yes
DNSSEC=allow-downgrade
DNSOverTLS=opportunistic
#DNSOverTLS=yes
Cache=yes
#DNSStubListener=udp
By setting the DNS directive, I'm overriding the DHCP's assigned DNS server, and I've disabled LLMNR for its uselessness and potential vulnerabilities in my case. The next big thing to note is that the Cache directive is activated (not set by default) and the DNSStubListener must be set to udp to activate the local DNS stub listener on the local loopback interface's IP address 127.0.0.53.
To be clear, systemd-resolved's DoT in the opportunistic mode is unreliable, as both 53 and 853 traffics are used; so NO confidentiality assurance here!
Now is the time to activate our DNS resolver:
Code: (Select All)
# starting the service
systemctl start systemd-resolved
#Permanently enabling the service
systemctl enable systemd-resolved
Testing using the deprecated netstat:
Code: (Select All)
netstat -tulpn|grep 53
udp 0 0 127.0.0.53:53 0.0.0.0:* 18478/systemd-resol
Code: (Select All)
ss -tuna | grep :53
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
Now, to let our local programs issuing DNS requests to this local DNS stub listener, we have to override the default /etc/resolv.conf
Code: (Select All)
ln -fsv /usr/lib/systemd/resolv.conf /etc
The content of this static resolv.conf is:
Code: (Select All)
# This file belongs to man:systemd-resolved(8). Do not edit.
#
# This is a static resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists no search
# domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 127.0.0.53
~
That should be it; all local clients that bypass local DNS APIs are connected to systemd-resolved.
Next post will expand on the monitoring, operations and troubleshooting issues of systemd-resolved.
last Edited on 8/02/2020
Fixed few typos, rephrased few sentences and added new content as code snippets.