All systems operational 6 offshore regions No-KYC checkout
Hands-on Field guide

Host a Tor onion service on an offshore VPS

An onion service turns the usual hosting problem inside out: instead of publishing an address and then spending the rest of the guide hiding what sits behind it, you publish nothing at all. The server opens no inbound port, advertises no IP, needs no domain and no certificate — it reaches out to the Tor network, and clients reach the service through a rendezvous that neither side can trace back to a machine. That is a stronger origin-hiding story than any reverse proxy, and it pairs naturally with a box that has no identity attached to it in the first place. This guide sets one up end to end on an offshore VPS: a current Tor, an app bound to localhost, a three-line torrc, and the one file whose loss or leak is the whole game.

Updated 2026-09-08 · 15 min read · Fleet operations
On this page
  1. What an onion service actually is
  2. When it is the right tool — and when it is not
  3. What the setup reveals, and to whom
  4. Install a current Tor, not the one your distro ships
  5. Bind the application to localhost and nothing else
  6. Declare the service, then read your address
  7. Advertise it, run both, and pick a memorable address
  8. Keep it up: performance, monitoring, and key hygiene
  9. Step by step
SP·01

What an onion service actually is

A Tor onion service is a server that is reachable only through the Tor network, at an address that ends in .onion and is derived from a cryptographic key rather than assigned by a registrar. There is no DNS lookup, no public IP in any record, and no TLS certificate to buy: the 56-character address is the service's public key, so the connection is authenticated and end-to-end encrypted by construction. A visitor running Tor Browser types the address; the network arranges an encrypted meeting point; the two halves talk without either learning the other's location. Nobody in the middle — not a relay, not an ISP, not the hosting provider — sees both ends of the conversation at once.

The consequence that matters for hosting is structural, not cosmetic. A normal web server has to listen on a public port, which means its address is discoverable, scannable, and ultimately linkable to whoever pays the bill. An onion service listens on nothing the internet can reach. Tor on the box makes only outbound connections, builds circuits to a handful of introduction points, and waits. The service is online and serving traffic while ss -tlnp shows nothing bound to a routable address. That inversion is the entire reason to run one.

SP·02

When it is the right tool — and when it is not

Reach for an onion service when the location of the machine is part of what you are protecting: a site that must stay reachable even if its clearnet domain is seized, a submission box for sources or researchers, an admin panel you would rather not expose to the scanning internet at all, or a service whose audience already runs Tor and values that you cannot log an IP you never receive. It is also the honest answer when "hide the origin" is the actual requirement — a reverse proxy in front of a clearnet server only moves the target, whereas an onion service removes it.

It is the wrong tool when your visitors will not or cannot run Tor, when you need the raw throughput and sub-100-millisecond latency of a directly reachable server, or when discoverability is the point — an onion address is not something people stumble onto from a search engine. Many operators split the difference and run both: a normal site for reach and an onion service for the users who want it, served from the same application. We cover that pattern below. Nothing here is a substitute for hardening the box itself; if the machine is compromised, its location and contents leak regardless of how it is published, so treat the first-hour hardening checklist as a prerequisite, not an afterthought.

SP·03

What the setup reveals, and to whom

It is worth being precise about the anonymity model, because "onion service" is often assumed to mean "untraceable" and the reality is more specific. Clients never learn the server's IP address — that property is strong and is the whole point. Your hosting provider, however, still sees a machine on their network making a steady stream of encrypted outbound connections to the Tor network; they cannot see the onion address, the content, or the visitors, but they can see that the box speaks Tor. On a mainstream host tied to your identity that is a thread worth pulling. On an offshore, anonymously paid VPS with no name on file, it leads nowhere — which is exactly why the two techniques belong together.

The failure modes that actually deanonymise onion services are almost never Tor itself. They are the application leaking a real IP in an error page, a header, an email it sends, or an outbound request to a clearnet analytics or update endpoint; a misconfigured server revealing its hostname or timezone; or correlation from the operator reusing the same box, key, or writing style across a clearnet identity. The cryptography holds; the plumbing around it is where people get caught. Every step below is written to keep that plumbing tight — bind to localhost, send nothing outbound in the clear, and keep the box's real identity off the machine per keeping your name off a server.

