Secure DNS

TL;DR: Use a VPN if you really care.

Hey, you over there! Want to take something that works perfectly well and make it more complicated? Sure ya do! Oh, need a little more convincing?

Okay – here’s the rundown. We use https to keep the baddies from seeing what we browse on the internet. So far, so good. However, there’s a problem – DNS. DNS isn’t encrypted for …. reasons (see the above webcomic). And if you don’t change any of your settings, then you’re probably getting your DNS records from your ISP. Which means your ISP knows everything about what you try to visit.

Okay, it’s not _everything_. For example, with DNS, your ISP (or anyone else who is sniffing traffic), can see that you went to, but it can’t see the query string of what you’re searching for.

Using wireshark, it’s easy to take a look at this in action:

Wireshark showing encrypted DNS lookup

The thing is, it’s not as bad as it seems (or rather the alternative isn’t much better). Here’s the main thing. Even if you encrypt your DNS record, then when you start to actually talk to the server… well then everyone sniffing the traffic will know which IP address you’re visiting. It’s definitely better than plaintext because it makes passive snooping a lot harder. Instead of just logging every DNS record that you see – you instead have to log IP addresses, and then do more work to figure out which websites are being hotsed by an IP address. If the website is hosted by a cloud service (who isn’t these days), then it might even be impossible to tell which website the IP address is hosting.

The other reason that the alternative isn’t as great is that even if your DNS records are encrypted, then when you make an HTTPS request to a website, it …. has the domain name in the unencrypted part of the handshake. Or at least it used to. ESNI is working on this part, and hopefully in a few years or so everyone will be using it.

Enough jibber jabber show me the codes

My approach largely follows the steps outlined here:

Since I’m on Manjaro, It’s easy to use override files (yay) and leave the base files untouched. You just need these files:




# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 2606:4700:4700::1111 2606:4700:4700::1001
# Google: 2001:4860:4860::8888 2001:4860:4860::8844
# Quad9: 2620:fe::fe 2620:fe::9
DNS= 2606:4700:4700::1111 2606:4700:4700::1001 2620:fe::fe
FallbackDNS= ::1


#! /usr/bin/bash
set -e


backup () {
  if [ -f "$1" ]; then
    mv "$1" "$1.bak" 
    echo "Moved $1 to $1.bak"

restore () {
  if [ -f "$1.bak" ]; then
    mv "$1.bak" "$1" 
    echo "Moved $1.bak to $1"

restart_services( ) {
  echo "Restarting systemd-resolved"
  systemctl restart systemd-resolved
  echo "Restarting NetworkManager"
  systemctl restart NetworkManager

enable () {
  restore "$network_manager_conf"
  restore "$resolved_conf"

if [ "$1" = "enable" ]; then
  restore "$network_manager_conf"
  restore "$resolved_conf"
  echo "Secure DNS enabled"
elif [ "$1" = "disable" ]; then
  backup "$network_manager_conf"
  backup "$resolved_conf"
  echo "Secure DNS disabled"
  echo "Usage secure_dns [enable|disable]"
  exit 1

The last bit is important because you’ll one day try to connect to wifi at the airport, or at some public hotspot and it won’t work. It won’t work because the server is hijacking your DNS queries to redirect to some captive bullshit. The good news is that this redirect stuff is based on MAC address, so once you hit Accept – you can go back to using secure DNS.