DNS for Tor Exit Relaying

One of the major pieces of infrastructure run by Tor Exit Nodes is DNS. DNS is the system that translates human readable names, like emeraldonion.org, into IP addresses. In Tor, the exit node is the location where this translation takes place. As such, DNS has been recognized as one of the places where centralization or attacks could be performed that could affect the integrity of the Tor network. To serve our users well, we want to mitigate the risks of compromise and surveillance as we resolve names on behalf of our users. It’s these principles that direct how we structure our DNS resolution.


Emerald Onion currently uses pfSense, which uses Unbound for DNS. Per our architectural design, we run our own recursive DNS server, meaning we query up to the root name servers for DNS resolution, and avoid the cache any upstream ISPs offering us DNS resolvers. This also means we query the authoritative resolvers directly, minimizing the number of additional parties able to observe domain resolutions coming from our users.

General Settings:

  • We use DNS Resolver and disable the DNS Forwarder
  • Only bind the DNS listener to the NIC the Tor server is connected to and localhost.
  • Only bind the DNS outgoing interface to the NIC that carries our public IP. If you use BGP, do NOT bind DNS to the interface used to connect to BGP peers.
  • Enable DNSSEC support
  • Disable DNS Query Forwarding
  • We don’t use DHCP, leave DHCP Registration disabled
  • Same goes with Static DHCP

Custom options:

prefer-ip6: yes
hide-trustanchor: yes
harden-large-queries: yes
harden-algo-downgrade: yes
qname-minimisation-strict: yes
ignore-cd-flag: yes

The most important of these options is qname-minimization, which means that when we perform a resolution like www.emeraldonion.org, we ask the root name servers only for who controls .org, the Org name servers, who controls emeraldonion.org, and only ask emerald onion’s name servers for the IP of www.emeraldonion.org. This helps to protect against our traffic resolutions being swept into the various “passive DNS” feeds that have been commoditized around the network.

Of the other custom options, the bulk are related to DNSSEC security.


Advanced Settings:

  • Hide Identity
  • Hide Version
  • Use Prefetch Support
  • Use Prefetch DNS Keys
  • Harden DNSSEC data
  • Leave the tuning values alone for now (Things like cache size, buffers, queues, jostle, etc)
  • Log Level is 1, which is pretty low.
  • Leave the rest alone.

Hiding the identity and version helps prevent the leakage of information that could be used in attacks against us. Prefetch Support changes how the DNS server fetches DNS records. Without it, it fetches the DNS record at the time of the request. With Prefetch Support, it refreshes the DNS entries as each record’s TTL expires helping to further obfuscate requests and makes it harder for specific Tor request correlation attacks.

Access Lists:

We don’t use this, but if you want to work with the Access Lists, that should be fine, just keep it in mind when troubleshooting.

DNSSEC is now fully implemented for our forward and reverse lookup zones

Last month (July 2017) we moved our DNS zone management to the Google Cloud Platform since our domains were already registered with Google. After applying for the DNSSEC alpha, we were granted access and turned on DNSSEC for all three of our forward (domain) and reverse (IPv6 and IPv4 scopes) lookup zones. Google’s alpha products come with no SLA, so we took a risk implementing DNSSEC through Google.

Turning on DNSSEC was as easy flipping a switch in the control panel. The last part is adding the DS entries at the Registrar.

In the upper-right hand corner of Zone Details is Registrar Setup. This is where we got our DS entry information.

This DS information translates to a specific Key Tag, Algorithm, Digest Type, and Digest that needs to go into Google Domains (the actual Registrar).

This completed the domain setup. Now we needed to configure DNSSEC for our reverse lookup zones. Because they are direct allocations from ARIN, we needed to copy over the DS details over to ARIN.

View and Manage Your Networks > View & Manage Network (for both our IPv6 and IPv4 scopes) > Actions > Manage Reverse DNS > (select the delegation) > Modify DS Records

String (for our IPv6) parsed:

3600 DS 46756 8 2 5396635C919BAF34F24011FAB2DE251630AE2B8C17F1B69D05BCFDD603510014

String (for our IPv4) parsed:

3600 DS 40286 8 2 54686118794BD67CC76295F3D7F1C269D70EB5646F5DA130CC590AE14B33935F

This completed the ARIN DNSSEC configuration. While Google provided a quick DNS update for validation, ARIN took over 12 hours.