SP·04

Install a current Tor, not the one your distro ships

Distributions freeze Tor at whatever version shipped with the release, and onion-service defenses move fast — the intro-point denial-of-service protection, v3 client authorisation and several stability fixes all landed in versions newer than what a stable Debian or Ubuntu carries by default. Install from the Tor Project's own signed repository so you track current releases and get security updates on their schedule, not the distribution's. The snippet below detects your release codename automatically and pins the repository to the project's signing key, so an attacker who tampers with the mirror cannot feed you a downgraded package.

Tor runs unprivileged as the debian-tor user on Debian and Ubuntu, drops into a sandbox, and needs no special network privileges — it dials out like any client. There is nothing to open in the firewall for the onion service itself, which is the first pleasant surprise of the whole exercise: your default-deny firewall can stay exactly as strict as it was.

SP·05

Bind the application to localhost and nothing else

An onion service is a front door onto a plain local service — a web server, an app, an SSH daemon, anything that speaks TCP. The rule that keeps the whole thing safe is that this local service must listen only on the loopback interface, 127.0.0.1. If it also listens on the public IP, you have quietly recreated the problem the onion service was meant to solve: the content is now reachable and fingerprintable directly, and a scan that matches your clearnet server to your onion content undoes the anonymity in one request. Bind to loopback, confirm it with ss -tlnp, and let Tor be the only thing that ever connects to that port.

Because the traffic between Tor and your app stays on 127.0.0.1, it never touches the network and needs no TLS of its own — the Tor circuit already encrypts everything end to end. Do not put a self-signed certificate on the loopback listener; it adds a fingerprintable surface and buys nothing. Keep the app boring: no clearnet redirects, no absolute https://your-domain links baked into templates, no third-party fonts or analytics that would make the visitor's browser reach off the onion and out to the open web.

SP·06

Declare the service, then read your address

The onion service is three lines of torrc: a directory where Tor keeps the key material, and a mapping from a virtual port on the onion address to the local port your app listens on. On the first restart, Tor generates an Ed25519 keypair in that directory and writes the hostname file — the 56-character .onion address you will hand out. That address is permanent for as long as you keep the key. Lose the key and the address is gone forever; leak it and someone else can impersonate your service. Treat the HiddenServiceDir as the crown jewels: 0700, owned by the Tor user, backed up encrypted and off the box.

Two settings earn their place next to the mapping. HiddenServiceEnableIntroDoSDefense 1 lets your introduction points rate-limit connection floods before they reach your box, which is the closest thing an onion service has to DDoS protection. Pinning HiddenServiceVersion 3 makes the version explicit and future-proof. If the service should be private rather than public, v3 client authorisation restricts it to holders of a key you distribute out of band — a clean way to run an admin panel that simply does not answer to anyone without the credential.

SP·07

If you also run a clearnet site, tell Tor Browser about the onion version with the Onion-Location response header (or the equivalent HTML meta tag). Browsers with onion support then offer visitors the .onion automatically — the standard way sites like major newspapers and search engines surface theirs. Serving the same application on both a domain and an onion address is the norm, not an exotic case: one codebase, one database, two front doors, with the clearnet side sitting behind the usual origin-hiding reverse proxy and the onion side exposing nothing at all.

The default address is a random 56-character string, which is secure but unmemorable. A vanity address lets you brute-force a key whose base32 encoding starts with a chosen prefix — a few readable characters is quick, but each additional character multiplies the work by 32, so anything past seven or eight letters becomes a serious compute job. Generate vanity keys on a trusted local machine, never on the server, and drop the resulting key into the HiddenServiceDir exactly as you would restore a backup. A recognisable prefix also blunts one real attack: phishing clones that count on nobody reading a wall of random characters.

SP·08

Keep it up: performance, monitoring, and key hygiene

An onion connection crosses six relays instead of the usual none, so latency is higher and throughput lower than a directly reachable server — that is physics, not misconfiguration, and no setting removes it. Resist the temptation of single-hop or non-anonymous modes to claw back speed; they trade away the exact property you built this for. What you can do is keep Tor current, leave the intro-point DoS defense on, front a busy service with caching so each request does less work, and size the box for CPU headroom because Tor's cryptography is not free. A modest offshore VPS from $8.00/mo handles a typical onion site comfortably.

