Hosting a Website Over Tor

This post describes the process of hosting a Tor .onion service and it assumes familiarity with Tor and experience with Linux service hosting.

How onion hosting works

Hosting an onion service is fairly similar to running a reverse tunnel. If you have used Cloudflare Tunnel, Pangolin, or similar tooling, the model will be familiar. A local service is exposed through an outbound connection, without opening inbound ports or advertising a public IP address.

With Tor, this is built into the network itself. When you configure an onion service, Tor generates a cryptographic key pair. The private key stays on the server and never leaves it. The public key is encoded directly into the .onion address. This is the reason behind the long onion addresses.

Because the address is derived from the public key, it is self authenticating. When a client connects to an onion service, Tor can verify that it has reached the service that owns the corresponding private key. There is no separate DNS lookup or external cert authority as address and the identity are the same thing.

Once the service is configured, the Tor daemon publishes service descriptors into the Tor network. Clients retrieve these descriptors and establish encrypted circuits to the service. Traffic is end to end encrypted between the client and the onion service. At no point does the client open a direct TCP connection to the server, and the server never learns the client's IP address.

From an operational perspective, the server only needs outbound connectivity and as long as the Tor process can reach the network, the service is reachable. Also, the onion address remains stable as long as the private key is preserved. If the key is lost, the address is lost with it.

System requirements

The setup requires a Linux host, Tor installed from distribution packages, and a web server already capable of serving the site locally. Persistent storage is required for Tor's service keys. There are no special hardware or network requirements beyond that.

The examples below assume a Debian / Ubuntu based system.

Installing Tor

Install Tor using the system package manager.

sudo apt update
sudo apt install tor

Once installed, verify that the service is running.

systemctl status tor

The Tor Browser is not needed on the server, only the Tor daemon is required.

Defining an onion service

Onion services are defined in Tor's configuration file.

sudo nano /etc/tor/torrc

Add a service definition.

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

The directory specified by HiddenServiceDir is where Tor stores the private key and the generated hostname. The HiddenServicePort line maps a virtual port on the onion service to a local address and port on the server.

Restart Tor to apply the configuration.

sudo systemctl restart tor

After restart, Tor creates the service directory and writes the hostname file. Reading this file shows the onion address.

sudo cat /var/lib/tor/ambientnode/hostname

This address is immediately usable.

Web server configuration

The web server should listen on a local interface for the onion service and you should not expose this publicly.

A minimal Nginx example looks like this.

server {
listen 127.0.0.1:8080;
server_name _;

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

TLS is not required for onion traffic, as Tor already provides encryption and authentication.

Key management and persistence

The onion address is tied directly to the private key stored in the service directory, so the directory should be backed up. If the key is deleted or corrupted, the onion address cannot be recovered.

In containerised setups, this directory must be mounted as a persistent volume and treated the same way you would treat a long lived TLS private key.

Access the onion address using Tor Browser. Assets should use relative URLs or be otherwise compatible with both access paths.

Notes

Onion services have higher latency than direct clearnet access due to the circuit establishment and lower throughput, so the site loading slower than on clear net is normal.

Discoverability is limited since onion sites are not indexed in the same way as clearnet sites, and users must already know the address.

Running an onion service is pretty simple as long as you understand how identity and addressing are tied together, and handle the service keys correctly. There is of course also the perception issue. Public understanding of Tor has largely been shaped by media coverage that tends to focus on criminal use cases. As a result, people associate .onion addresses exclusively with illegal activity. This association is inaccurate, but it exists and should be expected when running a Tor site.