How to Setup a Tor Middle/Guard Relay on an Ubuntu VPS

We all know what Tor is by now. Whether you know it as a tool to fight unjust censorship or that special browser you open to buy drugs online, it’s become increasingly widely used in the past decade, and it remains a powerful tool for important things like bypassing government firewalls and remaining anonymous while running home servers.

In this post I will give a brief, high level overview of how The Onion Router (yes, that’s what TOR stands for) works in different scenarios and how you can help secure and decentralise the Tor network while helping it to remain censorship resistant, and dedicate bandwidth to improve performance, all without sacrificing your own security or privacy.

I will focus this guide on setting up fresh from a VPS. You can use a cheap one such as the $6 a month option from Vultr without hogging your home network’s bandwidth. Additionally, running a Tor relay will expose your IP address to the public, as all relays are stored in the Tor relay directory. The dynamic nature of most home internet IP assignments may also degrade the reliability of your relay.

Basically, it’s worth paying the $6 to run it off a VPS.

First off, a very important distinction must be made…

"Middle” and “Guard” Relays vs. Exit Nodes

Tor has three types of nodes: guard (or entry) nodes, middle nodes, and exit nodes.

An entry node, as the name implies, is your entrance to the Tor network. Whether you type a regular old .com domain in or you use a .onion one, your traffic is first routed through an entry node.

A middle node is similarly self-explanatory. Tor works by bouncing your traffic between multiple relays, typically three. These are made up of an entry/guard node, middle node, and, depending on whether you want to access the regular “clearnet” or a “darknet” Tor hidden service, either an exit node (to the clearnet) or direct from the middle node to the server of the site you’re visiting (hidden service).

Technically an entry/guard relay and a middle relay are the same thing, but a relay is only used as an entry once it’s been active for a month or so and has been assessed by the network as being fast enough.

If you go to a normal “clearnet” site through Tor, your traffic is routed through an entry, middle, and exit node. If you go to a .onion site, your traffic remains routed within the Tor network, therefore it doesn’t require an exit node.

Here is where the important warning comes in!

You are absolutely fine running an entry/middle node, but DO NOT RUN AN EXIT NODE unless you fully understand the risks involved and have taken proper legal advice.

This is such a vital topic that even the Tor Project itself has dedicated a page to why you should not run an exit node from your home, instructing you to do it under a non-profit or limited company that supports the Tor network and can assure you are protected legally, and what to do if you get raided because someone did illegal shit that looked like it was coming from your IP address.

Luckily this is not a concern at all if you only setup a Tor entry/middle relay and disable all exit traffic. The above risks only apply to exit nodes.

This is because with a standard entry/middle node, you only relay encrypted traffic within the Tor network, and none of the traffic hits the “clearnet” from your IP or your VPS’s IP. Either your relay will send the traffic to an exit node run by someone else, or it will send the traffic within the Tor network if the user is accessing a Tor hidden service.

In either case, the encrypted nature of the Tor circuit means the network cannot monitor entry and middle relays and the traffic routed through your relay isn’t attached to your IP address.

And that’s what this guide is going to cover. How to securely setup an entry/middle relay in the Tor network. This is virtually zero risk to you if setup correctly on a VPS and assists the Tor network’s security, speed, decentralisation, and censorship resistance.

Setting up the VPS

Fire up a basic VPS with Debian or Ubuntu. Ideally you should use an SSH key for login, not a password. You should also setup the host’s firewall rules to only allow incoming traffic through port 22 from your own IP address, which would make it impossible for someone outside your IP range to even attempt to crack your SSH login.

Important: make sure you also allow HTTPS (port 443) from anywhere (not just your IP) in these host firewall rules as well!

Vultr firewall rules page allowing SSH to accept only connections from your IP

The hardware of the VPS itself can even have just 1 vCPU and 1GB RAM. The most important part to pay attention to here is the bandwidth. You want at least a few hundred GB a month, ideally at least 1TB, and if there’s charges for going over they should be reasonable. Luckily bandwidth tends to be cheap these days.

