A docker-compose file to provide a secure adblocking DNS server
NOTE: if you are interested in a hosted solution, please take a look at nextdns.io. I'm not affiliated with nextdns.io.
Run a secure DoT (DNS-over-TLS) and DoH (DNS-over-HTTPS) DNS server that can do ad blocking and hide your DNS query from your ISP.
Hide your DNS query from upstream recursive DNS server. Why? Because to me hide my trail from various ISPs (Verizon, ATT, and any other ISPs behind public WiFis) is more important.
We are running a DNS forwarder instead of a DNS resolver. Running a forwarder and connect to upstream DNS over secure connection does hide your DNS queries from your ISP, but it would also leaks your web history (in the form of DNS query) to the upstream DNS.
Your web history is always open to your ISP until ESNI is widely adopted. Even with ESNI, it's still easy for the ISP to learn your web history based on the IP addresses you connected.
The main benefit of running a forwarder that communicate securely with
upstream DNS is that your ISP won't be able to manipulate your DNS query
results, e.g. hijack the NXDOMAIN
response to show ads, force traffic
to go through a transparent proxy (with more and more sites offering
HTTPS, this is less of a concern) and so on.
There's a trade off you need to make whether the benefit beats the reduced privacy. Personally, making it harder for the ISP to learn my web history is a good enough reason.
- Unbound: A DNS server that provide DNS-over-TLS service. (doc)
- Pihole: Ad blocking DNS server. Pihole forked dnsmasq and provide a nice UI to manage the DNS server. (donate)
- Stubby: A DNS stub server, which support forwarding DNS request to upstream DNS-over-TLS server. Note Unbound also support forwarding request to upstream over TLS, but I was told (can't find the reference) Unbound does not reuse TLS connections which is a concern to me (my ATT gateway has an internal NAT table with limited # of entries). (doc)
- DNS-over-HTTPS: A DoH server.
- Pomerium: An identity-aware reverse proxy. This allows me to remote access PiHole's web UI. (reference)
- Autoheal: Auto-restart container that failed health check.
- Ouroboros: Auto-pull latest version of each container.
- Install Docker (how) and
docker-compose
command (how). - Know how to DNAT from your public IP to the server running the stack. Or alternatively if you have IPv6, allow dport=853 access to your server.
- Know how to get a Let's Encrypt certificate for your domain. You need a single wildcard certificate if you host both DoH server and pihole on the same server.
The following instruction will run a list of jobs on docker to DNS-over-TLS service on port 853 and foward your request through PiHole then to Google DNS.
NOTE: if you don't trust Google, please modify ./stubby/stubby.yml
and
specify a different upstream_recursive_servers
. A list of available
DNS-over-TLS name server is available at
https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers.
- Create a network called
infra_network
. (Why not create the network in the compose file? Because you cannot create thedefault
network in compose file, and can only replace it withexternal
.)
docker network create --subnet 172.30.0.0/16 infra_network
- Modify
.env
file. See the comment in that file for instructions. - Use your favorite ACME client to create free certificate from Let's
Encrypt and save it in
./letsencrypt
directory. If your domain name's NS is Cloudflare, the following is an example on how to do it within docker:
certbot:
image: certbot/dns-cloudflare:latest
container_name: certbot
dns: 172.29.1.1
restart: unless-stopped
volumes:
- ./letsencrypt/etc:/etc/letsencrypt
- ./letsencrypt/var:/var/lib/letsencrypt
- ./letsencrypt/credentials.txt:/credentials.txt
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
docker-compose up -d
and you are done :-)
None