[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-talk] Experimental DNS/DNSSEC hidden service HOWTO (optionally over TLS)
I've started a DNS/DNSSEC hidden service at b36iqwi6e4l4eyvf.onion. The
service listens on two ports:
- 53 (plain DNS over TCP)
- 44353 (DNS over TLS)
The TLS version is an experiment - paradoxically not for security
(unbound currently does not check the certificate), but as a hackish
attempt at performance.
Below is a HOWTO for setting up your system resolver to upstream to the
hidden service with unbound.
1. For whom and what purpose is it intended
- DNS hidden service can be used as your system resolver if you have a
virtualized environment (virtualized Linux distribution)
- you want to resolve "uncommon" RR types like SRV for XMPP (Jabber)
- you still should use Tor SOCKS proxy for any application that needs
only connecting to a given FQDN and TCP port (like browsers, IRC) so
that no unnecessary DNS requests are made. See
 for more information about circuit correlation. Tor
0.2.3.x-alpha recommended due to stream isolation support.
- in the steps below, 9050 is expected to be Tor's SocksPort (the default)
- is it slow? Yes, it's very slow. Expect timeouts. A lot depends on the
state of unbound's cache of DNS records.
2. What software you'll need
- unbound, latest (1.4.16) is recommended, some features like
tcp-forwarding or DNS-over-TLS may not be available in older versions
- socat (http://www.dest-unreach.org/socat/)
- dig (from bind-utils, this is just for testing the tunnel)
3. Setup of resolver on client side (version without inner TLS)
Create a file name /etc/unbound/root.key containing (this is for DNSSEC
"." 257 3 8
// key id = 19036
In /etc/unbound/unbound.conf, find the line with option
'trusted-keys-file' and point it to the root.key file (make sure the
line is not commented out by leading #).
(Note: if you don't set the 'trusted-keys-file' and also keep other DNS
key settings like 'dlv-anchor-file' commented out, that will turn off
DNSSEC validation - makes the DNS resolving faster, unbound acts as a
non-validating caching resolver.)
In the same way, find option 'tcp-upstream' and change it to 'yes':
At the end of /etc/unbound/unbound.conf, add following lines (that is
what makes the forwarding to the upstream DNS hidden service happen):
Next, we setup socat so that it will listen on 5353 and upstream any DNS
request made by system to the hidden service (run in different terminal
or screen, you may remove the two '-d -d' later, those are just for
debugging purposes to see when it opens/closes connection):
socat -d -d TCP4-LISTEN:5353,fork \
First check that the hidden service is connected (try few times if 'dig'
dig +dnssec +tcp -p 5353 addons.mozilla.org @localhost
If you got answer, it's time to start the local unbound resolver:
There's an utility named 'unbound-checkconf' that might help you if
unbound complains about errors in config.
Again, try if unbound can resolve (may timeout, try multiple times):
dig +dnssec addons.mozilla.org @localhost
If it seems to work, make unbound your system resolver by replacing any
lines in /etc/resolv.conf starting with "nameserver" by:
Note that if the Linux distro is using things like NetworkManager (or
dhclient hooks), you need to tell them to set local unbound as resolver.
E.g. for NetworkManager by creating file
with the following contents (make it executable):
# Override /etc/resolv.conf to use unbound, no search and no domain
if [ "$2" = "up" ]; then
echo "nameserver 127.0.0.1" > /etc/resolv.conf
4. Configuring client's unbound for DNS-over-TLS
In unbound.conf, uncomment and set 'ssl-upstream' to 'yes'. Then, in the
socat invocation, change destination to port 44353, i.e.:
socat -d -d TCP4-LISTEN:5353,fork \
Restart of unbound is necessary if already running.
The TLS version was an attempt to side-step the performance issue that
unbound opens TCP connection for each query (i.e. what would be single
UDP packet is now TCP SYN/ACK-handshake+data+FIN/ACK).
Still not sure it actually helped, seeing TLS encrypted alert 21 often
(followed by partial TLS handshake in some cases and FIN/ACK in others).
5. Setting up unbound as DNS hidden service
It's done just as any other hidden service , just point it at local
port 53. By default unbound listens on TCP (option 'do-tcp').
If you want to have the service "hidden", you need to upstream to other
resolver either via VPN or unbound's 'forward-zone' option (just like
above, only set the address to an actual IP adress of validating
But keep in mind that it's not "really hidden" since it needs to perform
DNS queries to outside world.
If you want TLS as well, first generate a self-signed certificate and
key using openssl, then set in unbound.conf:
#unbound.pem and unbound.key are the generated cert/key
This is not "full DNS/DNSSEC in Tor" yet, but can be used/deployed
Other not yet mentioned quirks:
- not scalable as such (no load-balancing/resolver switching at client's
- resolving timeouts might cause strange corner-cases, like unbound
thinking that a response is bogus because DNSKEY query timed out
- greatest problem performance-wise is validation of names that chain
through multiple zones due the use of CNAME/DNAME (commonly CDN/cloud
services - requires many DS/DNSKEY queries)
- "if it times out first time, there's good chance it will work second
time" - usually unbound queried and cached the reply in the meantime
tor-talk mailing list