Some hosts like Digital Ocean even “pool” your bandwidth too so if you already have a VPS or a few of them, and some of their allotted bandwidth goes unused, it can be instead used by another.

Don’t worry, if you want to keep your bandwidth use under control you can set limits in the config for your relay before you enable it.

Basic VPS configuration

The first step after getting the VPS running and SSHing into it is to update the system, configure the firewall to only allow SSH and HTTPS, make sure apt is setup to install via HTTPS, and reboot:

sudo apt update && sudo apt upgrade -y
sudo apt install apt-transport-https
sudo ufw allow ssh
sudo ufw allow https
sudo ufw enable
sudo reboot

Now for security we just need to set the server to update itself automatically:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Simply remove the // from behind the updates and backports lines, than add below the default lines:


It should then look something like this:

If it looks like this you set it up right

Now just scroll down a bit and make sure it’s set to auto-reboot and auto cleanup options are enabled to ensure updates Just Work. You do this by removing the // before the Unattended-Upgrade options you want to enable, and make sure you change false to true if needed.

These are the options you want to enable, it should look like this:

Makes sure it reboots to automatically install updates and clears no longer required dependencies

Now hit ctrl + O to save and ctrl + X to exit.

Once that’s done, we can get straight on with setting up the Tor relay!

Optional: set up a domain name

At this point you can also point a domain or subdomain to your VPS’s IPv4 and IPv6 (if supported) addresses as you would any other VPS by setting A and AAAA records on your domain.

This will show up in the Tor relay directory instead of the host’s default reverse DNS. It’s not essential, but it’s better to have your relay connected to a domain you control, it’s more organised and it also gives you the option to serve up a webpage explaining what Tor is if someone visits that URL in a browser.

Vultr allows you to set reverse DNS on their end too, either while you spin up the VPS or later on in the settings tab

Most hosts should also allow you to set your domain as a reverse DNS on their control panels as well. This is not a replacement for buying and setting records for the actual domain. You should do both.

Installing the Tor relay

SSH back into the VPS once it reboots and check the codename for the version of Ubuntu or Debian you’re running:

lsb_release -c

On the current Ubuntu LTS for example this should come back with codename: jammy, this will be important in the next step.

Now we create the Tor repository file:

sudo nano /etc/apt/sources.list.d/tor.list

This should create a new blank file. In it, assuming your OS release codename is jammy, you’d paste these two lines in:

deb     [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] jammy main
deb-src [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] jammy main

If your OS codename is different (e.g. buster for Debian) replace jammy with that instead in the two lines above.

Now simply add the PGP key so apt can verify the packages:

wget -qO- | gpg --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null

Finally, we do the actual installation of the Tor server:

sudo apt update
sudo apt install tor


Now we just need to configure it.

Configuring the Tor relay

Simply open the config file:

sudo nano /etc/tor/torrc

You want to make sure to uncomment (remove the # from) the following lines:

SocksPort   0
ORPort 443
Nickname whatevernameyouwant
ExitPolicy reject *:* # no exits allowed
ExitRelay   0

SocksPort 0 has to be set for it to work properly as a relay.

The ORPort will probably be different by default. Changing it to 443 is ideal if this VPS isn’t also being used as a webserver.

Nickname can be anything but don’t make it too long. It can only contain letters and numbers, no special characters or spaces. The Tor relay will refuse to start until you change the name if you make it too long and/or put spaces or special characters in.

Last but certainly not least, the ExitPolicy reject : line makes sure that your relay does not act as an exit node. MAKE SURE YOU UNCOMMENT THIS! IT SHOULD NOT HAVE A # IN FRONT OF IT!

The ExitRelay 0 option is depreciated in favour of the ExitPolicy reject *:* option above, but they don’t cancel each other out, so you can add both to be double sure.

Here’s some screenshots of what a correct setup should look like. Remember all of this is already there, all you need to do is remove the # before the bits you want to activate!

SocksPort 0 must be set to work in relay mode

“Just for relays” section:

ORPort 443 is most compatible if this is a dedicated VPS, you can leave address commented if you didn't set a domain, set a nickname to identify your relay

Make absolutely certain you uncomment the no exits allowed line like below:




If you set a domain for your VPS earlier, enter it here.

RelayBandwidthRate 100 KB  # Throttle traffic to 100KB/s (800Kbps)
RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)

