Tor is a secure network created by the US gov in 1990 [Read More].

Tor Project [Link] continues the research and development of the “Onion” network and browser.

Assuming you know what it is and how it works (at least used it before), let’s set up the HTTP hidden service in the Tor network.

Of course, we will use Linux (Ubuntu 20.04) for the server. It can also be done in Raspberry Pi (I will try and share later).

There are 3 main things for this process:

  • You need a webserver
    • We will set up a simple web server using Phyton3, but I recommend using Apache2 or NGINX for more reliable service.
    • Note that the web service will be only accessible from localhost (127.0.0.1) because the Tor service is running in localhost too and the service will be hidden from outside the Tor network.
  • You will need to install Tor Network on your server
    • Note the difference between, Tor Browser is a client that navigates inside the Tor Network.
    • We will receive one unique .onion address to the service.

Said that, let’s set it up:

sudo mkdir /var/www/tor_service
cd /var/www/tor_service
python3 -m http.server --bind 127.0.0.1 8080

The last command creates the HTTP server only accessible by 127.0.0.1 at port 8080 in the current directory. Feel free to make changes. This command will lock your terminal while the server is running, so leave this terminal running and open another terminal to continue.

sudo nano /var/www/tor_service/index.html

Add any HTML content, for example:

<html><body>Hello World!</body><html>

Then test your webserver:

curl http://127.0.0.1:8080

You should be able to see the plain text of the HTML code.

Now install the Tor Network:

sudo apt install tor -y
sudo nano /etc/tor/torrc

If ‘torrc‘ is not there, try to search for it issuing ‘whereis tor‘.

Look for the lines below, uncomment and adjust them to look like shown or match to any modification you did in your HTTP server.

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:8080

Start Tor service and verify the given address to your server:

sudo tor

If you don’t get any error message means your service is running fine. This second terminal will also stay locked while this service is running, so open a third terminal and check the generated address to your server:

sudo cat /var/lib/tor/hidden_service/hostname

You should see something like:
4l67wy7uuntt6i4tlmdznqjyqq7rwxrtwddcatkvfc6ivclfxtbndeyd.onion

This is your address in the Tor network. Understand it as a “domain”.

Note, for this exercise you used 3 terminals.

  • First to run the HTTP server;
  • Second to run the Tor;
  • Third to see the hostname (.onion address).

The first and second terminals must still be running in order to keep the hidden service active. It works very well for testing or simulations, but not for a production environment.

An alternative is to run the HTTP server as a service with Apache2 or NGINX.

And configure Tor to run as a Daemon uncomment the following line in the configuration /etc/tor/torrc:

RunAsDaemon 1

Also change the following line in the file /lib/systemd/system/tor.service:

ExecStart=/usr/sbin/tor -f /etc/tor/torrc

Reboot your system and test everything.

To have many services running on different ports and using different .onion addresses follow the syntax:

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 22 127.0.0.1:22

HiddenServiceDir /var/lib/tor/other_hidden_service/
HiddenServicePort 80 127.0.0.1:8080

Feel free to visit the project RPi Zero Tor Hidden Service.


Tip: define the geolocation of the entry and exit nodes.

sudo apt install tor-geoipdb -y
sudo nano ~/.local/share/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc

Append:

EntryNodes {us} StrictNodes 0
ExitNodes {de},{ca} StrictNodes 1

Country code’s shortlist:

AUSTRALIA {au}
BELGIUM {be}
BRAZIL {br}
CANADA {ca}
FRANCE {fr}
GERMANY {de}
HONG KONG {hk}
INDIA {in}
RUSSIAN FEDERATION {ru}
SWEDEN {se}
SWITZERLAND {ch}
UNITED KINGDOM {uk}
UNITED STATES {us}

See the full list at [Link].


BONUS

Configure your web-server on the clear internet to inform the visitors that is also offers an S address:

NGINX configuration:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    ssl_certificate /etc/ssl/fullchain.pem; 
    ssl_certificate_key /etc/ssl/privkey.pem;

    add_header Onion-Location http://<your-onion-address>.onion$request_uri;

    index index.html;
    root /var/www/html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Note: only copy and past the line in bold into your configuration. The other parts of the example are just to contextualize where the additional line have to be placed. Don’t forget to restart the web-server and check if it worked with a Tor browser.

sudo nginx -t
sudo nginx -s reload

APACHE configuration:

<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html

Header set Onion-Location "http://<your-onion-address>.onion%{REQUEST_URI}s"

SSLEngine on
SSLCertificateFile "/etc/ssl/example.com.cert"
SSLCertificateKeyFile "/etc/ssl/example.com.key"
</VirtualHost>

Test you configuration and reload the web-server:

sudo apachectl configtest
sudo systemctl reload apache2

See also how to Set Up a Tor Node [Link].

See also how to create a Tor Snowflake [Link].