Caching dns over tor
Netizens in this day and age are rightfully concerned about their
privacy. One way for ISP's in particular to track their "customers"
is to record their dns traffic. Google likely does the same with
their dns service. Their are many dns services across the net. Some
claim to respect privacy, some support unofficial tlds, some do ad,
porn, and malware filtering.
The number one privacy tool, in my admittedly amateur and possibly
erroneous opinion, is tor. And tor now supports resolving dns requests.
"But wait" you say, "Doesn't tor only handle tcp and not udp traffic?"
and you would be right. What tor does is use a socks5 feature and
sends a RELAY_RESOLVE <hostname> request along the tor network, the
exit-node then handles the actual dns request, and sends the response
back down the line. See
https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt
section 6.4 Remote hostname lookup.
Now what is the number-one downside of using tor? latency. (Number
two would be black-listing). Therefore I set-up a caching dns server
to save requests made over tor. This has the added benefit to privacy
that no one can snoop on local requests to a cache.
First we edit our torrc to handle dns requests. tor(1) has lots of
great info on every option and lists many helpful resources.
Thankfully, asking our tor client to handle dns just for localhost
is very easy, add a single line:
DNSPort 5353 # listen for dns requests on port 5353
Why not use port 53? Because the local caching dns resolver will
use it. If you have no desire to cache dns requests, using port 53
and setting /etc/resolv.conf to use localhost will be enough.
Next we edit unbound.conf, unbound(1) and unbound.conf(5) are both
super useful. There are only two options to change, the first is
do-not-query-localhost which by default is set to yes. Perhaps,
because for most setups it's a mistake to query localhost and would
only slow it down. The next is to set our upstream dns, in this
case, our tor client.
server:
do-not-query-localhost: no
forward-zone:
name: "." # use for all queries
forward-addr: 127.0.0.1@5353 # odd format
The last step is to now tell localhost to ingnore whatever nameserver
the router tells us to use and use our own. This can be done by
editing /etc/resolv.conf and by configuring your dhcp client. On
this system, OpenBSD 6.3, dhclient is used and we just need to set
/etc/dhclient.conf to read:
supersede domain-name-servers 127.0.0.1;
Self-explanatory. Different dhcp clients will have different setups
but all are pretty similar.
Finally to check everything:
$ dig duckduckgo.com
...
;; ANSWER SECTION:
duckduckgo.com. 300 IN A 46.51.179.90
;; Query time: 3611 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
...
$ dig duckduckgo.com
...
;; ANSWER SECTION:
duckduckgo.com. 296 IN A 46.51.179.90
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
...
Caching looks good. Then visit dnsleaktest.com. Results will vary
from whatever your IP is and will vary between tests.
We're done!