The above can be uncommented and adjusted if you wish to throttle the bandwidth rate. This is set as byes per second, not bits per second. You can convert the two here if you need.

Uncomment this to set a hard limit on the amount of data to pass through the relay daily:

AccountingMax 4 GB
AccountingStart day 00:00

Or, if you’d rather set max bandwidth per month, keep the day line commented and uncomment this one instead:

AccountingStart month 3 15:00

A screenshot of these settings:

Set only if required by your VPS provider

Now hit ctrl + O to save and ctrl + X to exit.

And finally run:

sudo systemctl restart tor@default

That’s it, your relay is now up!

You can verify it’s working by waiting a few seconds then checking the logs:

sudo journalctl -xeu tor@default.service

A message like this means it’s working:

[your IP address:443] is reachable from the outside. Excellent. Publishing server descriptor.

You will see two similar lines if you have both IPv4 and IPv6 enabled.

Final step: optional DDoS protection

The Tor network is often the target of DDoS attacks. To mitigate the effect of these on your relay, you can install a set of bash scripts that automatically updates and applies new firewall rules blocking known botnets dynamically.

First make sure you’re in your home folder:


The first command puts you in your home folder if you weren’t there already. The second should print /home/[username] to confirm you’re in your home folder.

Now let’s install the dependencies and the scripts:

sudo apt install ipset iptables curl


Now open ipv4.txt with nano:

nano ipv4.txt

Remove the contents including the comment and put in the actual IPv4 address of your VPS followed by the port (443 if you followed the above exactly) in this format:

As before hit ctrl + O and ctrl + X to save and exit.

If IPv6 is enabled, open ipv6.txt with nano and repeat the above in this format:


If you don’t have IPv6, simply wipe that file so it’s empty.

Now we make the shell scripts executable:

chmod a+x
chmod a+x
chmod a+x

And run the script with root privileges to set it up:

sudo ./

It should now print your “mangle” ipset rules. If it does, it’s working.

Finally, set a crontab so it updates daily and restores when the server reboots after an update:

(crontab -l ; echo "0 0 * * * $PWD/") | crontab -

It is normal to get a message like no crontab for [username] if you’ve not set any cronjobs before on this VPS. Don’t run it again.

You can be sure it’s working by running the below:

crontab -l

If it shows this you’re gucci:

0 0 * * * /home/[username]/

If you ever need to update these rules manually, just run:

sudo ./


You did it!

If you got this far, well done! You now have a Tor relay!

After around three hours, searching the nickname you gave to your relay on the Tor relay directory should show it. Once indexed, along with details such as IP address(es) you should see badges that say “running” and “valid.”

Don’t worry if the bandwidth field is blank and the consensus weight is 0. This is normal for a brand new node. This post from Tor explains the process for testing new relays before they’re fully active on the network.

The TL;DR is they won’t see much traffic for the first three days, then once the network gets a better idea of how much bandwidth it has it will be assigned a rank and begin to get used more and more in relays.

Since you probably feel like Mr Robot now, here’s a sick track to celebrate!

Well done!

You’re now helping the excellent Tor project remain secure, decentralised, fast, and censorship resistant!

Enjoyed this content and want more? You can follow me on Twitter, Telegram, and Nostr!

Manually copy/paste my Nostr public key here:


Wanna give me a lil tip? You can mint this post as an NFT on Optimism for 0.01 ETH using the “collect” button or zap me some sats with

You can also send some BTC on-chain here:


Or send some XMR here:





Disclaimer: The content above is only the author's opinion which does not represent any position of Followin, and is not intended as, and shall not be understood or construed as, investment advice from Followin.
Add to Favorites