Your DNS requests are leaking, being recorded and tampered with

Web request -> DNS -> PiHole -> dnscrypt-proxy -> VPN -> dns server

right click view image for hi res

What a path. It turns out that your ISP, NBN, VPN provider are very likely recording your DNS requests. A good friend recently pointed out:

Copyright Amendment (Online Infringement) Bill 2015
https://www.legislation.gov.au/Details/C2015A00080

>
> 115A  Injunctions against carriage service providers providing access
> to online locations outside Australia
>
>              (1)  The Federal Court of Australia may, on application
> by the owner of a copyright, grant an injunction referred to in
> subsection (2) if the Court is satisfied that:
>
>                      (a)  a carriage service provider provides access
> to an online location outside Australia; and
>
>                      (b)  the online location infringes, or
> facilitates an infringement of, the copyright; and
>
>                      (c)  the primary purpose of the online location
> is to infringe, or to facilitate the infringement of, copyright
> (whether or not in Australia).
>
>              (2)  The injunction is to require the carriage service
> provider to take reasonable steps to disable access to the online
> location.
>

DNS providers, including proxies do not do this and thus are not covered
by this amendment.

However your favourite VPN (and/or their hosting provider, since VPN providers usually don't own any computers) may be facilitating this type of activity. So to cover themselves, they may be recording or blocking your DNS requests or both.

DNS is one of those odd things that has been completely overlooked by most internet users. It passes about the place unencumbered by firewalls because it's mostly harmless. DNS is usually not encrypted because it's not considered a privacy issue.

Unforunately because these factors DNS is routinely recorded (DNS leaks) and spoofed (you ask for an address but you're given the IP of another server). Profiling a users DNS can reveal lots of things about you too.

Essentially, this is why Google provide a high quality super fast free DNS service on 8.8.8.8 and 8.8.4.4. If you use it you're pretty much handing over access to all websites you visit and all applications you use (and the DNS information is also used for search engine rankings too). Furthermore your ISPs will want to change the addresses of things like NetFlix to use their own local on network servers (which is actually a real speed benefit for users).

The intent of this piece of work is to show how to take the spyware filtered DNS requests from Pi Hole and then encrypt them so nobody can listen and record or spoof the requests. Then to make things even more interesting from the point of view of DNS providers receiving your information, the encrypted DNS requests are then run though a VPN. The final DNS providers can only record a source address of the VPN exit point, making it a bit harder (but not impossible) to correlate your identity with DNS requests. The objective is to make it too hard for Google to figure out who you are but not our national security services.

Unfortunately the approach is so successful that Google occasionally spits the dummy and refuses to answer my searches, or it puts up the dreaded Shop Front photos. After passing the IQ test they resort to fingerprinting the browser (which is the subject of yet another page - when I get to it - In the meantime go to browserleaks.com, these guys are amazing! Prepare to be shocked - your VPN is leaking like a sieve - Netflix knows you're using a VPN).

The basic layout of the, now extensive, DNS spyware blocker/filter - encryption - VPN tunnel is handled by a series of docker containers. They are:

a) Pi Hole (official)
b) dnscrypt-proxy
c) OpenVPN-client (NordVPN)
d) Apache mod-proxy (for web browsing via VPN)

Traffic at ElectricBrain.com.au doesn't all get channelled down the VPN. Obviously stuff like the Telstra Roku box won't work if it goes out via the VPN and then tries to come back in to the network. Needless to say, stopping Netflix is a major crime here at electricbrain, punishable by no cup of tea!

Details of the container builds go here.

Route a container's communications via your VPN container

Once you have your OpenVPN container installed and running, the next question becomes: how to route traffic through it. Essentially this is accomplished with the aid of the now standard program - ip. It manipulates the network Name Space of a container. Name Spaces are outside the scope of the piece, but here's a link to an old, but well written, article which covers the concepts ( https://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/)

The script file shown below (set_container_default_route.sh) relies on jq, a program that can parse JSON produced by Docker. Docker is able to provide a wealth of information about any of the containers under its control. In amongst all that is the IP address allocated at container creation time. This is vital since it is otherwise quite difficult to divine the IP of a container. Once armed with the OpenVPN container's address it's possible to tell another container to direct all its traffic to the OpenVPN router container thereby encapsulating and encrypting everything. (This has now changed to fixed IPs using a Docker Network where IP can be allocated at startup time - so jq is no longer required).

Install jq ("dnf install jq" or "yum install jq") which comes with a good man page explaining how to use it. The OpenVPN container's name is hard wired to 'openvpn' in the docker inspect command but might require changing depeding on your circumstances.

#!/bin/bash
#
# Get the VPN container's address
#
set -x

