DNS security, anonymity, and Pi-hole: what are the options?


This is my attempt at understanding the intricacies of DNS, primarily based on what I’ve learned while setting up Pi-hole, and hopefully figuring how to achieve an even better setup. Hopefully, this isn’t too far off the mark but where inaccuracies occur please do point them out.

The goals in having a Raspberry Pi 3+ running Pi-hole for me, and I assume for most, are:

  1. Network-wide adblocking

  2. Adblocking on devices (particularly phones) when away from home

  3. Enhance DNS and general privacy – as few as possible should be able to monitor your DNS and your internet activity

  4. Enhance DNS and general security – nobody should be able to tamper with your DNS request.

PH pretty much achieves 1) by its default setup, and with some tinkering it’s possible to run OpenVPN on the Raspberry and connect to it remotely, thereby achieving 2). To me, it seems like there isn’t that much to raffle about so far. However, due to the nature of DNS, figuring out the best way to optimize 3) and 4) is a bit tricky. Specifically, I’m thinking of the ability to hijack DNS and its unencrypted nature, which allows surveillance and logging of your internet history by your ISP (particularly if you are using their DNS server) and others (insert various 3-letter-agencies here).

To quote the pi-hole documentation:

With standard DNS, requests are sent in plain-text, with no method to detect tampering or misbehavior. This means that not only can a malicious actor look at all the DNS requests you are making (and therefore what websites you are visiting), they can also tamper with the response and redirect your device to resources in their control (such as a fake login page for internet banking).


Assuming a ‘basic’ setup that is running an OpenVPN server on a Raspberry Pi that your phone is connected to, the phone’s traffic would be encrypted on its way to the Raspberry Pi but the DNS lookups sent from the Raspberry Pi to the upstream DNS server, operated by your ISP, would be in plain-text and you can’t be sure of the integrity of the replies you receive.

There are various ways of trying to deal with the mess:

  • Change the DNS server from which your Pi-hole asks for info – how this helps depends a lot on who you decide to ask, e.g. it’s probably not a good idea to ask Google to optimize 3). Neither does this help with 4). https://docs.pi-hole.net/guides/upstream-dns-providers/

    • Make PI a recursive DNS server – this way, no single entity like Google, your ISP or Cloudflare will see your DNS activity. This helps with 3) but not 4). But we can combine it with DNSSEC which does help with 4)…https://docs.pi-hole.net/guides/unbound/
  • DNSSEC – you can be sure you’re actually ending up on the website you wanted to visit, not some sketchy website that wants to make you mine cryptocurrency for them, i.e. it helps with 4). However, it doesn’t encrypt your DNS traffic so 3) is still an issue and depending on where your Pi-hole is getting its info from, e.g. Google or Cloudflare would know everything you’re looking up. https://docs.pi-hole.net/guides/unbound/

So it seems that we just need to add encryption between the Pi-hole and upstream DNS servers which is actually possible!

  • DNS over HTTPS – The DNS traffic is sent via HTTPS and is as such encrypted. Neither your ISP nor Google can see what’s going on and no sketchy types can tamper with where you end up. So we’ve reached 3) and 4) and can close down the shop (or browser)? Sadly, no. While 4 has been obtained 3) isn’t looking too great. DNS Over HTTPS isn’t supported many places (see https://en.wikipedia.org/wiki/Public_recursive_name_server) and the setup as described by pi-hole docs requires that we lock ourselves into one particular upstream DNS, Cloudflare, which means the whole ‘making your PH a recursive DNS server’-thing, isn’t an option anymore. Since a single entity like Cloudflare would be getting all your DNS traffic, this is not a solution to me as it goes against 3).


This is pretty much where I have stranded myself right now, currently having my PH configured as a recursive DNS server with DNSSEC enabled, looking for a way to further enhance my privacy (further). I have not mentioned DNS over TLS since it’s not in the Pi-hole docs and seems to result in the same issues as DNS over HTTPS.

You can, of course, use a VPN provider and connect to them from your devices, assuming you trust the VPN (if you don’t, it doesn’t seem to make sense to use one) this would solve 3) and 4), but then we’ve moved away from the whole point: 1). Unless you configure the VPN to use your PH as DNS server, but this is not possible if you want 2) and as far as I can tell, you wouldn’t really be much better off than you were in the first place in regards to 3) and 4), since you want to encrypt the bloody DNS traffic.

