Randomization and encryption of DNS requests

by Martin Monperrus

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

One solution to this is to use the DNS-over-TLS protocol together with the a DNS client that supports randomization. For maximum privacy prefer servers owned by different organizations. If you set up x (say x=10) DNS servers, only 1/x of your DNS requests will be intercepted if one of those servers get infiltrated.

How to do so?

  1. Install and configure stubby or unbound
  2. Set up your box to use it

Solution with stubby

Install stubby, eg on Debian aptitude install stubby

Then activate several DNS servers in /etc/stubby/stubby.yml. A list of DNS-over-TLS server can be found at https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Public+Resolvers.

  - 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.

Next, activate round-robin, so that your DNS request are spread over different servers:

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

This is not pure randomization but it is satisfactory enough. There is is feature request for pure randomization on the stubby repository, see https://github.com/getdnsapi/stubby/issues/95.

Solution with unbound

Install unbound, eg on Debian aptitude install unbound

Configure it through /etc/unbound/unbound.conf.d/forward.conf. A list of DNS-over-TLS server can be found at https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Public+Resolvers.

server:
  rrset-roundrobin: yes
  #    do-ip6: no
  #verbosity: 3

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

  # surfnet/sinodun
  forward-addr: 145.100.185.15@443
  
  # Quad9
  forward-addr: 9.9.9.9@853
  
  # Cloudflare
  forward-addr: 1.1.1.1@853

  # UncensoredDNS
  forward-addr: 89.233.43.71@853
    
  # securedns.eu
  forward-addr: 146.185.167.43@853
  
  # cmrg
  forward-addr: 199.58.81.218@443
  
  # ldn
  forward-addr: 80.67.188.188@443

Randomization is builtin 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

Configure your resolver

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

If you have a laptop, not' 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

Open questions

"Over time (days, weeks) any resolver you use (either in round robin or with a random distribution) will likely acquire enough information about an end user to profile that user because over time it will see the entire query profile (we are creatures of habit and tend to visit the same sites)." Sara Dickinson on Github

On solution to this would be to randomize but deterministically: a random server only sees a slice of your traffic, but this slice always goes to the same server. For instance, all requests to domains starting with letter "a-g" go to DNS server "foo" and all requests to domains starting with letter "h-z" go to DNS server "bar".

Downside

The only downside of this approach is that when you are behind a captive portal, you first have to manually set /etc/resolv.conf to get the IP of the registration portal, and, once registered, to revert to the normal configuration.

Alternatives

Use DNS over HTTPS: see Configure DNS Over HTTPS in Firefox (network.trr.mode)

Use DNS over TOR: see Resolving DNS through TOR @ stackexchange

See also

Other configurations

# The following unbound configuration includes domain name verification.
# based on local CA
server:
  # on debian 
  tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"

  # other possibility
  #tls-cert-bundle: "/etc/pki/tls/certs/ca-bundle.crt"
forward-zone:
  name: "."
  forward-tls-upstream: yes
  forward-addr: 9.9.9.9@853#dns.quad9.net
  forward-addr: 1.1.1.1@853#cloudflare-dns.com

 
 

Tagged as: