Tor relays are volunteer-run servers that route encrypted traffic through the Tor network. A middle relay (also called a non-exit relay) only passes traffic between other relays: it never connects to websites on behalf of users, so your server's IP address does not appear as the source of anyone's traffic. In this tutorial you will install Tor from the Tor Project's repository on Ubuntu 24.04, configure a middle relay with sensible bandwidth limits, keep it updated automatically and verify that it has joined the network.
Prerequisites
To follow this tutorial you need:
- A server running Ubuntu 24.04 LTS with a public IPv4 address, for example a CubePath VPS. The relay should stay online for months: relays that come and go are of little use to the network.
- A non-root user with
sudoprivileges. - Bandwidth to spare. The Tor Project recommends at least 16 Mbit/s in both directions and at least 100 GB of outbound traffic per month. Relays below 40 Mbit/s need at least 512 MB of RAM; faster ones need 1 GB or more.
- Permission to run a relay under your provider's acceptable use policy. Middle relays rarely generate abuse complaints, but read the policy before you start.
NoteThis guide configures a non-exit relay only. Exit relays make outgoing connections for Tor users, receive abuse complaints and need careful legal and operational preparation. Do not turn a relay into an exit without reading the Tor Project's exit relay guidelines first.
Step 1 - Adding the Tor Project repository
Ubuntu's own tor package lags behind upstream releases, and relays should run a current, supported Tor version. The Tor Project publishes signed packages for Ubuntu at deb.torproject.org.
Install the tools needed to fetch the signing key:
sudo apt update
sudo apt install curl gpg
Download the Tor Project's archive signing key and store it as a keyring:
curl -fsSL https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg > /dev/null
The keyring is stored in /usr/share/keyrings/ rather than /etc/apt/keyrings/ because the deb.torproject.org-keyring package you will install next updates that exact file when the Tor Project rotates its key.
Add the repository for Ubuntu 24.04 (noble):
echo "deb [signed-by=/usr/share/keyrings/deb.torproject.org-keyring.gpg] https://deb.torproject.org/torproject.org noble main" | sudo tee /etc/apt/sources.list.d/tor.list
Step 2 - Installing Tor
Refresh the package index and install Tor together with the keyring package:
sudo apt update
sudo apt install tor deb.torproject.org-keyring
Confirm that the package comes from the Tor Project repository:
apt policy tor
tor:
Installed: 0.4.8.x-1~noble+1
Candidate: 0.4.8.x-1~noble+1
Version table:
*** 0.4.8.x-1~noble+1 500
500 https://deb.torproject.org/torproject.org noble/main amd64 Packages
On Debian-based systems Tor runs as the tor@default systemd unit; tor.service is only a wrapper that starts it. Check that it is running:
sudo systemctl status tor@default --no-pager
● [email protected] - Anonymizing overlay network for TCP
Loaded: loaded (/usr/lib/systemd/system/[email protected]; enabled-runtime; preset: enabled)
Active: active (running)
At this point Tor runs as a local client only. The next step turns it into a relay.
Step 3 - Configuring the relay
Tor reads its configuration from /etc/tor/torrc. The default file contains only commented examples, so it is easiest to replace it. Make a backup first:
sudo cp /etc/tor/torrc /etc/tor/torrc.orig
sudo nano /etc/tor/torrc
Replace the contents with the following, adjusting the nickname, contact address and bandwidth values:
## Relay identity
Nickname your_nickname
ContactInfo your_name <admin AT example DOT com>
## Relay port (TCP)
ORPort 9001
## Middle relay only: never act as an exit
ExitRelay 0
ExitPolicy reject *:*
SocksPort 0
## Bandwidth: average rate and allowed burst
RelayBandwidthRate 20 MBytes
RelayBandwidthBurst 40 MBytes
## Optional monthly traffic cap (counts each direction separately)
#AccountingStart month 1 00:00
#AccountingMax 1 TBytes
## Local control port for monitoring with nyx
ControlPort 127.0.0.1:9051
CookieAuthentication 1
What each setting does:
Nickname: a public name for your relay, 1 to 19 letters and digits, no spaces.ContactInfo: a public address the Tor Project and other operators can use to reach you. Obfuscate it as shown to reduce spam, but keep it reachable.ORPort 9001: the TCP port other relays connect to. Any port works as long as it is reachable from the Internet;443helps clients behind restrictive firewalls if nothing else listens on it.ExitRelay 0andExitPolicy reject *:*: make sure the relay never becomes an exit.SocksPort 0: disables the local client proxy, which a dedicated relay does not need.RelayBandwidthRateandRelayBandwidthBurst: cap the traffic Tor relays, in bytes per second (MBytes, not megabits).20 MBytesis about 160 Mbit/s.AccountingMaxandAccountingStart: uncomment them if your plan has a monthly traffic quota. When the limit is reached, Tor hibernates until the next period.ControlPortandCookieAuthentication: expose a control port on localhost only, used by thenyxmonitor in Step 6.
Check the configuration before restarting. Run it as the debian-tor user so file permissions match the service:
sudo -u debian-tor tor --verify-config -f /etc/tor/torrc
Configuration was valid
Step 4 - Opening the ORPort in the firewall
Other relays must be able to reach your ORPort. Allow it in UFW:
sudo ufw allow 9001/tcp
sudo ufw status
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
9001/tcp ALLOW Anywhere
If UFW is not active yet, allow SSH first with sudo ufw allow OpenSSH and then run sudo ufw enable. Do not open port 9051: the control port is bound to 127.0.0.1 and must stay private.
Step 5 - Starting the relay and checking reachability
Restart Tor to apply the new configuration:
sudo systemctl restart tor@default
Follow the log while Tor bootstraps and tests its own ports:
sudo journalctl -u tor@default -f
Within a minute or two you should see lines similar to these:
Bootstrapped 100% (done): Done
Now checking whether IPv4 ORPort 203.0.113.10:9001 is reachable... (this may take up to 20 minutes -- look for log messages indicating success)
Self-testing indicates your ORPort 203.0.113.10:9001 is reachable from the outside. Excellent. Publishing server descriptor.
Press Ctrl+C to stop following the log. The line Publishing server descriptor means your relay has announced itself to the directory authorities.
Show your relay's fingerprint, which identifies it in the network:
sudo cat /var/lib/tor/fingerprint
your_nickname 1A2B3C4D5E6F7A8B9C0D1E2F3A4B5C6D7E8F9A0B
Step 6 - Monitoring the relay with nyx
nyx is a terminal monitor for Tor that shows bandwidth, connections, flags and log events in real time. Install it:
sudo apt install nyx
Run it as the debian-tor user so it can read the control port's authentication cookie:
sudo -u debian-tor nyx
The first screen shows a live bandwidth graph and recent events. Use the arrow keys to switch between pages and q to quit.
Step 7 - Finding your relay on Tor Metrics
About one to three hours after publishing its descriptor, your relay appears on the public relay search at https://metrics.torproject.org/rs.html. Search for your nickname or fingerprint.
What to expect over the following weeks:
- First days: the relay has the
RunningandValidflags but carries little traffic. The network measures new relays before trusting them with load. - After roughly a week: bandwidth usage grows as measurements come in.
- After about eight days of stable uptime: fast and stable relays receive the
Guardflag and start acting as entry nodes for clients. Traffic can drop briefly at that point, which is normal.
Restarting often or changing the relay's IP address resets much of this progress, so leave it running.
Step 8 - Keeping Tor updated automatically
Relays running outdated Tor versions are eventually rejected by the network. Ubuntu's unattended-upgrades only installs security updates from Ubuntu's own archives by default, so add the Tor Project origin.
Make sure the package is installed:
sudo apt install unattended-upgrades
Create a small configuration file for the Tor repository:
sudo nano /etc/apt/apt.conf.d/51unattended-upgrades-tor
Unattended-Upgrade::Origins-Pattern {
"origin=TorProject";
};
Check that APT picked up the new setting:
apt-config dump | grep TorProject
Unattended-Upgrade::Origins-Pattern:: "origin=TorProject";
You can then run sudo unattended-upgrade --dry-run --debug to see which packages would be upgraded on the next run.
Tor restarts automatically after an upgrade.
Troubleshooting
The log says the ORPort is not reachable. Check that UFW allows the port with sudo ufw status, that no other firewall in front of the server blocks it, and that Tor is listening with sudo ss -tlnp | grep 9001. Test from another machine with nc -zv your_server_ip 9001.
The relay does not appear on Tor Metrics after several hours. Look for Publishing server descriptor in sudo journalctl -u tor@default. If it is missing, the reachability test has not passed yet. Also make sure the server clock is correct with timedatectl, since Tor rejects consensus documents when the clock is far off.
The relay goes quiet in the middle of the month. If you enabled AccountingMax, the log shows Hibernation messages once the quota is used up. Raise the limit or lower RelayBandwidthRate so traffic spreads across the whole period.
Tor fails to start after editing torrc. Run sudo -u debian-tor tor --verify-config -f /etc/tor/torrc, which prints the line with the error, and read sudo journalctl -u tor@default -n 50.
Conclusion
Your server now runs a Tor middle relay from the official repository, with capped bandwidth, local monitoring through nyx and automatic updates. Next, you can subscribe to the tor-relays mailing list to follow operator announcements, add IPv6 to the relay with a second ORPort line using your IPv6 address in brackets, or run a bridge instead of a public relay if you want to help users in countries that block Tor.
