Home | Send Feedback

Expose server behind NAT with Tor

Published: 10. January 2019  •  linux

After I showed you how to expose a service behind a NAT or firewall with a VPN and a virtual private server in my previous blog post, we look at another way how you can achieve the same with different technology.

In this tutorial, we utilize the Tor network and set up a hidden service to expose a service running on a computer that isn't accessible from the public Internet. Compared to the previous VPN solution, this is very easy to set up, but accessing these services needs a bit of configuration and special software.


Tor is a free software for enabling anonymous communication and consists of thousands of relays to hide a user's IP address. For accessing the Tor network, you need special software. The easiest way to start with Tor is by downloading the Tor Browser, a customized Firefox browser with an integrated Tor proxy and some pre-installed add-ons like NoScript and HTTPS Everywhere. When you access a website on the surface Web, for example, https://www.google.com, the connection will be routed via 3 Tor relays. You can inspect them by clicking on the onion icon.

surface web

These relays hide my IP because all the server sees is the IP of the last node in the circuit (exit node). Be aware that while everything from the browser until the exit node is encrypted using HTTP over cleartext TCP, the last node can read everything you send.

This is one use case of the Tor browser, accessing websites on the surface web and hiding the IP address. You can also access a special kind of service: Hidden Services.

These services utilize the usual TCP/IP infrastructure but are only accessible from inside the Tor network. These services can even run on servers that are not accessible from the Internet and don't have a static IP address. Each server that wants to be part of the Tor network installs a Tor client to accomplish this. The client takes care of opening a permanent connection from the server to the Tor network and routes incoming traffic to the exposed services.

The traffic is usually routed over six servers when accessing a hidden service; three servers from your browser to the rendezvous server and three servers to the target server from there. This way, they try to hide the location of the client and the location of the server. Be aware that connecting to these hidden services takes longer because of the additional servers.

Expose Webserver

For demonstration purposes, I use my Raspberry Pi and install a web server, Nginx, to show the process of setting things up with Tor.

sudo -i
apt install nginx

After the package has been installed, open a browser from another computer and check if you see the Nginx welcome page. Nginx listens by default on port 80.

To expose this service, we install the Tor client.

apt install tor

Open the configuration file torrc

nano /etc/tor/torrc

Search for the following two lines and uncomment them (remove # at the start)

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80

This configuration tells Tor to redirect requests that are sent to port 80 over the Tor network to, the interface where Nginx is listening for requests.

Save the file and restart Tor.

systemctl restart tor

Change into the hidden service directory /var/lib/tor/hidden_service. Here you find a private_key and a hostname file.

cat hostname

This public onion address gives you access to your Nginx server over the Tor network.

Enter the URL from the hostname file into your Tor browser, and you should see the welcome page from Nginx. When you click on the onion icon, you see the six servers that routed the traffic from the browser to the Nginx server.



Let's expose another service, this time the SSH server of the Raspberry Pi.

Open the configuration file again.

nano /etc/tor/torrc

and add the following three lines

HiddenServiceDir /var/lib/tor/hidden_ssh/
HiddenServicePort 22
HiddenServiceAuthorizeClient stealth clien1,client2

Because SSH is such a security-sensitive service, we add an extra layer of security. With the HiddenServiceAuthorizeClient directive, we tell Tor to give access to this service to authorized clients only. In this example, we allowed two clients to access the SSH service.

Restart Tor and look into the /var/lib/tor/hidden_ssh/ directory. You find a new third file, client_keys, containing the clients' private keys. When you open hostname, you see an additional key after the address. Each client has an onion address and public key.

uwz4e5vato5n3x64.onion 5+bgjVb... # client: clien1
w7e5qlniiwacdzpf.onion eCGVCcH... # client: client2

We can't use the Tor browser to access this service because he is not an SSH client. But the Tor browser also starts a SOCKS5 proxy in the background. So go to the installation directory of your Tor browser and look for the folder.


In this folder, you find the file torrc. Close the browser and open this file with a text editor. Insert the following line to tell Tor to use this public key when somebody wants to connect to uwz4e5vato5n3x64.onion

HidServAuth uwz4e5vato5n3x64.onion 5+bgjVb...

Start the Tor browser again; this automatically starts the SOCKS5 proxy. You can use this proxy from every application on your computer that provides proxy support. The SSH client I usually use is Putty, and it has SOCKS5 support built-in. Start Putty, open the menu Connection->Proxy select SOCKS5, and enter the hostname and the port 9150.


Go to Sessions and enter the onion address into the Host Name field.


Open the connection, and you should see the login from the SSH server.

Instead of installing the complete Tor browser on Windows, you can install just the Tor proxy. Go to the download page and download the Expert bundle, unzip it and start the proxy with Tor/tor.exe. Notice that the SOCKS5 proxy listens on port 9050. The program looks in your home directory for the torrc file: C:/Users/<USER>/AppData/Roaming/tor/torrc