Introduction
Previously, I had been using my ISP’s default DNS server. After encountering a page blocked by CUII, I decided to move to an alternative DNS server without censoring. This made it necessary to setup DNS over TLS (DoT, RFC7858).
As it was not easily done using the traditional
/etc/resolv.conf and /etc/network/interfaces
style configuration I decided to take this as an opportunity to move to
systemd-networkd and systemd-resolved. Initially, this broke my AES 67
audio setup such that I subsequently needed to re-enable Avahi Daemon
instead of the mDNS solution integrated into systemd-networkd.
This post summarizes the individual steps for my own reference and for everyone who may be interested in it.
Alternative DNS Server Providers
The first and most difficult step is to select a suitable replacement DNS provider. I went with the DNS by Digitalcourage e.V., but there are also other privacy-respecting and uncensored DNS providers:
| Provider | IPv4 | IPv6 | Link |
|---|---|---|---|
| AdGuard | 94.140.14.140 | 2a10:50c0::1:ff | https://adguard-dns.io/de/public-dns.html |
| 94.140.14.141 | 2a10:50c0::2:ff | ||
| Artikel 10 e.V. | 217.197.91.153 | 2001:67c:1401:2120::1 | https://dns.artikel10.org/ |
| Digitalcourage e.V. | 5.9.164.112 | 2a01:4f8:251:554::2 | https://digitalcourage.de/support/zensurfreier-dns-server |
| Digitale Gesellschaft | 185.95.218.42 | 2a05:fc84::42 | https://www.digitale-gesellschaft.ch/dns/ |
| 185.95.218.43 | 2a05:fc84::43 | ||
| dns.watch | 84.200.69.80 | 2001:1608:10:25::1c04:b12f | https://dns.watch/ |
| 84.200.70.40 | 2001:1608:10:25::9249:d69b | ||
| Foundation for Applied Privacy | 146.255.56.98 | 2a02:1b8:10:234::2 | https://applied-privacy.net/services/dns/ |
| Freie Netze München e.V. | 5.1.66.255 | 2001:678:e68:f000:: | https://ffmuc.net/wiki/doku.php?id=knb:dohdot |
| 185.150.99.255 | 2001:678:ed0:f000:: | ||
| Mullvad | 194.242.2.2 | 2a07:e340::2 | https://mullvad.net/en/help/dns-over-https-and-dns-over-tls |
| Njalla | 95.215.19.53 | 2001:67c:2354:2::53 | https://dns.njal.la/ |
| Restena Foundation | 158.64.1.29 | 2001:a18:1::29 | https://www.restena.lu/en/document/190-configuring-your-server-public-dns-resolver |
| Quad9 | 9.9.9.9 | 2620:fe::fe | https://quad9.net/service/service-addresses-and-features/ |
| 149.112.112.112 | 2620:fe::9 | ||
| UncensoredDNS | 91.239.100.100 | 2001:67c:28a4:: | https://blog.uncensoreddns.org/dns-servers/ |
I mostly created above table from the sources linked from section See Also/Free Uncensored DNS Servers. This is obviously Europe-centric. If you are in a different part of the world, consider checking for regional alternatives if you trust them more.
DNS over TLS
Standard DNS runs over UDP and DNS requests are issued by the
libraries used by the applications i. e. there is not necessarily a
central daemon that emits them. The information about which DNS server
to consult is typically retrieved from
/etc/resolv.conf.
In a standard configuration, the values to put there are obtained from a DHCP server and typically point to the router on the network which in turn forwards the DNS requests to the DNS server provided by the ISP.
When using a DNS server which accepts requests via UDP, changing the
DNS server of the system is as simple as replacing the entry in
resolv.conf, e. g. by Google’s famous DNS 8.8.8.8 or
Cloudflare’s just as easy to remember 1.1.1.1.
However, this time I wanted to setup a future-proof privacy-respecting choice of DNS server and many of them newly require DNS over TLS (DoT, or alternatively DNS over HTTPS, aka. DoT) and do not allow the unencrypted access via UDP anymore.
This is of course, good for security, but not all applications are individually capable of contacting a DoT or DoH-based DNS server directly. Hence for this use case, it is helpful to run a local unencrypted DNS server that translates the locally incoming UDP-based cleartext requests to TCP-based and encrypted DoT.
Such a local DNS server can be provided by systemd-resolved.
systemd-resolved
There are certainly other alternatives, but in recent times I tend to prefer the solutions offered by the systemd-related tools as sensible default choices.
Often, they implement only a subset of what is technically possible
but this is often sufficient to solve my kind of use cases.
Also, I like that the INI config file format and introspection features
(*ctl-series of commands) are somewhat similar across the
systemd tools, making them easy to get started with once one knows how
any of the other tools work.
This case here is only the second time that the out-of-the-box feature set of the systemd tool was not coverying my use case 100% hence I had to substitute the integrated systemd-resolved feature for mDNS with the proper avahi-daemon (cf. Section Recovering avahi-daemon further down).
The configuration for systemd-resolved is a straight-forward INI file:
# /etc/systemd/resolved.conf.d/20-digitalcourage-dot.conf
[Resolve]
DNS=5.9.164.112#dns3.digitalcourage.de 2a01:4f8:251:554::2#dns3.digitalcourage.de
DNSOverTLS=yes
Domains=~.
# disable multicast DNS because we _must_ use avahi-daemon for AES67!
MulticastDNS=no
The DNS servers to use are configured in line DNS and
DoT is enabled by setting DNSOverTLS=yes.
If I understood it correctly, for systemd-resolved to run correctly,
the network interface must be known by systemd-networkd. I used the
opportunity to configure systemd-networkd for my primary network
interface eno1 but it would possibly be enough to only have
the [Match] and Name=eno1 lines if the
interface was managed by /etc/network/interfaces.
# /etc/systemd/network/20-masysma-main.network
[Match]
Name=eno1
[Link]
RequiredForOnline=routable
[Network]
DHCP=ipv6
Address=192.168.1.16/24
Gateway=192.168.1.1
For my use of systemd-networkd, I removed the interface from
/etc/network/interfaces, keeping only the loopback
interface there:
# /etc/network/interfaces
auto lo
iface lo inet loopback
Ensure both of the required systemd services are running:
# systemctl enable --now systemd-networkd.service
# systemctl enable --now systemd-resolved.service
Then inspect the status of systemd-resolved with the
resolvectl command:
# resolvectl
Global
Protocols: +LLMNR +mDNS +DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 5.9.164.112#dns3.digitalcourage.de
DNS Servers: 5.9.164.112#dns3.digitalcourage.de
2a01:4f8:251:554::2#dns3.digitalcourage.de
DNS Domain: ~.
Link 2 [...]
Link 5 (eno1)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Protocols: +DefaultRoute +LLMNR -mDNS +DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: fe80::1
DNS Servers: fe80::1
Default Route: yes
Link 6 [...]
Note the -mDNS and +mDNS in the output: If
you wanted to setup systemd-resolved with mDNS support but without
avahi-daemon, you could set the variable MulticastDNS=yes
in the network interface configuration and the systemd-resolved
configuration to enable its integrated mDNS support.
Check that systemd-resolved works by itself:
# resolvectl query masysma.net
masysma.net: 2a01:239:241:bf00::1 -- link: eno1
87.106.179.152 -- link: eno1
-- Information acquired via protocol DNS in 936us.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: yes
-- Data from: cache
Once it works OK there, replace /etc/resolv.conf by a
configuration that points to the locally running server provided by
systemd-resolved:
# mv /etc/resolv.conf /etc/resolv.conf.bak
# ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Check the content of the effective resolv.conf:
$ grep -vE '^#' /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search .
Confirm that DNS works by running host:
$ host masysma.net
masysma.net has address 87.106.179.152
masysma.net has IPv6 address 2a01:239:241:bf00::1
masysma.net mail is handled by 5 smtpin.rzone.de.
Recovering avahi-daemon
After initially setting up systemd-resolved as a replacement also for
avahi-daemon, I noticed that the audio streams configured in
aes67-linux-daemon cf. aes67_audio_notes(37) would no
longer be received on the Audio Interface. This was due to the streams
not being announced with mDNS anymore.
In general, it seems the aes67-linux-daemon requires
avahi-daemon for this task. Hence I disabled the mDNS support in
systemd-resolved and instead re-enabled the
avahi-daemon.service.
After restarting aes67-linux-daemon the audio streams
were again discovered by the interface.
The configuration in the previous section already accounts for this
change. If you don’t run AES67 you might get away successfully with
setting MulticastDNS=yes in
/etc/systemd/resolved.conf.d and
/etc/systemd/network and could then probably do without the
separately running avahi-daemon.service…
See Also
- RFC7858 - DNS over TLS
About CUII
Free Uncensored DNS Servers
- https://european-alternatives.eu/category/public-dns
- https://www.privacy-handbuch.de/handbuch_93d.htm
- https://github.com/dns-sb/dns.sb/issues/36