Randomization and encryption of DNS requests

by Martin Monperrus

For sake of privacy, I want to have randomization and encryption of my DNS requests:

coredns

This is what I'm using for resolving in Firefox with TRR

The idea is that a DNS-over-HTTPS proxy resolver connects to DNS-over-TLS upstream, based on coredns.

Corefile with multiple upstream servers:

https://.:8053 {
  forward . tls://8.8.8.8 tls://1.1.1.1 tls://9.9.9.9
  log
}

Randomization: Coredns can be configured with a forwarding policy which is by default random (source). Privacy-aware randomization is discussed at https://github.com/coredns/coredns/issues/3656.

systemd-resolved (encryption only)

This is what I'm using for native resolving

systemd-resolved is a systemd service, it provides support for DNS-over-TLS, with config in /etc/systemd/resolved.conf (plus nameserver 127.0.0.53 in /etc/resolv.conf)

[Resolve]
Domains=~
DNS=1.1.1.1
DNSOverTLS=yes
Cache=yes

unbound

(This example exposes DNS locally and connects to DNS-over-TLS upstream)

Install unbound, eg on Debian aptitude install unbound

Configure it through /etc/unbound/unbound.conf.d/forward.conf.

server:
  rrset-roundrobin: yes

forward-zone:
  name: "."
  forward-ssl-upstream: yes

  forward-addr: 1.1.1.1@853
  forward-addr: 8.8.8.8@853
  forward-addr: 9.9.9.9@853  

Randomization: some kind of randomization is implemented in unbound: "The fastest server (randomly picked within a so-called RTT band of 400 msec) is selected when a query has to be sent out" (source)

dns-over-https

(This example exposes DNS-over-HTTPS locally and connects to DNS-over-TLS upstream)

Install doh-server from dns-over-https.

Configure doh-server.conf with multiple upstream servers:

upstream = [
    "tcp-tls:1.1.1.1:853",
    "tcp-tls:8.8.8.8:853",
    "tcp-tls:9.9.9.9:853",
]

Randomization: By default dns-over-https takes a random upstream server (source).

stubby

(This example exposes DNS locally and connects to DNS-over-TLS upstream)

Install stubby, eg on Debian aptitude install stubby

Then activate several DNS servers in /etc/stubby/stubby.yml.

  - address_data: 80.67.188.188
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: WaG0kHUS5N/ny0labz85HZg+v+f0b/UQ73IZjFep0nM=
 

Also, it is good to set up some servers that listens on port 443 and others on port 853, so as to be resilient if you are on a network with blocked ports. You can also blend IPv4 and IPv6 addresses.

# Instructs stubby to distribute queries across all available name servers. 
round_robin_upstreams: 1

Randomization: it is achieved with round-robin, so that the DNS request are spread over different servers. Note that this is not pure randomization, there is is featurte request for pure randomization on the stubby repository, see https://github.com/getdnsapi/stubby/issues/95.

nss-tls

(This example plugs in to glibc and connects to DNS-over-TLS upstream)

Install nss-tls which is a plugin for GlibC. It supports randomization.

Randomization: nss-tls has a unique randomization strategy: "it pseudo-randomly chooses one of the servers, for each name lookup, the choice of the server is consistent: if the same domain is resolved twice, nss-tlsd will use the same DoH server for both queries" This is good for privacy, since every upstream server only sees a portion of the user's browsing history. This addresses Sara Dickinson's concern on privacy

dnsmasq (only randomization)

(This example exposes DNS locally and connects to unsecured DNS upstream)

With dnsmasq, one can use multiple forward name servers.

In /etc/resolv.conf:

  nameserver 127.0.0.1

In /etc/dnsmasq.conf

  resolv-file /etc/resolv.dnsmasq

In /etc/resolv.dnsmasq

  nameserver 1.1.1.1
  nameserver 8.8.8.8
  nameserver 9.9.9.9

Randomization: The server is chosen not purely randomly, but it is indeed pseudo-randomly changed every 50 queries or 10 seconds have elapsed. This can be checked by logging queries (log-queries).

Configure your resolver

Modify /etc/resolv.conf so that it only contains: nameserver 127.0.0.1

If you have a laptop, note that your network manager may overwrite this configuration. This can be disabled, eg in NetworkManager (/etc/NetworkManager/NetworkManager.conf) with

[main]
dns=none
... # rest of the config

Captive portals

A downside of setting nameserver 127.0.0.1 in resolv.conf is that it breaks registration on captive portals.

A solution for this is captive-browser.

Encrypted DNS Servers

For maximum privacy prefer servers owned by different organizations.

See also: https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Public+Resolvers

TLS Servers:

# OpenDNS
208.67. 222.222

# Cloudflare
1.1.1.1@853

# Google
8.8.8.8@853

# Quad9
9.9.9.9@853

# surfnet/sinodun
145.100.185.15@443

# UncensoredDNS
89.233.43.71@853
   
# cmrg
199.58.81.218@443

# ldn
forward-addr: 80.67.188.188@443

See also