2026 is here, and it is time to begin technical writing on a regular basis; the complete opposite of the "LLM-ification" of the interweb.
Here is a simple one about DNS setup on Linux, primarily using systemd-resolved and NextDNS recursive resolvers.
NextDNS
Nowadays you have plenty of choices as recursive DNS. The goto, which I don't like, is usually 8.8.8.8 from Google or 1.1.1.1 from CloudFlare.
If you are concerned about sovereignty, you will see that these options are 100% US-based and do not allow you to control filtering, statistics, or security.
Alternatives exist and I have relied on NextDNS since 4y as a paid subscriber.
NetworkManager
NetworkManager is usually the default frontend for managing connections under Linux; as is the case for Raspberry Pi 4 running Debian Trixie (Raspbian).
I won't debate about it versus other configuration tools like networkd, netplan or bare interfaces files.
DNS backend
By default NetworkManager writes acquired DNS resolvers to /etc/resolv.conf and leaves it at that.
This approach lacks configurability and features such as DNSSEC or DoT/DoH. To do so you will need to use another DNS backend.
You can choose between dnsmasq and systemd-resolved.
systemd-resolved
$ # nm generated resolv.conf from dhcp acquired resolvers
$ cat /etc/resolv.conf
# Generated by resolvconf
domain lan
nameserver 45.90.28.0
...
nameserver 192.168.1.1
$ # switching to systemd-resolved backend
$ sudo apt install systemd-resolved
...
Converting /etc/resolv.conf to a symlink to /run/systemd/resolve/stub-resolv.conf...
$ tail -3 /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search lanBy linking systemd-resolved stub resolver to /etc/resolv.conf, NetworkManager enables it as the DNS backend, thus supporting DoT/DoH and caching.
You can now configure selected connections to use any resolver you prefer.
You have the option to configure all interfaces or only specific ones; I prefer the latter for flexibility.
NetworkManager
$ nmcli con
NAME UUID TYPE DEVICE
wired bd073894-9915-3f6d-8daf-3f3372783ae9 ethernet eth0
tailscale0 2b3c82c5-917b-4781-a148-c9f11dc7cf11 tun tailscale0
lo 28348d3c-2cdf-46a6-a879-0e6b904df6f7 loopback lo
$ sudo nmcli con mod wired ipv4.dns 45.90.28.0#raspberry-12345.dns.nextdns.io,45.90.30.0#raspberry-12345.dns.nextdns.io
$ sudo nmcli con mod wired ipv6.dns 2a07:a8c0::#raspberry-12345.dns.nextdns.io,2a07:a8c1::#raspberry-12345.dns.nextdns.io
$ # ignore DHCP DNS servers
$ sudo nmcli con mod wired ipv4.ignore-auto-dns yes
$ sudo nmcli con mod wired ipv6.ignore-auto-dns yesLet's verify that everything works as expected.
$ resolvectl status
Global
Protocols: +LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
resolv.conf mode: stub
Link 2 (eth0)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Protocols: +DefaultRoute +LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
Current DNS Server: 45.90.28.0#raspberry-12345.dns.nextdns.io
DNS Servers: 45.90.28.0#raspberry-12345.dns.nextdns.io 45.90.30.0#raspberry-12345.dns.nextdns.io 2a07:a8c0::#raspberry-12345.dns.nextdns.io
2a07:a8c1::#raspberry-12345.dns.nextdns.io
DNS Domain: lan
Default Route: yes$ resolvectl query google.com
google.com: 142.250.201.14 -- link: eth0
2a00:1450:4006:80e::200e -- link: eth0
-- Information acquired via protocol DNS in 56.9ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: yes
-- Data from: network$ sudo resolvectl statistics
Transactions
Current Transactions: 0
Total Transactions: 21
Cache
Current Cache Size: 4
Cache Hits: 6
Cache Misses: 11
Failure Transactions
Total Timeouts: 4
Total Timeouts (Stale Data Served): 0
Total Failure Responses: 0
Total Failure Responses (Stale Data Served): 0
DNSSEC Verdicts
Secure: 0
Insecure: 0
Bogus: 0
Indeterminate: 0To make the setup even more explicit, you can configure NetworkManager to always use systemd-resolved
$ head -4 /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile
dns=systemd-resolved
dns-over-tls=yesDoT with DNSSEC
DNS-over-TLS is a transport security that protects your DNS traffic from tampering. It is basically encryption of the UDP/TCP requests and responses between you and the server. The standard is defined by the RFC 7858.
DNSSEC is a signature mechanism for response integrity, confirming that you get an unaltered response from the domain owner. The standard is defined by the RFC 9364.
systemd-resolved supports both.
systemd-resolved
$ cat /etc/systemd/resolved.conf.d/01-nextdns.conf
[Resolve]
DNS=2a07:a8c0::#pooptop-12345.dns.nextdns.io
DNS=2a07:a8c1::#pooptop-12345.dns.nextdns.io
DNS=45.90.28.0#pooptop-12345.dns.nextdns.io
DNS=45.90.30.0#pooptop-12345.dns.nextdns.io
DNSOverTLS=yes
DNSSEC=true
Cache=no-negative
StaleRetentionSec=60
Domains=~.There is a catch about Domains. ~. means to route all queries to these DNS servers, giving them top priority over DNS servers acquired via DHCP.
You should now see the secure count increasing. Currently, not all domains support DNSSEC, which explains the insecure count.
❯ sudo resolvectl statistics
Transactions
Current Transactions: 0
Total Transactions: 8091
Cache
Current Cache Size: 78
Cache Hits: 3905
Cache Misses: 7277
Failure Transactions
Total Timeouts: 12
Total Timeouts (Stale Data Served): 0
Total Failure Responses: 0
Total Failure Responses (Stale Data Served): 0
DNSSEC Verdicts
Secure: 3530
Insecure: 3675
Bogus: 33
Indeterminate: 0EDNS Client Subnet
ECS is a EDNS0 extension designed to improve performance in a world of anycast IP.
Bear with me, it is implemented by recursive resolver to forward the client's CIDR to the authoritative resolver, providing a hint about the optimal origin.
Without ECS, the authoritative resolver bases its decision on the location of the intermediate recursive resolver, which may be geographically distant from the client.
NextDNS support ECS and I use it despite some privacy concern (on that matter we will see how to use Tailscale exit node as an affordable and permanent VPN)
The standard is defined by the RFC 7871.
Resources
See you in a bit ✌︎㋡