// Host anonymously. Leave no trace.
// WHAT WE'RE BUILDING
In this tutorial, you'll create an onion site - a hidden service on the Tor network. Unlike regular websites, onion sites don't appear in search engines and are only accessible through the Tor browser. The server's IP address is hidden, and visitors can reach your site without revealing either party's identity.
// WHY THIS MATTERS
The regular internet is heavily surveilled. Every connection, every request, every site you visit can be logged, tracked, and tied to your identity. An onion site adds layers of encryption and anonymity that make this surveillance extremely difficult. Journalists use onion sites to protect sources. Activists use them to organize safely. Privacy-conscious individuals use them to browse without being tracked.
When you host an onion site, here's what happens:
The magic is that your server never reveals its IP address to visitors. The entire connection path goes through Tor relays, each only knowing the previous and next hop.
⚠️ IMPORTANT: LEGAL NOTICE
Onion sites have legitimate privacy uses. However, they can also be used for illegal activities. This tutorial is for:
Do not use this tutorial for illegal purposes. Know the laws in your jurisdiction.
Prerequisites
For true anonymity, how you acquire and configure your VPS matters. This section covers setting up a VPS that won't be traceable to you.
Before you provision your VPS, consider these OpSec principles:
Connect to your VPS (ideally from a location/network not tied to you):
$ ssh your-user@your-vps-ip
Don't run your onion site as root. Create a dedicated user:
your-user@vps:~$ sudo adduser onion # Create a user named "onion" with a strong password
your-user@vps:~$ sudo usermod -aG docker onion # Add onion user to docker group (if using Docker)
your-user@vps:~$ sudo apt update && sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
your-user@vps:~$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
your-user@vps:~$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
your-user@vps:~$ sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
For an onion site, you don't need to expose any ports to the regular internet. The Tor network handles all connections:
your-user@vps:~$ sudo ufw disable # Disable firewall - Tor handles network access
Why No Firewall?
Your server only needs to connect to the Tor network. The Tor daemon manages all external connections. Traditional firewall rules aren't needed because:
your-user@vps:~$ sudo apt install -y tor
Create the Tor configuration file:
your-user@vps:~$ sudo cat > /etc/tor/torrc << 'EOF' # Hidden Service Configuration # Enable the onion service HiddenServiceDir /var/lib/tor/onion_service/ HiddenServicePort 80 127.0.0.1:8080 # Security settings ExcludeExitNodes {us},{gb},{ca},{au},{nz} StrictNodes 1 # Don't log anything Log notice stdout EOF
Configuration Explained
HiddenServiceDir - Where Tor stores your private key and hostnameHiddenServicePort 80 127.0.0.1:8080 - Forward port 80 (onion) to localhost:8080 (your web server)ExcludeExitNodes - Avoid routing through Five Eyes countries (US, UK, Canada, Australia, New Zealand)StrictNodes 1 - Always respect the excluded nodesLog notice stdout - Minimal loggingyour-user@vps:~$ sudo chown -R debian-tor:debian-tor /var/lib/tor/onion_service/ your-user@vps:~$ sudo chmod 700 /var/lib/tor/onion_service/
your-user@vps:~$ sudo systemctl start tor your-user@vps:~$ sudo systemctl enable tor
your-user@vps:~$ sudo cat /var/lib/tor/onion_service/hostname abcdef1234567890.onion
Save this address! It's your unique onion URL. The private key in that directory is the only proof of identity for your site. Back it up securely.
⚠️ CRITICAL: BACKUP YOUR PRIVATE KEY
The private key in /var/lib/tor/onion_service/ is the only way to prove you own this onion address. If you lose it, your address is gone forever.
Backup steps:
OpSec is the practice of keeping your anonymity intact. Technology alone isn't enough - you must also change your habits.
your-user@vps:~$ sudo cat > /etc/tor/torrc << 'EOF' # Hidden Service Configuration HiddenServiceDir /var/lib/tor/onion_service/ HiddenServicePort 80 127.0.0.1:8080 # Avoid certain countries ExcludeExitNodes {us},{gb},{ca},{au},{nz},{de},{fr} StrictNodes 1 # Reduce information leakage DisableDebugger 1 DisableNetwork 0 # Logging - minimal Log notice stdout EOF
your-user@vps:~$ sudo cat /etc/ssh/sshd_config | grep -E "^(PermitRootLogin|PubkeyAuthentication|PasswordAuthentication)" # Check current settings
your-user@vps:~$ sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config your-user@vps:~$ sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config your-user@vps:~$ sudo systemctl restart sshd
System logs can reveal information about your server. Configure minimal logging:
your-user@vps:~$ sudo systemctl stop rsyslog your-user@vps:~$ sudo systemctl disable rsyslog
your-user@vps:~$ sudo apt remove --purge -y unattended-upgrades update-notifier # Remove auto-update services that connect externally
Follow these rules to maintain anonymity:
The Golden Rule of Onion OpSec
Imagine everything you do will be exposed. Because it might be. Don't do anything online that you wouldn't be comfortable seeing on the front page of a newspaper.
Now let's run your web server. It will only be accessible through Tor.
Create a simple HTML page that will be served over Tor:
your-user@vps:~$ mkdir -p ~/onion-site && cd ~/onion-site your-user@vps:~$ cat > index.html << 'EOF' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Welcome to My Onion Site</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; background: #1a1a1a; color: #e0e0e0; } h1 { border-bottom: 1px solid #333; padding-bottom: 10px; } .info { background: #252525; padding: 15px; border-left: 3px solid #00ff00; } </style> </head> <body> <h1>🧅 Welcome to My Onion Site</h1> <div class="info"> <p><strong>You're accessing this site through Tor.</strong></p> <p>Your IP address was not logged.</p> <p>This server's location is hidden.</p> </div> <p>This is a demonstration of a simple onion site running on a Tor hidden service.</p> </body> </html> EOF
your-user@vps:~$ cat > docker-compose.yml << 'EOF' version: '3.8' services: nginx: image: nginx:alpine container_name: onion-nginx ports: - "127.0.0.1:8080:80" volumes: - ./:/usr/share/nginx/html:ro restart: unless-stopped networks: - onion-net networks: onion-net: driver: bridge EOF
your-user@vps:~$ docker-compose up -d
your-user@vps:~$ curl http://127.0.0.1:8080 # Should return your HTML page
On your local machine (NOT from your home IP if possible), open Tor Browser and visit your onion address:
Visit: http://abcdef1234567890.onion
(Replace with your actual onion address from Step 2.5)
Your site is now live on the Tor network!
To help Tor Browser users discover your onion site, add a meta tag to each HTML page on your regular (clearnet) website. When visitors using Tor Browser load a page, they'll see a purple onion icon in the address bar.
Add this to the <head> section of each HTML file:
<meta http-equiv="onion-location" content="http://your-onion-address.onion/path/to/page.html" />
Each page needs its own meta tag pointing to the corresponding page on your onion site. For example:
content="http://your-onion.onion/"content="http://your-onion.onion/about.html"content="http://your-onion.onion/blog/my-post.html"Why This Matters
The Onion-Location meta tag:
Ensure your nginx doesn't leak information:
your-user@vps:~$ cat > nginx.conf << 'EOF' server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html; # Don't reveal server version server_tokens off; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; # No access logs (Tor handles this) access_log /dev/null; error_log /dev/null; } EOF
For maximum OpSec, run your onion site inside Whonix:
You can run multiple onion sites from the same server:
your-user@vps:~$ sudo cat >> /etc/tor/torrc << 'EOF' # Second onion service HiddenServiceDir /var/lib/tor/onion_service_2/ HiddenServicePort 80 127.0.0.1:8081 EOF
your-user@vps:~$ sudo systemctl restart tor your-user@vps:~$ sudo cat /var/lib/tor/onion_service_2/hostname
You've created an anonymous onion site!
Remember:
Onion sites are one of the most powerful tools for digital privacy. Use them responsibly.
The revolution will not be proprietary.