Configuring DNS over TLS and .internal domains
For many years I’ve been using the DNS over TLS (DoT) using quad9 DNS service, preventing anybody from wiretapping and/or hijacking what website I’m visiting on my browser. Since I moved my local services to .internal I was not able to resolve their DNS entries. This is how I configured my laptop to enjoy DNS over TLS and allow .internal services to be resolved too.
What is DNS over TLS?
DNS over TLS (DoT) is a security protocol that encrypts communication between your device and a DNS server over port 853. It protects your privacy and ensures the integrity of the data. Imagine it like sending your DNS requests and responses in a sealed envelope instead of a postcard, making it much harder for anyone to intercept or tamper with them. DoT is especially important in situations where you’re using public Wi-Fi.
Overview
We will enable ability to encrypt DNS queries system-wide and send them to quad9 servers. This means that we will not use the DNS servers given to us by DHCP connections, I always use the quad9 ones. This is true except for the resolution of .internal domain names in my home network.
Configure DoT
Step 1. Edit your /etc/systemd/resolved.conf.d/50-DNSOverTLS.conf by adding the following:
[Resolve]
# AdGuard
# DNS=94.140.14.14#dns.adguard-dns.com 94.140.15.15#dns.adguard-dns.com 2a10:50c0::ad1:ff#dns.adguard-dns.com 2a10:50c0::ad2:ff#dns.adguard-dns.com
# quad9
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
# Always use DNS over TLS
DNSOverTLS=yes
Domains=~.
Adding Domains: ~., I force that all DNS queries are routed to quad9 resolvers over DoT. It means that the per link DNS resolvers will not be taken into consideration.
Step 2. Save the configuration and restart the systemd-resolved
sudo systemctl restart systemd-resolved
Step 3. Check the results
$ resolvectl status
Global
Protocols: -LLMNR -mDNS +DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: foreign
Current DNS Server: 9.9.9.9#dns.quad9.net
DNS Servers: 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
DNS Domain: ~.
Link 2 (enxd0c0bf2e92c0)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.1.3
DNS Servers: 192.168.1.3 192.168.1.10
Link 3 (wlp0s20f3)
Current Scopes: none
Protocols: -DefaultRoute -LLMNR -mDNS +DNSOverTLS DNSSEC=no/unsupported
The quad9 servers are set at Global level which route all the domains ~. and DNSOverTLS is enabled.
Check one domain:
$ resolvectl query example.com
example.com: 104.20.23.154 -- link: enxd0c0bf2e92c0
172.66.147.243 -- link: enxd0c0bf2e92c0
2606:4700:10::ac42:93f3 -- link: enxd0c0bf2e92c0
2606:4700:10::6814:179a -- link: enxd0c0bf2e92c0
-- Information acquired via protocol DNS in 31.8ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: yes
-- Data from: network
As you can see Data was acquired via local or encrypted transport: yes means that this DNS query was encrypted.
Another way to see which protocol you’re using is going to on.quad9.net or by CLI:
$ dig +short txt proto.on.quad9.net.
"dot"
What about .internal domains
After moving all my homelab to the .internal domain, as I explained in a previous post, the DNS queries for this domain were not working.
$ nslookup printer.internal
Server: 127.0.0.53
Address: 127.0.0.53#53
** server can't find printer.internal: NXDOMAIN
These DNS entries are defined in my local DNS, two Adguard Home services running on my network. I needed to redirect these kinds of queries to the local DNS servers instead of using the quad9 one.
This configuration needs to be implemented for each trusted home network connection, given that the .internal services are only accessible from my home network.
Security Note: Queries for
.internaldomains will not be encrypted since we disable DoT for this connection. This is acceptable for home networks but ensure you only configure this for trusted networks.
Step 1: Connect to your home network
Step 2: Get the name of the active connection.
$ nmcli con show --active
NAME UUID TYPE DEVICE
aetas 95783eb7-4513-4b80-a6b4-ada6541034b2 wifi wlp0s20f3
lo 770e3286-58c8-4e7e-88f6-22cf2c77c0c8 loopback lo
Step 3: Configure the connection
$ nmcli con mod "aetas" ipv4.dns-search "~internal"
$ nmcli con mod "aetas" connection.dns-over-tls no
I have added ~internal domain as DNS domain, it will redirect .internal DNS queries to this connection. It disables DoT for this connection, given that my local DNS are using just plain DNS (over port 53).
Step 4: Re-connect to apply the changes
$ nmcli con up "aetas"
Note: If you have multiple home network connections (different WiFi SSIDs or Ethernet connections), repeat Steps 2-4 for each one.
Step 5: Check if .internal works
nslookup printer.internal
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: printer.internal
Address: 192.168.1.23
Now all the .internal DNS queries are resolved by my local DNS while the rest are using quad9 DNS over DoT.
Step 6: Verify DoT is still working for other domains
To ensure that non-.internal domains are still using encrypted DNS, verify the DoT status:
$ dig +short txt proto.on.quad9.net.
"dot"
If you see "dot", it confirms that your regular DNS queries are still encrypted via DNS over TLS.
Wrapping up
I’ve included this configuration in my dotfiles repository
DNS_Over_TLS.shis the utility to enable/disable the DoTDNS_internal_domains.shis the utility to configure the active network to enable.internalresolution.
Enjoy!