Transparent Access to Tor Hidden Services

Written 4 years ago by Mike Cardwell

Tor is a network which allows you to anonymously access services on the Internet. Tor also has a feature for hosting TCP based services anonymously called Hidden Services. I have configured my home network to allow any connected device to access these hidden services without having to install any additional software or reconfigure any proxy settings on them.

A standard Tor installation exposes a SOCKS proxy on port 9050. The idea is that if you want an application to connect to a service through Tor (including hidden services), then you should configure it to connect via that SOCKS proxy (if the application has such a setting). I have a Debian GNU/Linux (Jessie) machine at the edge of my network, which sits between the Internet and my LAN. It handles DHCP, DNS and NAT amongst other things. I have configured that machine to intercept connections to .onion hostnames and then redirect them through Tor. I will refer to this machine as “the router” from now on.

If it is essential that you hide the fact that you are visiting a Tor hidden service, then you should install the Tor Browser Bundle on your own machine, otherwise there are potential leaks. Always use the Tor Browser Bundle unless you are confident you know what you are doing. However if you don’t care that the owner of the hidden service, or myself (when on my network), or my ISP could potentially see that you visited a particular hidden service, then you can rely on the transparent routing that my network provides. Sometimes it is important for the provider of the hidden service to remain anonymous, but not necessarily for the person accessing it. This is the situation that my setup works well for.

Installing Tor

I personally prefer to use the experimental versions of Tor. This is optional, but if you want to do it, you just need to add the following to your /etc/apt/sources.list:

deb experimental-jessie main
deb-src experimental-jessie main

Then on your router, you just need to run “apt-get update” and “apt-get install tor”. You may need to install “apt-transport-https” first otherwise apt wont like accessing HTTPS based repositories.

Adding DNS to .onion hostnames

.onion is not a “real” TLD. If I were to try and visit http://abcdefgh12345678.onion/ (fake), then my web browser would perform a DNS lookup, which would fail, and wouldn’t even attempt to make a connection, so my router would have nothing to intercept and re-route. In my /etc/tor/torrc I added the following:

AutomapHostsOnResolve 1

This causes Tor to expose a DNS server on port 5300. Whenever you perform a DNS lookup of a .onion domain against Tor’s DNSPort, Tor will create a temporary internal mapping, linking a previously unused IP address in the “” range to that .onion hostname, and will return that IP address in the DNS response. Tor will then know that any future connection attempts to that IP address are meant for that .onion hostname. I picked “” simply because it was a range that I wasn’t already using on my network.

The reason I used port 5300 rather than the standard port 53 is because I only want “.onion” DNS lookups to go through Tor. I don’t want any other domains to be looked up through Tor. I have a caching DNS resolver on my router listening on port 53, named Unbound which is advertised to the rest of the machines on my LAN via DHCP. I added the following configuration to it to make it reroute .onion DNS requests via Tor:

domain-insecure: "onion"
private-domain: "onion"
do-not-query-localhost: no
local-zone: "onion." nodefault

    name: "onion"

Routing connections through Tor

As well as the usual SOCKS proxy interface that Tor provides, there is also another interface which you can turn on which will route raw TCP connections through Tor. I added the following configuration to /etc/tor/torrc:

TransPort 9040

And then ran the following commands:

iptables        -A INPUT      -p tcp --dport 9040     -j ACCEPT
iptables -t nat -A PREROUTING -p tcp -d -j REDIRECT --to-port 9040
iptables -t nat -A OUTPUT     -p tcp -d -j REDIRECT --to-port 9040

Now, when one of my clients attempts to connect to “abcdefgh12345678.onion”, the following happens. A DNS lookup for “abcdefgh12345678.onion” is made, which hits Unbound. Unbound then forwards the request on to Tor running on port 5300. Tor allocates an IP address like for example and returns that back to Unbound, which returns it to the client. The client then attempts to open a TCP connection to This connection hits the router. The iptables rules on the router notice it is in the range and then redirects it to Tor running on port 9040. Tor notices that the connection was originally going to and that has a mapping to “abcdefgh12345678.onion”, and so routes it to that hidden service.

Performance Improvements

Ordinarily when connecting to a Tor hidden service, your client makes a 3-hop circuit to a rendevouz point which the hidden service also maintains a 3-hop circuit to, meaning that there are 6 hops between you and the hidden service. This is part of the reason why they are so slow to load. We’ve already established that in this transparent routing configration, the anonymity of the client is already potentially compromised, so wouldn’t it be nice if we could just make a direct connection to the rendevouz point instead of a 3-hop connection (reducing the total from 6 to 4), to speed things up? Well luckily, this is possible, thanks to “Tor2webMode”. Tor2webMode was created in order to speed up sites like, but we can use it too. You need to compile a special version of Tor with this mode enabled and it will prevent you from connecting to anything other than hidden services, i.e connecting to Internet facing services through exit nodes. If you need this functionality, you can always run two copies of Tor, one in Tor2webMode and one not.

To build Tor in Tor2webMode on Debian, I do the following:

cd /usr/local/src
mkdir tor
cd tor
apt-get update
apt-get source tor
cd tor-$VERSION/

I then add “confflags += –enable-tor2web-mode” to the top of “debian/rules”, comment out the “if” block starting “if (options->Tor2webMode) {“ in “src/or/connection_edge.c”, comment out the “ifdef” block starting “#ifdef ENABLE_TOR2WEB_MODE” in “src/or/config.c”, and then run “debuild”. This gives you a nice Debian package that you can install, or you can just run the binary directly from “build/src/or/tor”

I then add the following to the torrc configuration file to finish it off:

Tor2webMode 1

I’ve also got a similar setup for accessing I2P eepSites, which I describe in a previous blog post called Transparent Access to I2P eepSites

Looking to hire somebody like me? I'm open to offers of full time employment and small contract jobs. Check out my hiring page. You can follow this Blog using RSS or . To read more, visit my blog index.

Feeling generous?BitcoinMoneroZcashPaypal