Configure Tor Hidden Service
Configure Tor Hidden Service
When your relay runs as a Tor hidden service, the server's IP address is never revealed to anyone who receives an invitation. The relay is reachable only at a .onion address.
This matters because:
- Someone who intercepts the invitation link cannot find or block your server.
- The server's location is not tied to you personally.
- The person opening the link cannot accidentally reveal the server's IP to their ISP.
How this is set up
The docker-compose.yml in infra/relay includes a tor service. When started, it:
- Generates a unique
.onionkey and address (stored in a Docker volume so it persists across restarts). - Creates a hidden service that forwards
.onion:80traffic to the relay container on port 3000. - Binds no host ports — the relay is unreachable from the public internet except through Tor.
Start with Tor
docker compose up -d tor relay
Wait about 30 seconds for Tor to bootstrap. Then read the .onion address:
docker exec relay_tor_1 cat /var/lib/tor/hidden_service/hostname
You will see something like:
abc123xyz789....onion
Copy this address. Update your .env:
RELAY_BASE_URL=http://abc123xyz789....onion
Restart the relay:
docker compose restart relay
Test the hidden service
From a machine with Tor installed (or using Tor Browser):
curl --socks5-hostname 127.0.0.1:9050 http://abc123...onion/health
Expected:
{ "status": "ok" }
If you get a connection error, wait another 30 seconds. Tor hidden services take a moment to propagate.
Sharing .onion links
A .onion link looks like this:
http://abc123xyz789....onion/i/TOKEN
When a user taps this link, their device needs to be able to connect to the Tor network. The iwacu app handles this automatically — it routes .onion addresses through its built-in Tor client.
Users who do not have iwacu installed will see the landing page via Tor Browser, or get a fallback message asking them to install the app first.
.onion links over WhatsApp, SMS, or any messaging platform. The link is meaningless to anyone without iwacu or a Tor-capable browser. The platform cannot see what the link leads to.Keeping your .onion address
The .onion address is derived from a cryptographic key stored in the tor-data Docker volume. As long as this volume persists, your address stays the same.
docker volume ls | grep tor
Do not delete this volume. If you lose it, your .onion address is gone permanently and you will need to redistribute a new address to everyone who has the old one.
Back up the volume data:
docker run --rm -v relay_tor-data:/data -v $(pwd):/backup alpine \
tar czf /backup/tor-data-backup.tar.gz /data
Store this backup off the server. A server failure without a backup means starting over with a new address.