Operationally, three habits keep an onion service healthy. Watch journalctl -u tor@default for reachability and descriptor-publishing errors rather than assuming silence means health. Back up the HiddenServiceDir the day you create it and after any change, encrypted and off the machine, because that key is the one thing you cannot regenerate. And keep the box's operational identity clean — a fresh key on a fresh anonymous VPS is worth little if the same operator habits tie it back to a clearnet self. The service will happily run for years untouched; the discipline is in the plumbing around it, not the service itself.

SP·09

Step by step

  1. 01

    Start from a hardened, anonymous box

    Deploy an offshore VPS — online in about 15 min — and do the boring, essential work first: a named sudo user, key-only SSH, a default-deny firewall, and automatic security updates. The onion service adds nothing you have to open in that firewall, so a locked-down box stays locked down. Do not skip this; an onion address in front of a compromised server hides nothing.

    ssh admin@203.0.113.10
    sudo apt update && sudo apt full-upgrade -y
    # firewall stays default-deny; the onion service needs no inbound port
    sudo ufw status verbose
  2. 02

    Install Tor from the Tor Project repository

    Add the project's signed repository so you run a current Tor with the latest onion-service defenses, then install it. The codename is detected from /etc/os-release, and the repository is pinned to Tor's signing key so a tampered mirror cannot downgrade you.

    sudo apt install -y apt-transport-https wget gpg
    . /etc/os-release
    wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc \
      | gpg --dearmor | sudo tee /usr/share/keyrings/tor.gpg >/dev/null
    echo "deb [signed-by=/usr/share/keyrings/tor.gpg] https://deb.torproject.org/torproject.org $VERSION_CODENAME main" \
      | sudo tee /etc/apt/sources.list.d/tor.list
    sudo apt update && sudo apt install -y tor deb.torproject.org-keyring
  3. 03

    Bind your service to localhost only

    Point whatever you are publishing at the loopback interface and nowhere else. Here nginx serves a static site on 127.0.0.1:8080; the same principle applies to any app — bind to 127.0.0.1, not 0.0.0.0. Reload, then prove with ss that nothing is listening on a routable address.

    # /etc/nginx/sites-available/onion.conf
    server {
        listen 127.0.0.1:8080;
        server_name _;
        root /var/www/onion;
        index index.html;
    }

    Enable it, reload, and confirm the bind is loopback-only:

    sudo ln -s /etc/nginx/sites-available/onion.conf /etc/nginx/sites-enabled/
    sudo nginx -t && sudo systemctl reload nginx
    ss -tlnp | grep 8080   # must show 127.0.0.1:8080, never 0.0.0.0:8080
  4. 04

    Declare the onion service in torrc

    Add the service to /etc/tor/torrc: a key directory and a port mapping from the onion's virtual port 80 to your local 8080. Turn on the introduction-point DoS defense and pin the address version. Then restart Tor — on Debian and Ubuntu the running instance is tor@default.

    # /etc/tor/torrc
    HiddenServiceDir /var/lib/tor/onion-www/
    HiddenServicePort 80 127.0.0.1:8080
    HiddenServiceVersion 3
    HiddenServiceEnableIntroDoSDefense 1
    
    sudo systemctl restart tor@default
  5. 05

    Read the address and lock down the key

    Tor has now created the key material and written your address. Read it, hand it out — and make sure the directory is 0700 and owned by the Tor user, which Tor enforces but which a careless restore can break. The hs_ed25519_secret_key file in that directory is your identity; nothing else is.

    sudo cat /var/lib/tor/onion-www/hostname
    # example: 2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion
    
    sudo ls -l /var/lib/tor/onion-www/
    # hostname  hs_ed25519_public_key  hs_ed25519_secret_key
    sudo chown -R debian-tor:debian-tor /var/lib/tor/onion-www
    sudo chmod 700 /var/lib/tor/onion-www
  6. 06

    Test it over Tor, then advertise it

    Verify the service from a machine that has Tor running, using torsocks so the request goes through the network rather than the clearnet. Once it answers, optionally point clearnet visitors at the onion version with an Onion-Location header on your normal site.

    # from any box running tor:
    torsocks curl -sSI http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion/ | head
    
    # advertise the onion from your clearnet nginx (inside the https server block):
    add_header Onion-Location "http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion$request_uri";
  7. 07

    Back up the key and write the runbook

    The address lives and dies with the key directory. Archive it the moment it exists, move the archive off the box to encrypted storage, and note that restoring it anywhere reproduces the exact same .onion address. Then write down the two commands you will actually need in six months — where the key is and how to check health — because the service runs untouched long enough that you will forget.

    sudo tar czf onion-www-key.tar.gz -C /var/lib/tor onion-www
    # copy onion-www-key.tar.gz to encrypted off-box storage, then delete the local copy
    
    # health check any time:
    sudo systemctl status tor@default
    sudo journalctl -u tor@default --since "1 hour ago" | grep -i "onion\|error"
