Run a Tor exit node: an operator's guide
We run Tor exit relays, so here is the real job: picking an exit-friendly host, exit policy, ContactInfo, reverse DNS, and answering abuse mail.
What a Tor exit node does, and who it makes you
A Tor exit node is the last relay in a circuit: the machine that opens the connection to the destination, so the destination logs your server's address and never the user's. Every other decision in this guide follows from that one fact. The address is treated as the source of everything that passes through it, so it has to be an address that does nothing else, at a provider that has agreed to carry this traffic.
Running an exit is the opposite of hiding. The relay is listed in a public directory that anyone can download. Your contact address sits in that directory under ContactInfo, your reverse DNS (domain name system) name announces what the box is, port 80 serves a page saying the same thing, and you answer the abuse mail yourself, under your own name. Nobody in this system is more identifiable than an exit operator. That is the job, and that is why the job works.
We run these. SSD Nodes operates exit relays in several countries as its contribution to free expression. We rent those machines from providers that have deliberately signed up for exit traffic, and we are not the provider for them. That is on purpose, and the next section explains why.
Where an exit belongs, and where it does not
An exit does not belong on a general-purpose VPS (virtual private server), and that includes ours. A general-purpose network carries websites, mail, backups and control panels for thousands of unrelated customers on neighbouring addresses. Exit traffic puts one of those addresses into scanning reports and spam blocklists, and the effects land on the neighbours. Providers that host exits well have built for it: address space set aside for the purpose, and an abuse desk that already knows what Tor is.
So a host writing this guide is telling you to buy the machine somewhere else. That is the useful part. We know what exit traffic does to an address because we pay other people to carry ours, and we pay them because carrying it properly is a different business from selling general-purpose servers.
The Tor Project says the same thing in blunter terms. Its types of relays page states that exit relays "have the greatest legal exposure and liability of all the relays" and that "you should not run a Tor exit relay from your home". A general-purpose VPS holding your own projects is closer to home than it looks. It is a machine you care about, on an address you want to keep clean.
If you have an ordinary VPS and you want to help the network this week, run a non-exit relay or a bridge on it. That is not a consolation prize. It is a different job with a different risk profile, and the network needs both. A non-exit relay never opens a connection to a destination, so it draws almost no complaints, and Tor's guidance asks for at least 2 MByte/s (megabytes per second) in each direction before it is worth listing. A bridge is an unlisted entry point for users in censored networks. It needs 24/7 connectivity and one open TCP (transmission control protocol) port, which makes it the highest-value thing a small box can do. Both of those belong on hardware you already have. An exit does not.
How do you find an exit-friendly provider?
Ask before you order, in writing, and keep the reply. Tor's exit guidelines suggest asking in two steps: first whether the provider is fine with a Tor exit at all, then whether they will assign a dedicated address or range for it. Asking for both at once tends to produce a reflexive no.
Four questions tell you whether a provider is really set up for this.
- Will you assign a dedicated IP address that hosts nothing else, and will you set the reverse DNS record I ask for?
- Who receives the abuse mail, and will you forward it to me unedited, with the reporter's address intact so I can reply to them directly?
- What happens on the first complaint: do you forward it to me, or do you null-route the address first and ask later?
- How many exits already sit on this network? Tor's guidelines are direct about this: "it does not help if we pool too many exits at one friendly ISP".
That last question matters more than it looks. Part of an exit's value comes from where it sits in the network. Another exit in a network that already holds fifty of them adds less than the same machine somewhere new. Relay Search shows which networks already carry exits, so you can check before you commit.
Get the answers before you pay, and buy the machine on its own account rather than adding it to the account that holds your other servers. How safe VPS hosting is depends mostly on what you place next to what, and this is the clearest example of that rule there is.
One address, one job
The exit's address must host nothing else. No website, no mail, no VPN, no monitoring dashboard, no personal SSH (secure shell) jump host. The address will land on blocklists, and anything else living there starts failing in ways that are hard to debug. A single-purpose address also keeps your answer to complaints short: this address is an exit relay, it is nothing else.
Before tor goes on, do the ordinary work. Key-only SSH with password login disabled, and a firewall that allows only the ports you are publishing. Hardening SSH on a VPS covers the first part and ufw firewall basics covers the second. An exit publishes exactly two ports to the world: the ORPort that carries Tor traffic, and port 80 for the exit notice page. Everything else stays closed.
Turn on unattended upgrades, because an exit left on an old tor build is a problem for every user routed through it.
sudo apt update && sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgradesDo not add logging. Capturing the plaintext that leaves an exit is technically easy and it is the one thing an operator must never do. The EFF Tor legal FAQ tells operators not to, because wiretap law in the United States and comparable law elsewhere can create liability for examining that traffic. Keep tor's default notice-level logging and nothing more.
Install tor from the Tor Project repository
Distribution packages lag. Use the Tor Project's own repository so security fixes arrive on the day they ship. As of August 2026 the current stable series is 0.4.9.
sudo apt update
sudo apt install -y apt-transport-https gnupg wget
lsb_release -csWrite /etc/apt/sources.list.d/tor.sources, replacing noble with the codename that lsb_release -cs printed:
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: noble
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpgAdd the signing key, then install:
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/null
sudo apt update
sudo apt install -y tor deb.torproject.org-keyring
tor --versionThe deb.torproject.org-keyring package keeps that key current on its own, so the repository does not break the day the key rolls over. If apt update reports the same repository configured twice, you have both a .list file and a .sources file naming it, and the deb822 duplicate source error explains how to clear that.
DNS: your exit resolves names for everyone using it
An exit performs the name lookups for every circuit leaving through it, so its resolver sees a stream of names belonging to other people. Point that at a large public resolver and you hand the whole stream to one company, which is the centralisation Tor asks exit operators to avoid. Run a validating, caching resolver on the box instead.
sudo apt install -y unbound bind9-dnsutils
sudo cp /etc/resolv.conf /etc/resolv.conf.backup
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
sudo chattr +i /etc/resolv.conf
sudo systemctl enable --now unboundchattr +i marks the file immutable, because DHCP (dynamic host configuration protocol) clients and resolvconf rewrite /etc/resolv.conf on their own schedule. Without it a reboot can move your lookups back to the provider's resolver, and nothing warns you when it happens. Tor's Debian and Ubuntu instructions also enable query name minimisation, which sends each name server only the part of a name it actually needs:
server:
qname-minimisation: yesPut that in a file under /etc/unbound/unbound.conf.d/, then confirm the resolver answers:
sudo systemctl restart unbound
dig +short example.com @127.0.0.1An address in the reply means unbound is working. If unbound fails to start with address already in use, another process holds port 53: run sudo ss -lntup | grep :53 and look at what owns it. On Ubuntu, systemd-resolved listens on 127.0.0.53, so it does not collide with unbound on 127.0.0.1.
The torrc for an exit relay
The Debian package reads /etc/tor/torrc. This is the whole exit-relevant configuration.
Nickname exampleExit01
ORPort 443
ExitRelay 1
SocksPort 0
ContactInfo email:tor[]example.org abuse:abuse[]example.org url:https://example.org ciissversion:3
ReducedExitPolicy 1
Log notice syslogEvery line there is load-bearing, so take them one at a time.
ORPort 443 is where other relays connect to you. Port 443 gets through restrictive networks that block unusual ports, so your relay is reachable by more people than it would be on the traditional 9001. You can only claim 443 because nothing else on this box wants it, which is one more argument for the dedicated address.
SocksPort 0 turns off the local SOCKS proxy. A relay never needs it, and a SOCKS port listening on a public address is an open proxy that will be found and abused within hours.
ExitRelay 1 is the switch that makes this an exit. Set it explicitly instead of relying on a default, so the config file states plainly what the machine does.
ContactInfo is published in the public directory for anyone to read. Write it in the ContactInfo Information Sharing Specification format, which is what the network's tooling parses, and keep ciissversion:3 in it. The [] in place of @ is the convention that specification uses to slow down address scrapers. Use a mailbox you read every day, because this is where abuse mail arrives.
If the box has working IPv6, add an IPv6 ORPort and enable IPv6 exiting. Leave both out if it does not, because a relay advertising an address it cannot actually use fails its own reachability test.
ORPort [2001:db8::1]:443
IPv6Exit 1Exit policy: what each port admits
The exit policy is the list of destinations your relay is willing to connect to. Tor reads it from top to bottom and the first matching rule wins. ReducedExitPolicy 1 selects a curated list of roughly seventy ports covering web, mail submission, chat and git, and it leaves out the ports that generate most complaints. It is the right starting point for a first exit.
Two rules are worth knowing by name. ExitPolicyRejectPrivate is on by default and stops the exit from connecting to private address ranges and to the relay's own addresses, which is what keeps your exit from being pointed at your provider's internal network. Port 25 (SMTP, simple mail transfer protocol) is rejected and should stay rejected, because allowing it turns the relay into a spam source and the address is blocklisted within days.
An exit has to allow ports 80 and 443 to be useful at all. Tor's exit relay documentation states that minimum directly. If your provider wants something tighter than the reduced policy, a web-only exit is still a real contribution:
ExitPolicy accept *:80
ExitPolicy accept *:443
ExitPolicy reject *:*End the list with reject *:* so your policy is complete on its own and nothing further is inherited. The reduced policy does allow port 22 (SSH), which is the usual source of brute-force reports, so add ExitPolicy reject *:22 above the rest if you would rather not field that category of mail. The file-sharing ports in the 6881-6999 range are the usual source of copyright notices, and the reduced policy already excludes them.
A policy change only reaches clients after your relay publishes a new descriptor and the directory propagates it, so give it a few hours before judging the effect.
ContactInfo, family keys, and registering the relay
Registering an exit means tying it to a name a stranger can verify. Two mechanisms do that, and they work together.
The first is a well-known file. Publish your family identity on a domain you control, then name that proof in ContactInfo:
ContactInfo email:tor[]example.org url:https://example.org proof:uri-familyid-ed25519 ciissversion:3The file lives at https://example.org/.well-known/tor-relay/ed25519-family-id.txt and contains your family ID. Anyone can now confirm that whoever claims these relays also controls that domain. That is the difference between a contact address and a verified one.
The second is the family itself. If you run more than one relay, the network needs to know they share an operator, so a client never builds a circuit through two of your machines. Current tor does this with a family key, called Happy Families, on relays running 0.4.9.2-alpha or later:
tor --keygen-family exampleFamilyThat writes exampleFamily.secret_family_key and prints a FamilyId line. Copy the secret key file into each relay's key directory (/var/lib/tor/keys on Debian and Ubuntu), keep the .secret_family_key ending on the filename, add the printed FamilyId line to each torrc, and reload tor. Tor's documentation is explicit that you must still set the legacy MyFamily option listing every relay fingerprint until the project announces that it is no longer needed, so configure both. Each relay's fingerprint is in /var/lib/tor/fingerprint.
The second and third machine is where operations start to matter, and managing several Linux servers at once is the same problem here as anywhere else. Back up /var/lib/tor/keys somewhere off the box. Lose it and the relay returns as a stranger, earning every flag and all of its reputation again from zero.
Subscribe to the tor-relays mailing list too. Changes that affect operators are announced there first.
Reverse DNS and the exit notice on port 80
Set the reverse DNS record before the relay carries any traffic. Tor's exit guidelines say to make it signal what the box is, along the lines of tor-exit-01.example.org. The reason is practical. When an unfamiliar address turns up in someone's logs, the first thing their admin runs is a reverse lookup. A name containing "tor-exit" answers the question before anyone writes to you, which turns a share of would-be complaints into no complaint at all. Ask the provider to set the PTR (pointer) record, and add a matching forward record on your side.
Then serve a notice page on port 80 that says the same thing in words. Older guides do this with tor's DirPortFrontPage setting, which depends on a DirPort. DirPort has been deprecated for relays since tor 0.4.6.5, so use a small web server instead.
sudo apt install -y nginx
sudo install -d -m 755 /srv/tor-exit-noticeWrite /srv/tor-exit-notice/index.html:
<!DOCTYPE html>
<html>
<head><title>This is a Tor exit relay</title></head>
<body>
<h1>This is a Tor exit relay</h1>
<p>Traffic from this address was sent by a user of the Tor network. It did not
come from the operator of this machine, and this machine keeps no record of
who sent it.</p>
<p>Operator: Example Org. Abuse reports: abuse@example.org. Every report gets a
reply from a person.</p>
<p>To check whether this address was a Tor exit at a given date and time:
https://metrics.torproject.org/exonerator.html</p>
</body>
</html>Write this server block to /etc/nginx/sites-available/tor-exit-notice:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /srv/tor-exit-notice;
index index.html;
access_log off;
}Enable it, drop nginx's default site, and check the result:
sudo ln -sf /etc/nginx/sites-available/tor-exit-notice /etc/nginx/sites-enabled/tor-exit-notice
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
curl -s http://127.0.0.1/ | head -n 5nginx -t reporting syntax is ok and test is successful means the file parses. The curl should print the first lines of your notice. If it prints nginx's welcome page instead, the default site is still enabled and your block is not being used.
Start it, and read what the log says
sudo systemctl restart tor@default
sudo journalctl -u tor@default -n 50 --no-pagerWithin a few minutes the log should carry the line that means other relays can reach you:
Self-testing indicates your ORPort is reachable from the outside. Excellent.If that line never appears, the ORPort is not reachable. Confirm tor is listening with sudo ss -lntp | grep 443, then test the port from another machine with nc -vz your.address.here 443. A firewall in front of the VPS, either yours or one in the provider's control panel, is the usual cause.
Check that the service returns after a reboot with systemctl is-enabled tor, which should print enabled.
The relay shows up on Relay Search about three hours after it starts, under the nickname you chose. Traffic then climbs over several days, because the network's bandwidth measurement has to observe your relay before clients give it much weight. A new exit carrying almost nothing on day one is normal.
The abuse playbook, and what the mail looks like
Write the playbook before the first complaint, because the first one usually arrives in the first week. Most of this mail is machine-generated. Tor's exit guidelines put automated reports at roughly 80% of the total, and a standard reply settles most of what remains.
Here is what actually arrives. A scanning or brute-force report produced by someone's intrusion detection system, quoting your address and a timestamp. A copyright notice, if your policy allows file-sharing ports. A forum or comment spam complaint from a site owner. Occasionally a preservation request or a subpoena from law enforcement, which is a different category and the point at which you talk to a lawyer rather than reaching for a template.
The reply is short, and it is nearly the same every time:
Hello,
Thank you for the report. The address 203.0.113.10 is a Tor exit relay,
operated by <your name> at <your organisation>. The connection you saw was
made by a user of the Tor network. It did not originate on this machine.
This relay keeps no record of which user made which connection, so I cannot
identify the sender and there are no logs for me to hand over.
You can confirm that this address was a Tor exit at the date and time in
question here: https://metrics.torproject.org/exonerator.html
If you would prefer to stop Tor traffic reaching your service, the current
list of exit addresses is published here:
https://check.torproject.org/torbulkexitlist
I read this mailbox personally and will answer any follow-up.
<your name>Four habits make that work. Reply within one working day, from the address in ContactInfo, signed with your own name. Never offer to identify a user, because you cannot, and an operator who implies otherwise has to break that promise later. Keep every reply in one folder, so a second mail about the same incident gets the same answer. If the provider forwards a complaint with a suspension warning attached, answer the provider first and the reporter second.
Two links carry most of the weight in those replies. ExoneraTor answers the question an investigator actually has: was this address a Tor exit at this moment. The bulk exit list is a plain list of current exit addresses, one per line, for anyone who has decided to block Tor and would rather do it accurately than guess.
Bandwidth, cost, and the second relay
Exits move real traffic. Decide the monthly ceiling before you order, and ask how the provider bills once the allowance is used, because what a VPS actually costs is mostly a question about the transfer allowance rather than the sticker price. Tor can enforce your side of that:
AccountingMax 4 TBytes
AccountingStart month 1 00:00
RelayBandwidthRate 20 MBytes
RelayBandwidthBurst 25 MBytesAccountingMax makes tor hibernate once it has moved that volume in the accounting period, then wake at the start of the next one. Compare the first month against the provider's own counter before you trust the number, because the two do not always count the same bytes. RelayBandwidthRate caps the sustained rate, which is what keeps the uplink usable and the provider relaxed.
When you add a second exit, put it on a different network rather than in the same rack as the first. Diversity is a large part of what an exit contributes, and two machines in one place fail together. Tie them into one family, publish the same verified contact for both, and answer the mail from both. An exit that nobody can reach is treated as an anonymous problem. An exit whose operator replies the same day is treated as a server with a person behind it, which is what it is.
FAQ
Can I run a Tor exit node on a VPS I already have?
No, and this is the one place to be strict. An exit needs a dedicated address that hosts nothing else, at a provider that has agreed in advance to carry exit traffic and to forward abuse mail to you unedited. On a general-purpose VPS, ours included, that address is already doing another job and shares a neighbourhood with customers running ordinary services. Run a non-exit relay or an obfs4 bridge on the machine you have. Those are genuinely useful, they draw almost no complaints, and they need nothing more than the box you already pay for.
How much abuse mail does a Tor exit relay get, and who receives it?
It depends on your exit policy. With ReducedExitPolicy 1, port 25 rejected and the file-sharing ports excluded, most of what arrives is automated scanning and brute-force reports. Tor's exit guidelines put automated reports at roughly 80% of the total. The mail goes to whoever the provider's abuse desk forwards it to, which is why you ask before ordering whether they forward it to you with the reporter's address intact. Publish the same address in ContactInfo and on the port 80 notice page, and answer within one working day.
Do I have to publish my real name and email address?
Yes. ContactInfo is published in the public relay directory and anyone can download it, the reverse DNS name announces what the machine is, and the notice page on port 80 repeats it. That transparency is the design, not a side effect. An exit with no working contact gets treated as an anonymous nuisance, and some clients exclude exits that publish no contact at all. Add proof:uri-familyid-ed25519 and the /.well-known/tor-relay/ed25519-family-id.txt file on a domain you control, so the contact is verifiable rather than merely stated.
Why is my new exit relay carrying almost no traffic?
First check that journalctl -u tor@default contains Self-testing indicates your ORPort is reachable from the outside. Excellent., because a relay that fails its reachability test is never published and will carry nothing at all. If that line is present, the answer is usually time. A relay appears in Relay Search around three hours after startup, and clients only send it meaningful traffic once the network's bandwidth measurement has observed it, which takes days. A policy that allows ports 80 and 443 is also required before your relay is treated as an exit at all.