Table of Contents
Short version: Install tor, add a HiddenServiceDir + HiddenServicePort block to /etc/tor/torrc, restart tor, and read your new v3 .onion address from hostname. Harden the origin by binding Apache/nginx to 127.0.0.1, stripping logs, and removing version headers. Takes about 45 minutes.
Key Takeaways
- A Tor onion service hides the server's location, not just the visitor's. Both ends are anonymous.
- v3 onion addresses are 56 characters and use ed25519 keys — v2 is deprecated and should not be used.
- The hardest part isn't configuring tor — it's making sure your web server doesn't leak identifying info.
- Bind your web server to 127.0.0.1 only. If it's also reachable on public IP, correlation attacks become trivial.
- The Tor Project documentation is the canonical reference — read it.
- Adding an
Onion-Locationheader to your clearnet site lets Tor Browser auto-promote the .onion.
What an Onion Service Is (and Isn't)
An onion service (formerly "hidden service") lets you run a website reachable only through the Tor network. Visitors reach you via a .onion address that doesn't require DNS, doesn't require a TLS certificate from a public CA, and doesn't reveal the server's IP address.
What it is:
- End-to-end encrypted by Tor's circuit crypto (no need for Let's Encrypt)
- Location-hidden on the server side — ISPs and adversaries can't traceroute to your server
- Authenticated by the onion address itself (the hostname IS the public key)
What it isn't:
- A magic cloak for sloppy opsec — a server that also runs on a public IP isn't hidden
- Immune to traffic-analysis attacks if you have a powerful adversary
- A replacement for good application security — SQL injection still works on .onion sites
Step 1: Install the tor Daemon
On Debian/Ubuntu, the distro package is usually too old. Use the official Tor Project apt repo:
# Add Tor Project signing key and repo, then:
sudo apt update
sudo apt install tor deb.torproject.org-keyring
On RHEL/Alma/Rocky:
sudo dnf install epel-release
sudo dnf install tor
Verify:
tor --version
# Tor 0.4.8.x (or newer)
Step 2: Configure the Hidden Service
Edit /etc/tor/torrc and add:
HiddenServiceDir /var/lib/tor/mysite/
HiddenServicePort 80 127.0.0.1:8080
HiddenServiceVersion 3
Meaning:
- HiddenServiceDir — where tor stores keys + the hostname file. Must be owned by the
debian-tor(or equivalent) user, mode 0700. - HiddenServicePort 80 127.0.0.1:8080 — visitors reach the .onion on port 80; tor forwards to your local web server on 127.0.0.1:8080.
- HiddenServiceVersion 3 — use v3. v2 is deprecated and removed from current tor.
Don't bind your web server on 0.0.0.0:8080 — only 127.0.0.1:8080. We'll reinforce why in Step 4.
Tired of slow, overcrowded shared hosting?
LaunchPad Host runs on NVMe SSDs + LiteSpeed with free migration, free SSL, daily backups, and crypto payments. 30-day money-back guarantee.
See Hosting PlansStep 3: Start tor and Read Your Onion Address
sudo systemctl restart tor
sudo cat /var/lib/tor/mysite/hostname
# somethingsomething56chars.onion
That's your address. It's derived from the ed25519 keypair in the same directory (hs_ed25519_secret_key). Back up that keypair — if you lose it, you lose the address forever.
Test with Tor Browser or torsocks curl http://yourfulladdress.onion/.
Step 4: Harden the Origin
This is where most deployments leak. Rules:
- Bind to 127.0.0.1 only. In nginx:
listen 127.0.0.1:8080;. In Apache:Listen 127.0.0.1:8080. If the site is also reachable on your public IP, an attacker can compare response fingerprints and de-anonymize you. - Strip server version headers. nginx:
server_tokens off;. Apache:ServerTokens Prod+ServerSignature Off. - Kill access logs that store IPs. Over Tor, the visible client IP is always 127.0.0.1 anyway — but don't log
X-Forwarded-Forheaders if anything upstream might set them. - Disable ETags and default error pages that could reveal inode numbers or OS specifics.
- Don't run anything else on the same IP that's reachable on clearnet. Mail server, SSH, another website — each is a correlation vector.
- Firewall outbound if possible. A compromised web app that phones home over clearnet will leak your real IP.
For high-threat-model deployments, run the onion service on a dedicated VM with no public IP at all — only the tor daemon reaches the outside world.
Step 5: Add Onion-Location (Optional)
If you also run the site on a regular clearnet domain, add this header:
Onion-Location: http://yourfulladdress.onion$request_uri
Tor Browser sees this and prompts visitors to switch to the onion version. This is the modern standard — The New York Times, BBC, ProPublica, and many others use it.
nginx snippet:
add_header Onion-Location http://yourfulladdress.onion$request_uri always;
Operational Notes
A few things that will save you pain later:
- Back up the keys.
/var/lib/tor/mysite/— encrypted backup, offsite. The .onion address is derived from those keys. - Monitor reachability. Onion services can drop off the network during DoS attacks on the Tor network itself. Use an external monitor (another tor client) to alert on downtime.
- Rate-limit at the application layer. You can't fail2ban by IP — all visitors look like 127.0.0.1. Use CAPTCHA, proof-of-work (Tor's built-in PoW), or application-layer tokens.
- Onion v3 PoW defense. Tor 0.4.8+ supports adaptive proof-of-work to mitigate denial-of-service. Enable it:
HiddenServicePoWDefensesEnabled 1. - Don't index the .onion in search engines. Robots.txt it. The whole point is that only people who have the address can reach it.
Want us to host it for you? Our VPS plans allow onion services by default, and we'll help with the hardening review.
Frequently Asked Questions
No — any Linux VPS where you can install tor will work. Shared hosting usually can't because you can't install daemons. We allow it on our VPS plans; some hosts prohibit it in their AUP, so check first.
In most jurisdictions, yes. Running the service is not the same as running a Tor exit relay (which has a different legal profile). What you publish on the onion service is subject to normal content law.
Use <a href="https://github.com/cathugger/mkp224o" target="_blank" rel="noopener">mkp224o</a> to brute-force ed25519 keypairs until the address starts with your chosen prefix. 6–8 character prefixes are feasible on a laptop; longer needs a GPU.
No — the onion protocol already provides end-to-end encryption and authentication by the address itself. Some sites add TLS anyway for defense-in-depth and to support legacy clients, using DigiCert's .onion EV certificates. For most sites, plain HTTP over onion is fine.
No. The Tor protocol is designed so neither end knows the other's IP. A bug in your application could leak through (e.g., loading a resource from a clearnet domain), but the transport itself doesn't.
Slower than clearnet — typically 200–600ms added latency from Tor's 6-hop circuit (3 hops each side). For text content it's fine; for video streaming it's rough. Keep assets small and cacheable.
Yes, but be careful with plugins that make external requests or assume a specific hostname. Hard-code <code>WP_HOME</code> and <code>WP_SITEURL</code> to the .onion address, disable auto-updates (they'll fail without clearnet), and review plugins for anything that phones home.
Ready for hosting that just works?
NVMe + LiteSpeed hosting with free migration, crypto payments accepted, and a 30-day money-back guarantee.
See Hosting PlansRelated tools, articles & authoritative sources
Hand-picked internal pages and external references from sources Google itself considers authoritative on this topic.
Related free tools
- WHOIS Lookup Registrar, creation date, expiry, nameservers, DNSSEC status — for any domain.
- DNS Lookup & Records Checker All DNS records (A, AAAA, MX, NS, TXT, CAA, SPF, DMARC) for any domain.
Offshore & privacy hosting
- Anonymous-Friendly Hosting Email-only signup, crypto checkout, free WHOIS privacy
- Offshore Hosting EU jurisdiction, privacy-first, from $3.99/mo
- Crypto Hosting BTC, Lightning, Monero via self-hosted BTCPay