SP·10 — FAQ

Quick answers

Can my hosting provider see my .onion address or what I host?

No to both, with one caveat worth stating plainly. The provider sees a machine making encrypted outbound connections to the Tor network — they cannot derive the onion address from that, cannot see the content, and never see your visitors, because the box only ever dials out and the rendezvous happens inside the network. What they can observe is that the server speaks Tor at all. That is a non-issue on an offshore VPS with no identity attached to it, and a potential thread on a mainstream host tied to your name — which is precisely why anonymous hosting and onion services are stronger together than either is alone.

Do I need a domain name or a TLS certificate?

Neither. The .onion address is derived from the service's own public key, so it needs no registrar and there is nothing to renew or leak. The connection is authenticated and end-to-end encrypted by Tor itself, which is why browsers treat onion origins as secure without a certificate. You can obtain a certificate that lists your onion address if you want the padlock UI, but it is optional and buys no additional transport security — do not put a self-signed cert on the loopback listener thinking it helps.

Onion service or a reverse proxy — which actually hides the origin?

The onion service, and it is not close. A reverse proxy hides your origin IP from casual visitors but the origin is still a listening, scannable server; anyone who finds its address — through a misconfiguration, a leaked DNS record, or an application that phones home — reaches it directly. An onion service has no reachable origin to find: the box listens on nothing routable and only dials out. Use a reverse proxy to hide a clearnet server you still want fast and public; use an onion service when the origin should not exist as a target at all. Many operators run both for the same app.

Why is my onion service slower than a normal site?

Because a connection to it crosses six Tor relays instead of going straight to your server, which adds latency and caps throughput. That is inherent to how the anonymity works, not a fault in your setup, and no configuration removes it. You can soften it: keep Tor current, cache aggressively so each request does less work, keep pages lean, and give the box enough CPU for Tor's cryptography. Avoid single-hop or non-anonymous onion modes — they recover speed by discarding the location privacy you built the service for.

Can I run the same site on both clearnet and .onion?

Yes, and it is the common pattern. One application listens on loopback; your clearnet front end and the onion service both proxy to it, so there is a single codebase and database behind two front doors. Advertise the onion to Tor Browser users with an Onion-Location header on the clearnet side. The one discipline that matters is avoiding leaks that link the two — no hard-coded clearnet URLs, no third-party analytics or fonts, and no error page that prints the server's real hostname or IP.

What happens if I lose the key, and how do vanity addresses work?

Lose the HiddenServiceDir and the address is gone permanently — there is no recovery and no registrar to appeal to, which is why the backup step is not optional. Restoring that directory on any box reproduces the identical .onion. A vanity address is a key brute-forced until its base32 encoding begins with a prefix you choose; a short readable prefix is fast, but each extra character multiplies the search by 32, so long custom strings become real compute jobs. Generate vanity keys on a trusted local machine, then install the key like a restored backup — never generate them on the server.

Put it into practice

VPS online in 15 min, dedicated handed over in 2–12 h. Top up from $30.00 in crypto — no identity attached.

Deploy a VPS