Using Tor Hidden Services to access servers behind firewalls


Occasionally I find myself in situations where I'd like to make a computer accessible over SSH or similar, but am either behind a router that I dont control or otherwise accessing the internet in such a way that I can't trivially change the firewall to make my computer visible. While its possible to do this with a VPN its not always easy to set that up for each of the computers that need to access the system. So, in a pinch, I can use Tor Hidden Services.

There is a lot to the functioning and design of Tor that one could go into, but for the purposes of this post I shall keep it simple: Tor basically functions as a virtual router. You can connect to it an access the internet, and you can also open ports on it to permit others on the network to reach your server.

We begin, of course, by installing Tor on both computers. If you have root access you likely can do this via your package manager, for exaple:

# apt install tor

Its also possible to run Tor as a user without any unusual administration access, this is especially easy if your system already has a C compiler, as you merely download the Tor sourcecode, compile it and install it to some directory you have control over. I'll proceed on the assumption that this is a computer for which you have root access.

Now that we have Tor installed, on the server, we need to configure it.

On the server, in whatever text editor you fancy, open the file contained at /etc/tor/torrc, and change the section about Hidden Services to reflect the following:

62 ############### This section is just for location-hidden services ###
63
64 ## Once you have configured a hidden service, you can look at the
65 ## contents of the file ".../hidden_service/hostname" for the address
66 ## to tell people.
67 ##
68 ## HiddenServicePort x y:z says to redirect requests on port x to the
69 ## address y:z.
70
71 HiddenServiceDir /var/lib/tor/hidden_service/
72 HiddenServicePort 22 127.0.0.1:22
73
74 #HiddenServiceDir /var/lib/tor/other_hidden_service/
75 #HiddenServicePort 80 127.0.0.1:80
76 #HiddenServicePort 22 127.0.0.1:22

We've uncommented lines 71 and 72, and changed 72 to use port 22 (SSH) rather than port 80 (HTTP). What these two lines mean is that you'll declare a hidden service which will be defined in a particular path, here /var/lib/tor/hidden_service/, and that you want it to map port 22 on 127.0.0.1 to port 22 on the Hidden Service.

We can now start tor on both the client and server. Tor needn't be run as root and can be launched simply by running the Tor executable (with the -f flag to specifiy your torrc file should you have it at a non standard location), but in most cases you likely can simply run something to the effect of:

# systemctl start tor

After doing this on both the client and the server, we can now proceed to trying to connect.

On the server, there should now be a file contained in /var/lib/tor/hidden_service/hostname, which will contain a single line with a very long ugly string ending in '.onion'. This string is your server's hostname in the Tor network, and is tied to a secret key also in /var/lib/tor/hidden_service to ensure that your server is the only one which can act as that hostname within the network.

Now, assuming you have an ssh server running at the correct port on the server, we can simply access it from the other client:

$ torsocks ssh username@longuglystring.onion

and navigate any prompts it delivers.

And voila, you should now have a shell on the server. You should be able to the server from pretty much any computer pretty much wherever, regardless of whatever firewalls the client or server may be behind.