What an onion service actually is
An onion service is a server that never tells anyone where it is. Instead of publishing an address in DNS and waiting for connections, it builds outbound circuits through the Tor network to a handful of relays it picks as introduction points, and publishes a signed descriptor saying "whoever holds this key can be reached through these relays". A client that knows the address fetches that descriptor, picks a third relay as a rendezvous point, and asks an introduction point to pass along a request to meet there. Both sides build their own circuit to the rendezvous point, and neither one ever learns the other's IP address, because neither one is ever told it.
The address itself is the interesting part. A v3 onion address is 56 characters of base32 followed by .onion, and it is not a name that points at a key — it is the key: an ed25519 public key, a checksum and a version byte, encoded. There is nothing to look up and nothing to trust. When your client connects, the descriptor it fetches is signed by that exact key, so the address authenticates the service by construction. No certificate authority is involved, nobody can issue a certificate for your address, and there is no transparency log recording that the service exists. The rendezvous specification is worth a read if you want the full handshake.
| What a normal site publishes | Who can see it | What an onion service publishes instead |
|---|---|---|
| A DNS record mapping name to IP | Anyone, forever, and passive DNS keeps history | Nothing — there is no DNS involved at any point |
| A TLS certificate naming the host | Anyone, via public certificate transparency logs | Nothing — the address is the key, so no CA is needed |
| An IP address that answers on port 443 | Anyone scanning the internet, continuously | Nothing — the service opens outbound circuits and listens on no public port |
| A hosting provider and an ASN | Anyone, from the address | Nothing derivable from the address alone |
| WHOIS or registrar records | Anyone, and registrars answer subpoenas | Nothing — there is no registration and no registrar |
That list is the entire value proposition, and it explains the mix of people running these. SecureDrop instances at newsrooms are onion services because a source should not have to trust DNS. Debian mirrors its archive over onion services so that the act of updating a package is not visible as a destination. Several very large consumer platforms publish one so that people in censored networks can reach them without a blocked IP in the middle. None of that is exotic; it is a transport with a different set of guarantees.
What it protects, and the part it cannot
The protocol guarantee is narrow and strong: the network layer does not reveal where the service runs. An adversary who can watch large parts of the internet still cannot resolve your address to a machine, because there is no resolution step to observe. A hosting provider cannot be handed the address and asked which customer it belongs to, because nothing on the provider's side knows. Scanners cannot find the service, because it does not answer on a public port. And an attack that would flood an ordinary site off the network has nowhere to aim, which is why the pattern shows up in DDoS conversations as often as in privacy ones.
Everything above the network layer is still yours to get wrong, and this is where the actual history lives. Services have been located because the application printed a stack trace containing a real hostname, because the same web server answered on the public IP with an identical page, because a certificate for the operator's other domain was installed on the same machine, because an image carried GPS coordinates in its metadata, because the box sent mail that traversed the open internet, or because a status endpoint left open to the world listed the server's own address. Tor did its job in every one of those cases. The person on top of it did not.
So hold two ideas at once. The transport is sound and has been for years; treating it as the weak link is a misreading of how these investigations have actually gone. And the transport is also the easy half — the hard half is a discipline about everything the machine says and does, which the rest of this guide is mostly about. If the reason you are here is a broader question about how traceable a rented server is, the honest version of that answer is a good companion to this page.
Bringing one up: two directives and a restart
The configuration is genuinely small, which surprises people who expect something ceremonial. Install the tor daemon, then add two directives to torrc: a HiddenServiceDir naming a directory that Tor will create and own, and a HiddenServicePort mapping the virtual port callers will use to the local address your application is listening on. Restart, and Tor generates an ed25519 key pair and writes your address into a hostname file inside that directory.
| Line | What it does | What goes wrong if you skip it |
|---|---|---|
HiddenServiceDir /var/lib/tor/site/ | Where Tor keeps the keys and writes the address; it creates it with mode 0700 | Wrong ownership or a world-readable mode and Tor refuses to start |
HiddenServicePort 80 127.0.0.1:8080 | Callers ask for port 80 on the onion address; Tor forwards to your local listener | Pointing it at a public address re-exposes the service on the open internet |
Application bound to 127.0.0.1 | Only Tor can reach it | The same content answers on the public IP and the whole exercise is pointless |
HiddenServiceVersion 3 | Explicit, though v3 is the only version left | Nothing today — v2 was removed from Tor in 2021 |
The single most common mistake is in the third row. A default web server installation listens on 0.0.0.0, which means the public IPv4 address and usually the IPv6 address too. Add an onion service in front of it and you now serve the same bytes in two places, one of which is indexed by every scanner on the internet. Anyone comparing a page hash, a favicon, an ETag or a distinctive error page links them in seconds. Bind to 127.0.0.1, then confirm it with ss -ltnp rather than assuming — the confirmation takes five seconds and the assumption has cost people everything.
Back up hs_ed25519_secret_key to somewhere encrypted and off the machine before you go any further. That file is not associated with the address; it is the address. Lose it and the address is gone permanently, with no recovery and no appeal. Leak it and somebody else can stand up a service that answers for your address and is cryptographically indistinguishable from you. Treat it like a signing key, which is what it is — and if the disk it lives on is a rented one, encrypting that disk is the obvious companion step, with the caveats that guide sets out.
Then close the front door. An onion service needs no inbound port at all — every connection it uses is one it opened itself, outbound, into the Tor network. You can drop all inbound traffic at the firewall and the service keeps working perfectly. Almost nothing else you can host offers that, and it removes the entire category of attacks that begin with a port scan. Reach your own management access through Tor too, and the machine simply stops answering the internet.
v3 addresses, vanity prefixes, and the phishing problem they create
If a tutorial you are reading mentions 16-character addresses, it is describing a protocol that no longer exists. Version 2 onion services used 80-bit RSA-1024 hashes, which were short enough to be attractive and weak enough to be a problem; they were also enumerable, because anyone running a directory relay could harvest the addresses that passed through it. The Tor Project announced the deprecation timeline in 2020, disabled v2 in the 0.4.6 series in July 2021, and removed the code entirely that October. Version 3 addresses are 56 characters, built on ed25519, and no longer leak through directory relays.
The length is the price of that, and it is why vanity addresses exist. Tools like mkp224o generate key pairs in bulk and keep the ones whose address starts with a chosen prefix. This does not weaken anything: you are not constraining the key, you are discarding candidates until one happens to encode the letters you wanted, and the survivor is exactly as strong as any other. What it costs is time, and the cost is exponential — each additional character multiplies the work by 32, so a four-character prefix is instant on a laptop, six or seven characters is a machine running for hours, and ten becomes a serious undertaking. Nobody brute-forces a full 56-character address; the search space is the entire point.
The real hazard is the mirror image of the feature. If a recognisable prefix helps your users identify you, it also helps somebody else generate a near-miss and put it on a phishing page, because the eight characters a human actually reads are the only part they check. Defend it the way key fingerprints have always been defended: publish the full address in several independent places, sign it with a key people already have, put it in the Onion-Location header of your clearnet site if you have one, and say out loud that you will never announce a new address only on social media. A vanity prefix is a usability feature, not an authentication one.
The leak surface that has actually unmasked services
This is the section that matters. The pattern in every publicly documented case is the same: the network layer held, and something above it pointed at a specific machine, a specific person, or a specific other property. Most of these are boring, all of them are checkable in an afternoon, and the checking is the work.
| The leak | How somebody finds it | The fix |
|---|---|---|
| The same application answering on the public IP | Fetch both, compare page hash, favicon, ETag or a distinctive error page | Bind to 127.0.0.1 only; verify with ss -ltnp |
| A default virtual host or a TLS certificate on the public address | Internet-wide scan data, searchable and archived by date | No listener on the public interface at all; a firewall that drops inbound |
| Server banners and framework error pages | Read the response headers and trigger a 500 on purpose | Suppress version banners, replace debug error pages with static ones |
| Absolute URLs baked into templates | Read the HTML: one hard-coded clearnet host is enough | Relative URLs everywhere, or a host-aware base URL |
| Third-party requests: analytics, fonts, avatars, CDNs | Load the page and watch what it tries to fetch | Self-host every asset; there is no acceptable third-party call here |
| Image metadata | Read the EXIF block: camera serial numbers and GPS coordinates | Strip metadata on upload, server-side, without exception |
| Status endpoints left open | Request /server-status and read the server's own view of itself | Disable them, or bind them to the loopback interface |
| Outbound traffic that identifies the host | Mail leaving the box, a monitoring agent phoning home, a cron job with an API key | Audit outbound, route what must leave through Tor, and send no mail at all |
| An SSH host key reused from another machine | Scan data keyed by host-key fingerprint links the two instantly | Fresh keys per instance; reach SSH through the onion service itself |
| Timestamps and locale | Log timestamps, generated documents, and an obvious working day | Run in UTC; do not let the application render a local timezone |
Two of those deserve emphasis because they catch careful people. The first is outbound traffic: a machine that never accepts a connection can still announce itself by making one. Package updates are fine and unavoidable; a monitoring agent that reports to a dashboard tied to your name is not, and neither is an application that sends password-reset mail through the open internet from a box whose whole purpose is not to be located. The second is the SSH host key. Reusing one across machines is a habit that feels tidy and creates a permanent, searchable, cryptographic link between two servers that were supposed to be unrelated.
Do the audit as an outsider, not as the operator. Open the service in Tor Browser on a machine that has never touched the project, read every response header, trigger a deliberate error, view the source of a page you did not write yourself, and watch the network panel for anything the page fetches from somewhere else. Then sit on the server and watch what leaves it for a full day. What you find in that day is the guide's whole point.
Client authorisation: a service only some people can reach
There is a mode most people do not know exists, and it is the neatest thing in the protocol. With client authorisation, the descriptor your service publishes is encrypted to a set of x25519 public keys you nominate. A client without the matching private key cannot even decrypt the descriptor, which means it cannot learn the introduction points, which means it cannot connect — and cannot confirm that anything is there at all. You drop the client public keys into an authorized_clients directory beside the service keys, one file per client, and restart.
Compare that with the usual ways of restricting access. An IP allowlist requires knowing where your users are and leaves a service answering the internet for everyone else to scan and fingerprint. HTTP basic auth leaves a login prompt sitting there advertising that something exists. A VPN adds a whole second system to run, with its own address to expose. Client authorisation removes the service from view for everyone who is not on the list, which is a categorically different property: not a locked door but an absence of one.
The natural fit is administrative surfaces. Put the public site on an ordinary onion service and the admin panel, the metrics dashboard, the database console and the SSH entry point behind separate authorised ones, and the parts of your deployment that would otherwise be probed continuously simply cannot be found. The cost is key distribution — every client needs its private key installed in its Tor configuration — which is fine for a handful of operators and impractical for a public audience. Use it where the audience is countable.
Latency, redundancy, and the honest trade-offs
An onion connection crosses six relays: three that the client chose and three that the service chose, meeting in the middle. That is the price of neither end knowing the other, and it shows up as latency rather than bandwidth — first byte is slow, throughput afterwards is usually fine. Design around it: fewer round trips, aggressive caching, no chatty request chains, no page that needs eleven sub-resources before it renders. A site that is pleasant over an onion service is usually a site that was well built to begin with.
If your service does not itself need location anonymity — a large public platform publishing an onion address purely so censored users can reach it, for instance — Tor offers a single onion service mode that uses a one-hop path on the service side. It roughly halves the latency and explicitly gives up the service's own anonymity, and the name of the configuration directive says so in as many words. It is the right answer for a known organisation and exactly the wrong answer for anyone whose location is the thing being protected. Choose it deliberately or not at all.
| Concern | Option | What it costs | When it is right |
|---|---|---|---|
| Latency | Standard six-hop service | Slow first byte, fine throughput | Always, unless anonymity of the service is genuinely not needed |
| Latency | Single onion service (one hop on the service side) | The service's own location anonymity, entirely | A named organisation publishing an address for censored users |
| Redundancy | OnionBalance across several backends | A management daemon and key handling on each backend | Anything that must stay up while a backend is rebuilt |
| Discovery from your clearnet site | Onion-Location header | Publicly links the two, deliberately | When the two being linked is fine and you want the traffic |
| Restricted audience | Client authorisation | Key distribution to every client | Admin panels, internal tools, a countable audience |
Redundancy deserves a note because the naive approach fails. You cannot simply copy the key material onto a second machine and run both — two services publishing descriptors for the same address fight over the directory and clients land unpredictably. OnionBalance exists for exactly this: a front-end instance holds the public address and publishes a descriptor pointing at the introduction points of several backend services, each with its own key. Backends can be rebuilt or moved one at a time without the address ever changing.
Running one alongside an ordinary site
Plenty of onion services are second front doors on something that already exists in public, and that is a different project from a service whose location is secret. Decide which one you are building before you write any configuration, because the two want opposite things. If the point is censorship resistance for a site everybody already knows you run, linking the two is the feature: publish an Onion-Location header on the clearnet site and Tor Browser will offer the onion address to visitors automatically. If the point is that nobody knows where the service runs, then every link between the two is a leak, and the correct number of them is zero.
The half-measure is what hurts people. Running both from one machine, with one database, one session cookie domain and one set of uploaded files, while telling yourself the two audiences are separate, means a single misconfiguration collapses the distinction — and you will not find out until somebody else does. If both must exist and must not be linked, they are two deployments on two machines with two sets of credentials, and the operational cost of that is the price of the property you wanted.
One practical detail if you do link them: keep sessions and cookies scoped per host. A user who logs in on the clearnet site and then arrives over the onion address should be a fresh session, not a shared one, or you have built a mechanism that correlates the two visits for anyone who can see either. And serve the onion address its own canonical links, so the site does not helpfully redirect a Tor Browser user back out to the clearnet host that they deliberately avoided.
What the hosting side actually has to get right
The requirements are unusual, which is why a generic host is often a bad fit. You need an unimpeded outbound path into the Tor network, because that is the only kind of connection your service makes; some providers filter Tor directory and relay traffic outright, and you will discover this as a service that never publishes a descriptor. You need a provider whose acceptable use policy addresses Tor in writing rather than by silence, because silence is what turns into a termination email the first time somebody complains about something unrelated. You do not need a stable IP, a domain, a certificate, or any inbound port — which means most of what hosting companies sell as differentiators are irrelevant here.
The abuse profile is the pleasant surprise. An exit node makes connections to the open internet on behalf of strangers and therefore collects complaints; that is the deal, and it is why exits need a provider with a documented posture. An onion service does the opposite: every connection is inbound from the Tor network, it never contacts the open internet on anyone's behalf, and consequently it generates essentially no abuse mail at all. It is a quieter workload to host than the relay next to it, and much quieter than a public web server.
On BitVPS, Tor is permitted in writing — relays, bridges, exits and onion services alike, with the exit case documented on the abuse page rather than left to chance. The Tor hosting page covers relay sizing; onion services are lighter. Practically, a Growth at $13.50 with 4 vCPU, 8 GB of RAM and an unmetered uplink runs a serious onion service with room for the application behind it, and a Starter at $8.50 is enough for a small one. Pick the location for its legal posture rather than its latency: six hops make the difference between a nearby and a distant datacentre almost invisible.
The network page publishes the ASN and the peering, which matters here for an indirect reason. You are not exposing an address, so the usual reason to care about a provider's network is gone — but a host that documents its infrastructure publicly is also a host that has written down what it does when someone asks about a customer, and that is the thing you are actually buying.
Where the line is
It is worth being direct about this, because the technology carries a reputation that does not match the traffic. Onion services are a transport with a specific privacy property, and the people running them are overwhelmingly ordinary: newsrooms taking tips, a package archive that does not want to log which machine fetched which update, messaging and self-hosting projects, people in countries where the ordinary internet is filtered, and administrators who would simply rather their management interface not be scannable. Running one is lawful in the great majority of jurisdictions, and it is not a statement about what you are hosting.
What it is not is a change in what the rules are. A provider that ignores copyright notices — and we do, as that guide explains — still acts on child sexual abuse material and credible threats to people, and acts on them fast: our published window is four hours for those, against forty-eight for everything else. That is not a loophole in an otherwise permissive policy, it is the policy, and no transport changes it. The acceptable use policy is short and worth reading before you build rather than after.
The other honest note is that anonymity is a system property, not a product you can buy. The address hides the machine; it does not hide a payment trail, a reused password, a writing style, a domain you registered years ago with the same email, or a screenshot with your own filesystem paths in it. If the threat model is serious, the transport is the easiest part of it and the part you will spend the least time on. The broader walkthrough covers the rest of that chain, and the bulletproof-hosting explainer is a useful antidote to the marketing that surrounds this whole subject.