if [ $# != 1 ]
then
  echo "Usage: $0 container_name"
  exit 1
fi

gcVPNaddress=`docker inspect openvpn | jq '.[0].NetworkSettings.IPAddress'`
gcVPNaddress="${gcVPNaddress%\"}"
gcVPNaddress="${gcVPNaddress#\"}"

echo ">>$gcVPNaddress<<"

#
# Set the $1 container's routes
#
pid=$(docker inspect -f '{{.State.Pid}}' "$1")
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
ip netns exec $pid ip route del default
ip netns exec $pid ip route add 172.17.0.0/16 via 172.17.0.1
ip netns exec $pid ip route add 192.168.0.0/24 via 172.17.0.1
ip netns exec $pid ip route add default via $gcVPNaddress

Details of rejigging/tuning the Linux IP stack on the firewall/router go here.

Things that cause Pi-Hole to hang.

Unfortunately the errors below from dnscrypt-proxy kill the entire network here. PI Hole's DHCP stops working too, so eventually all computers lose their address allocations and drop off completely.

Update (March 2019): This issue appears to now be addressed in docker.io/pihole/pihole:4.2.2_armhf

[2019-02-04 22:01:44]   172.17.0.2      nrdp50-appboot.netflix.com      A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      customerevents.netflix.com      A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      cdn-0.nflximg.com       A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      nrdp.prod.ftl.netflix.com       A       PASS
[2019-02-04 22:01:44]   172.17.0.2      nrdp-moderate.prod.ftl.netflix.com      A       PASS
[2019-02-04 22:01:44]   172.17.0.2      push.prod.netflix.com   A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      secure.netflix.com      A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      cdn-0.nflximg.com       A       SERVER_ERROR
[2019-02-04 22:01:44]   172.17.0.2      nrdp-conservative.prod.ftl.netflix.com  A       SERVER_ERROR
[2019-02-04 22:06:06]   172.17.0.4      play.googleapis.com     A       PASS
[2019-02-04 22:06:09]   172.17.0.4      play.googleapis.com     AAAA    SERVER_ERROR
[2019-02-04 22:06:16]   172.17.0.4      play.googleapis.com     A       PASS
[2019-02-04 22:06:16]   172.17.0.4      play.googleapis.com     AAAA    PASS
[2019-02-04 22:10:18]   172.17.0.4      play.itunes.apple.com   A       PASS
[2019-02-04 22:10:19]   172.17.0.4      omt.garmin.com  A       PASS
[2019-02-04 22:10:19]   172.17.0.4      omt.garmin.com  AAAA    PASS
[2019-02-04 22:10:20]   172.17.0.4      play.itunes.apple.com   AAAA    SERVER_ERROR
[2019-02-04 22:10:22]   172.17.0.4      c.apple.news    A       PASS
[2019-02-04 22:10:24]   172.17.0.4      c.apple.news    AAAA    SERVER_ERROR
[2019-02-04 22:10:29]   172.17.0.4      connectapi.garmin.com   A       PASS
[2019-02-04 22:10:31]   172.17.0.4      connectapi.garmin.com   AAAA    SERVER_ERROR
[2019-02-04 22:10:31]   172.17.0.4      c.apple.news    A       PASS
[2019-02-04 22:10:34]   172.17.0.4      c.apple.news    AAAA    SERVER_ERROR
[2019-02-04 22:10:38]   172.17.0.4      connectapi.garmin.com   A       PASS
[2019-02-04 22:10:39]   172.17.0.4      connectapi.garmin.com   AAAA    PASS
[2019-02-04 22:10:41]   172.17.0.4      c.apple.news    A       PASS
[2019-02-04 22:10:42]   172.17.0.4      c.apple.news    AAAA    PASS
[2019-02-04 22:11:05]   172.17.0.4      gold.garmin.com A       PASS
[2019-02-04 22:11:06]   172.17.0.4      gold.garmin.com AAAA    PASS
[2019-02-04 22:11:48]   172.17.0.2      www.jbhifi.com.au       A       SERVER_ERROR
[2019-02-04 22:11:48]   172.17.0.2      www.jbhifi.com.au       A       SERVER_ERROR
[2019-02-04 22:11:48]   172.17.0.2      www.jbhifi.com.au       AAAA    SERVER_ERROR
[2019-02-04 22:13:11]   172.17.0.4      news-edge.apple.com     A       PASS
[2019-02-04 22:13:11]   172.17.0.4      news-edge.apple.com     AAAA    PASS

Successful dnscrypt-proxy.toml configuration

Details of criticisms of dnscrypt-proxy's default config go here (but look at:
https://diasp.org/posts/a02706b0efe301367610047d7b62795e ).

Update (March 2019): Since version docker.io/pihole/pihole:4.2.2_armhf PiHole seems immune to defective encrypted DNS servers. The server_names entry has therefore been commented out allowing dnscrypt_proxy to spray requests all over the world.

During testing it became apparent that Google is now using the same technique as DNSLEAKTEST to correlate user DNS requests back to pages requests. Spraying DNS requests all over the place seems to bring up more shopfront and traffic signal image requests, so I guess there is some effect. Just be aware this is happening, particularly on youtube.

Only modifed lines shown:

# Use reliable server - SERVER_ERROR responses lock Pi Hole up good!
# server_names = ['scaleway-fr', 'google', 'yandex', 'cloudflare']
# server_names = ['cloudfare', 'publicarray-au-doh']

# Port 53 for http proxy container and 5353 for Pi Hole container
listen_addresses = [ '0.0.0.0:53', '0.0.0.0:5353' ]

# Prevent ipv6 lookups upstream via ipv4. Security leak of local server names. Easy to identify source.
#block_ipv6 = false
block_ipv6 = true

# Use this instead of a local name server for on LAN servers
#cloaking_rules = '/etc/dnscrypt-proxy/cloaking-rules.txt'
cloaking_rules = '/etc/dnscrypt-proxy/cloaking-rules.txt'

 

# Pi Hole is already doing this for us
#cache = true
cache = false

Fix for hanging on TCP DNS queries from NetFlix

This link is to an excellent piece of work than resolves this and other issues:

https://medium.com/@AaronKalair/netflix-brought-down-my-home-network-bec5dac0b7c5

Essentially TCP needs to be disabled for port 53. Only UDP should be allowed through to Pi Hole.

Your true IP may be leaking via IPv6

Once connected via a VPN run this check to verify your real IP address is not leaking. Mine was.... doh!