The only solution that I can think of is to change my configuration to DNS over HTTPS but preventing Cloudflare from knowing my identity by having all of my network traffic run through a VPN service so that the VPN provider appears as the source of the DNS traffic from Cloudflare’s point of view.

My question finally then is if this is this possible, or is there a simpler/better way to achieve the same result?


Is it possible to both achieve both DNS security (your DNS traffic can’t be tampered with) and privacy (only you have complete knowledge of your DNS traffic) while running an OpenVPN server on your Raspberry Pi, which runs Pi-hole. If so, how?


You could setup unboud DNS and have that configured listen on a diffrent port (55 or something) for DNS queuries. This way it can co-exist next to pihole/dnsmasq.
Tehre is descent info on the web to configure it to use DNS over TLS, TCP port 853 encrypted.
Example 2, but change the port to 55 or something free and best to limit it to cloadflare

Once you have this Unbound runnning with cloudflare, change the upsteam server in the pihole config page to the ip adress of the pihole with the correct port.(55)

Now unbound encrypts the DNS queries.
Have not tested this, but should work as long as you change the listen port in unbound.

I assume you know how to install unboud with apt-get.

Best ro make a copy of your sd card first with rpi-clone.


Good discussion and your understanding is correct (at least matches mine). My thoughts:

  1. You have to trust somebody along the way. Your ISP sees all your traffic. If you hide your DNS requests from them (by encrypted DNS to a third party provider), they don’t see those requests but will immediately see the request for traffic from an IP (even if https the request is in the clear). Your ISP can quickly figure out where you are going on the web. And, the third party provider has all your traffic tied to your IP. You have to trust two parties (the DNS provider and your ISP).

  2. If you route all through a VPN (DNS and traffic), you have to trust the VPN, but your ISP sees none of it.

  3. With unbound as your local resolver (using DNSSEC and qname minimisation and perhaps “use-caps-for-id” (experimental), you don’t give any one party all your DNS history, although your ISP sees the requests. You have to trust yourself and your ISP. For the reason that your ISP sees all your traffic requests anyway, I don’t think encrypted DNS is of much value compared to unbound.

  4. For my purposes, I settled on unbound as local resolver, route traffic through ISP. This routes my incoming OPENVPN DNS through unbound, but since that’s what I choose when I’m at home it’s good enough when away.

For out of market streaming or access to foreign content or to visit a potentially sketchy website for the first time, I use a VPN service and route all traffic through that. That’s not very frequent, and i give up Pi-Hole for that traffic (acceptable for me). ISP sees nothing, and I appear to originate in a country of my choosing.

You could use a VPN service and route your DNS traffic outside the VPN encrypted to a third party DNS. ISP sees none of it, but you are back to trusting two parties (DNS and ISP), and you get the benefits of your Pi-Hole. Performance can also be an issue with VPN services.

Another option is Tor. Multiple random hops, probably the most difficult for intermediaries to see the whole path. Has its drawbacks as well - performance, not an absolute guarantee of anonymity.

Summary - for DNS security and reasonable privacy, unbound as local resolver. For anonymity, Tor or VPN (or Tor while running on a VPN).


Hi all,

Yes, agree with jfb and QED.
Not beeing a network specialist:
Yes your isp sees (dns) traffic to cloudflare, but: are you sure the isp is able to see what domain you are requesting? As this should be encrypted…
Most isp is logging dns requests on their own dns servers to have some tracking records.
At least this logging is gone now. Enhanching a little more privacy

For the other part: without a vpn or something: yes: your isp knows what you are doing.
At least the ipadresses you are visiting.

If you want nothing of this to be seen by your isp, only option is a VPN based solution or Tor.
As Tor is already infiltrated with bad “gateway” / exit nodes from most of the 3 letter known agencys, I would not trust the total anonymaty from Tor, unless you know what exit node can be trusted…
Do you know really…?

Leaves VPN…Can anyone really tell what VPN is not under some control of gouvernement 3 letter agencies?

So who to trust :slight_smile: ?

The days of total anonymity are something from the past.
Beeing a good citizen: that is something positive as long as you live in a western country.
With current threaths. I think it is good we are under some kind of control.
How else can we keep our family and childrens safe?


That’s the ultimate question. Without wanting to repeat this discussion, I can tell you what I’m doing: I run a local unbound instance just like @jfb mentioned.

It directly queries the respective DNS servers on the web, e.g. Google will know that I queried www.google.com but they will not know when I query www.pi-hole.net. Actually, nobody will know everything. As unbound will only query the name server of the company you want to connect to. This is the major difference to asking a single provider (such as Cloudflare) which could log all of your requests. The integrity of the data is ensured using DNSSEC inside unbound.

It is true that your ISP (or VPN provider) is (potentially) able to record your DNS packets, but, as has also already been mentioned, they can anyways record your entire traffic. In my case, I decided to trust my ISP more than any external DNS provider as I pay them money whereas the services of Cloudflare, etc. as “free”. And you know how things work these days: Companies never offer services for free, you pay at least with your data and data are actually quite valuable.


As @jfb and @DL6ER I also prefer the method of a local resolver.
Additionally (started to work with unbound 1.7.0) I also set in unbound an auth-zone and query the root servers directly to transfer me the root-zone file. This file is then used in future queries been used the query the correct data.
It means if I query for google.com, then unbound doesnt ask the root servers but it begins its query with the .com zone.

Maybe it doesnt raise privacy too much (qname minimisation) but it feels good :slight_smile:


Would you mind explaining how to do this?


First of all, you need a newer unbound version (version 1.7.0 and newer).
Then define an auth zone with some root server and where to put the zonefile.

Example of mine:

name: "."
master: f.root-servers.net
master: k.root-servers.net
master: l.root-servers.net
master: j.root-servers.net
fallback-enabled: yes
for-downstream: no
for-upstream: yes
zonefile: "/var/lib/unbound/root.zone"

Restart unbound and there you go :slight_smile:


Using unbound 1.8.1
The file is NOT created when starting unbound, no error message. If I manually create an empty file, the file remains empty, again, no error message. In the sample unbound configuration file, the root auth-zone is defined as you describe, but without the zonefile setting.
The only thing I notice is a lot of queries to the root servers, defined in the configuration.

What am I missing?


While I agree with most you said, this sentence is no longer 100% correct. Recently Cloudflare introduced support for encrypted SNI as an extension for TLS 1.3. I think that closes the hole you’re talking about (if combined with DoH).

Needless to say that other aspects have to considered:

  1. You have to trust Cloudflare.
  2. One must hope that many DNS providers will introduce that, too, in order to avoid a monopolization of the DNS system - a tendency which is clearly observable.

I’m also running unbound and I hope that the root servers will introduce encryption as well before long (DNSSEC is already supported).


Good question. I am using 1.8.0 build from sid debian sources and here everything is working fine. (last root zone update 6hrs ago). Maybe some chroot error with unbound? Did you raise verbosity level to check log file?


Found the problem. I copy / paste your example (from discourse) in notepad++. For some reason, the quotes are changed. Changed the quotes, restarted, all OK


Good catch on the punctuation. This happens occasionally on discourse. I edited the referenced post to remove the fancy quotes, but even with that they sometimes re-appear in a copy and paste.