Skip to content
VPSDen
Networking8 min read903 words

Running a v3 onion service on a VPS

Setting up a v3 onion service properly: configuration, avoiding the leaks that deanonymise services, client authorisation, and vanity addresses.

Short answer

How do I host a website as a Tor onion service?

Install Tor, add a HiddenServiceDir and HiddenServicePort to torrc, and restart — the hostname file then contains your v3 .onion address. What separates a working setup from a safe one is everything around it: bind the web server to localhost only so the service is not simultaneously reachable over clearnet on the same IP, strip identifying headers and error pages, disable server-status and default vhosts, keep the service on a machine that hosts nothing else attributable to you, and consider client authorisation if the service should not be publicly discoverable. The most common deanonymisation is not an attack on Tor — it is a misconfigured web server answering on the public IP with the same fingerprint.

Publishing a v3 onion service takes four lines of configuration. Publishing one that does not immediately give away the machine behind it takes rather more care, and almost every documented deanonymisation of an onion service has come from the second part rather than from any weakness in Tor.

The basic configuration

# /etc/tor/torrc
HiddenServiceDir /var/lib/tor/site/
HiddenServicePort 80 127.0.0.1:8080
HiddenServiceVersion 3
systemctl restart tor
cat /var/lib/tor/site/hostname
# k7qm4x...4xid.onion

The directory contains hs_ed25519_secret_key, hs_ed25519_public_key and hostname. The secret key is your address — the .onion string is a base32 encoding of the public key plus a checksum and version byte. Back it up encrypted, off the machine. If you lose it the address is gone permanently; there is no recovery and no registry to appeal to.

Why v3 rather than the old v2: 56-character addresses derived from Ed25519 keys instead of 16 characters from truncated SHA-1, an improved directory protocol that prevents hostile directory nodes from harvesting a list of every onion address, and offline master key support. v2 was deprecated in 2021 and removed from Tor entirely; it is no longer a choice.

The leaks that actually deanonymise services

The web server answering on the public IP

This is the big one. If nginx listens on 0.0.0.0:80 and serves the same site, anyone who scans the internet for that content — and several organisations scan the entire IPv4 space continuously — can correlate your onion address to your public IP in a single query. Bind to localhost:

server {
    listen 127.0.0.1:8080;
    server_name k7qm4x...4xid.onion;
    server_tokens off;
    # ...
}

And confirm it with ss -tlnp rather than assuming.

Server headers and error pages

server_tokens off removes the version string. Also remove the distribution's default error pages, which are recognisable, and any X-Powered-By or framework-specific headers. Two servers with an identical uncommon header set are trivially correlated.

Status and metrics endpoints

Apache's mod_status, nginx's stub_status, and application health endpoints frequently expose the real hostname, internal IPs, or absolute URLs. Disable them or bind them to a separate loopback port that is not exposed through the onion service.

Absolute URLs and mixed content

An application that generates absolute links to its clearnet domain — in canonical tags, in Open Graph metadata, in a stylesheet reference, in an email template — tells every visitor exactly which site this is. Configure your framework's base URL for the onion address, or use relative URLs throughout.

Time and locale correlation

Content timestamps in a distinctive timezone narrow the operator's location. Set the server to UTC and be aware that publication patterns are themselves an identifier.

Sharing the machine

An onion service on the same host as your personal mail server, a clearnet site with your name on it, or a git remote pointing at your identified account, inherits every one of those associations. If it matters, give the service its own machine.

Client authorisation

By default anyone with your address can reach the service. Client authorisation restricts it to holders of specific keys — the descriptor itself cannot be decrypted without one, so unauthorised clients cannot even confirm the service exists.

# generate a client keypair
openssl genpkey -algorithm x25519 -out /tmp/k.prv.pem
openssl pkey -in /tmp/k.prv.pem -pubout | \
  grep -v " PUBLIC KEY" | base64pem_to_base32   # helper of your choice

# on the server
echo "descriptor:x25519:" \
  > /var/lib/tor/site/authorized_clients/alice.auth

Clients add the corresponding private key to their ClientOnionAuthDir. This is a genuinely strong access control — considerably stronger than an application-level login, because the unauthorised party never reaches the application at all.

Vanity addresses

mkp224o brute-forces Ed25519 keypairs until the encoded address starts with a chosen prefix. Rough costs on a modern multi-core CPU:

Prefix lengthTypical time
4 charactersseconds
6 charactersminutes
8 charactershours
10 charactersmonths to years
12+ charactersimpractical

Each additional character multiplies the search space by 32, so the table above is a rough order of magnitude on a modern multi-core CPU and nothing more — measure on your own hardware before committing to a prefix length. A 5–7 character prefix is the sweet spot: recognisable enough that users can verify the address at a glance, cheap enough to generate. Do the generation on a machine you control, not on a rented server, and never use a "vanity address generation service" — they know your key.

Operational notes

  • Onion services are naturally stateless-friendly and pair well with RAM-only hosting. Keep the key material in an encrypted off-node vault, pull at boot, and the running machine holds nothing that survives a power cut.
  • Use OnionBalance for redundancy. It lets multiple backend instances serve one address, which also removes the single point of failure that a lost key represents.
  • Consider Vanguards. The vanguards add-on mitigates guard discovery attacks against long-running services. It matters more the longer the service stays up at the same address.
  • Do not run a relay on the same machine. It creates correlation opportunities and it is explicitly advised against in the Tor Project's own documentation.
  • Rate-limit at the application layer. Onion services have no client IP to rate-limit on — every request arrives from 127.0.0.1. Use proof-of-work challenges, tokens, or Tor's own onion-service PoW defence, which is now built in and effective against flooding.

Every VPSDEN plan can provision a managed v3 onion endpoint with Vanguards hardening and optional client authorisation for €1/month, and our own panel, API and support desk are reachable over onion.

Cite this page

VPSDEN, “Running a v3 onion service on a VPS”, vpsden.com/kb/tor-onion-service-vps, revised 2026-04-22. Published under CC BY 4.0 — reproduce it freely, with attribution.

Found an error? We amend the article and name the reader who reported it. Tell us.

Offshore VPS from €4.40/month. No KYC, no email, paid in Monero.

Nine jurisdictions, RAM-only options, disks we cannot read, live in about 48 seconds.

No email · No KYC · Pay in Monero · Deployed in under a minute