Tor relay¶
Introduction¶
Tor is an anonymity service and software that routes traffic by way of three volunteer-run servers called relays. The three-hop design is to ensure privacy by resisting surveillance attempts.
Prerequisites and assumptions¶
The following are minimum requirements for using this procedure:
- A public IPv4 address, whether directly on the server or with port forwarding
- A system that is able to run 24/7, to be useful for the Tor network
- The ability to run commands as the root user or use
sudo
to elevate privileges - Familiarity with a command-line editor. The author is using
vi
orvim
here, but substitute in your favorite editor - Comfort with changing SELinux and firewall settings
- An unmetered connection, or a connection with a high bandwidth limit
- Optional: A public IPv6 address for dual-stack connectivity
Installing Tor¶
To install Tor, you need to first install the EPEL (Extra Packages for Enterprise Linux) and run updates:
dnf -y install epel-release && dnf -y update
Then install Tor:
dnf -y install tor
Configuring Tor¶
With the packages installed, you need to configure Tor. The author uses vi
for this, but if you prefer nano
or something else, go ahead and substitute that in:
vi /etc/tor/torrc
The default torrc
file is pretty descriptive, but can get long if you just want a Tor relay. A minimum relay configuration is similar to this:
Nickname TorRelay
ORPort 9001
ContactInfo you@example.com
Log notice syslog
Taking a closer look¶
- The
Nickname
is a (non-unique) nickname for your Tor relay. - The
ORPort
is the TCP port your Tor relay listens on. The default is9001
. - The
ContactInfo
is your contact information, in case there's issues with your Tor relay. Set this to your email address. - The
Log
is the severity and destination of your Tor relay logs. We are loggingnotice
to prevent sensitive information from being logged, andsyslog
to output to thesystemd
log.
System configuration¶
If you have chosen another TCP/IP port than 9001
(the default), you will need to adjust the SELinux tor_port_t
to whitelist your Tor relay's port. To do so:
semanage port -a -t tor_port_t -p tcp 12345
Replace 12345
with the TCP Port you set in your ORPort
.
You will also need to open your ORPort
port in the firewall. To do so:
firewall-cmd --zone=public --add-port=9001/tcp
firewall-cmd --runtime-to-permanent
Replace 9001
with the TCP Port you set in your ORPort
.
Limiting the bandwidth¶
If you do not want to dedicate all your bandwidth to Tor, say you have a fair use policy at your ISP, you can limit your bandwidth. You can limit in terms of bandwidth (e.g., 100 megabits) or traffic in a period of time (e.g., 5GB per day).
To do this, edit the torrc
file:
vi /etc/tor/torrc
If you want to limit the bandwidth, you will need to append the following line to your torrc
file:
RelayBandwidthRate 12500 KB
This will allow 12500 KB per second of bandwidth, which is about 100 megabits per second.
If you prefer to transfer a specific amount of traffic in a period of time, say per day, append the following instead:
AccountingStart day 00:00
AccountingMax 20 GB
These values imply that:
- Your bandwidth accounting period is every day starting at 00:00 system time. You can also change
day
toweek
ormonth
, or replace00:00
with another time. - In your bandwidth accounting period, you will transfer 20 GB. Increase or decrease the value if you want to allow more or less bandwidth for your relay.
What happens after you used your specified bandwidth? Your relay will block new connection attempts until the end of the period. If your relay did not use the specified bandwidth in your period, the counter will reset without any downtime.
Test and turn up¶
Once you have set your Tor relay configuration, the next step is to turn up the Tor daemon:
systemctl enable --now tor
In your systemd logs, you should get a line like:
Jan 14 15:46:36 hostname tor[1142]: Jan 14 15:46:36.000 [notice] Self-testing indicates your ORPort A.B.C.D:9001 is reachable from the outside. Excellent. Publishing server descriptor.
This indicates your relay is accessible.
Within a few hours, your relay will be listed on Tor Relay Status by typing in your Nickname or public IP address.
Relay considerations¶
You can also extend the configuration to make your Tor relay an exit or bridge relay. You can also set up a maximum of 8 relays per public IP address. The Tor systemd unit file in EPEL is not designed for more than one instance, but the unit file can be copied and modified to accommodate a multi-relay setup.
Exit relays are the last hop of a Tor circuit connecting directly to websites. Bridge relays are unlisted relays that help users with internet censorship connect to Tor.
Options for the torrc
file are in the man page. Here, we describe a basic configuration for an exit and bridge relay.
Running an exit relay¶
Warning
If you plan to run an exit relay, make sure your ISP or hosting company is comfortable with it. Abuse complaints from exit relays are very common, as it is the last node of a Tor circuit that connects directly to websites on behalf of Tor users. Many ISPs and hosting companies disallow Tor exit relays for this reason.
If you are unsure your ISP allows Tor exit relays, look at the terms of service or ask your ISP. If your ISP says no, look at another ISP or hosting company or consider a middle or bridge relay instead.
If you want to run an exit relay, you'll need to append the following to your torrc
:
ExitRelay 1
However, this will use the following default exit policy:
ExitPolicy reject *:25
ExitPolicy reject *:119
ExitPolicy reject *:135-139
ExitPolicy reject *:445
ExitPolicy reject *:563
ExitPolicy reject *:1214
ExitPolicy reject *:4661-4666
ExitPolicy reject *:6346-6429
ExitPolicy reject *:6699
ExitPolicy reject *:6881-6999
ExitPolicy accept *:*
This exit policy blocks only a tiny subset of TCP ports, which allows abuse from BitTorrent and SSH, with which many ISPs are uncomfortable.
If you want to use a reduced exit policy, you can set it in the torrc
:
ReducedExitPolicy 1
You can also have a more restrictive exit policy, for instance only allowing DNS, HTTP, and HTTPS traffic. This can be set as:
ExitPolicy accept *:53
ExitPolicy accept *:80
ExitPolicy accept *:443
ExitPolicy reject *:*
These values imply that:
- We allow exit traffic to TCP ports 53 (DNS), 80 (HTTP), and 443 (HTTPS) with our
ExitPolicy accept
lines - We disallow exit traffic to any other TCP port with our wildcard
ExitPolicy reject
lines
If you want an unrestrictive exit policy, by only blocking SMTP traffic, this can be set as:
ExitPolicy reject *:25
ExitPolicy reject *:465
ExitPolicy reject *:587
ExitPolicy accpet *:*
These values imply that
- We disallow exit traffic to the standard SMTP TCP ports of 25, 465, and 587 in our
ExitPolicy reject
lines - We allow exit traffic to all other TCP ports in our wildcard
ExitPolicy accept
line
We can also allow or block a range of ports as follows:
ExitPolicy accept *:80-81
ExitPolicy reject *:993-995
These values imply that:
- We allow exit traffic to TCP ports 80-81
- We disallow exit traffic to TCP ports 993-995, which are used for the SSL-secured IMAP, IRC, and POP3 variants
You can also allow exit traffic to IPv6 addresses, assuming your server has dual-stack connectivity:
IPv6Exit 1
Running an obfs4 bridge¶
Direct connections to Tor are blocked in many parts of the world, including China, Iran, Russia, and Turkmenistan. In those countries, unlisted bridge relays are used by Tor clients.
Tor operates using a system of pluggable transports, which allow Tor traffic to be masked as other protocols such as unidentifiable dummy traffic (obfs4), WebRTC (snowflake), or HTTPS connections to Microsoft services (meek).
Due to its versatility, obfs4 is the most popular pluggable transport.
To set up an obfs4 bridge, as obfs4 is not in the EPEL repos, we will need to compile it from scratch. Let us first install the necessary packages:
dnf install git golang policycoreutils-python-utils
Next, we will download and extract the obfs4 source code:
wget https://gitlab.com/yawning/obfs4/-/archive/obfs4proxy-0.0.14/obfs4-obfs4proxy-0.0.14.tar.bz2
tar jxvf obfs4-obfs4proxy-0.0.14.tar.bz2
cd obfs4-obfs4proxy-0.0.14/obfs4proxy/
You can also get obfs4 directly from git clone
, but that depends on a newer version of Go than what exists in AppStream so we will not use that.
Then, we will compile and install obfs4:
go build
cp -a obfs4proxy /usr/local/bin/
Once obfs4 is installed, we will append the following to our torrc
:
ServerTransportPlugin obfs4 exec /usr/local/bin/obfs4proxy
ServerTransportListenAddr obfs4 0.0.0.0:12345
ExtORPort auto
These values imply that:
- We are running an obfs4 pluggable transport located at
/usr/local/bin/obfs4proxy
on ourServerTransportPlugin
line ServerTransportListenAddr
makes our pluggable transport listen on port 12345- Our
ExtORPort
line will listen on an randomly chosen port for connections between Tor and our pluggable transport. Normally, this line should not be changed
If you want to listen on another TCP port, change 12345
with your desired TCP port.
We will also allow our chosen TCP port 12345
(or the port you chose) in SELinux and firewalld
:
semanage port -a -t tor_port_t -p tcp 12345
firewall-cmd --zone=public --add-port=12345/tcp
firewall-cmd --runtime-to-permanent
Running multiple relays¶
As mentioned earlier, you can set up to 8 Tor relays per public IP address. For instance, if we have 5 public IP addresses, we can set up a maximum of 40 relays on our server.
However, we need a custom systemd unit file for each relay we run.
Let us now add a secondary systemd unit file at /usr/lib/systemd/system/torX
:
[Unit]
Description=Anonymizing overlay network for TCP
After=syslog.target network.target nss-lookup.target
PartOf=tor-master.service
ReloadPropagatedFrom=tor-master.service
[Service]
Type=notify
NotifyAccess=all
ExecStartPre=/usr/bin/tor --runasdaemon 0 -f /etc/tor/torrcX --DataDirectory /var/lib/tor/X --DataDirectoryGroupReadable 1 --User toranon --verify-config
ExecStart=/usr/bin/tor --runasdaemon 0 -f /etc/tor/torrcX --DataDirectory /var/lib/tor/X --DataDirectoryGroupReadable 1 --User toranon
ExecReload=/bin/kill -HUP ${MAINPID}
KillSignal=SIGINT
TimeoutSec=30
Restart=on-failure
RestartSec=1
WatchdogSec=1m
LimitNOFILE=32768
# Hardening
PrivateTmp=yes
DeviceAllow=/dev/null rw
DeviceAllow=/dev/urandom r
ProtectHome=yes
ProtectSystem=full
ReadOnlyDirectories=/run
ReadOnlyDirectories=/var
ReadWriteDirectories=/run/tor
ReadWriteDirectories=/var/lib/tor
ReadWriteDirectories=/var/log/tor
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH
PermissionsStartOnly=yes
[Install]
WantedBy = multi-user.target
Replace the X
suffix after tor
/torrc
with your desired name. The author likes to number it for simplicity, but it can be anything.
Subsequently, we will add the instance's torrc
file in /etc/tor/torrcX
. Ensure each instance has a separate port and/or IP address.
We will also allow our chosen TCP port 12345
(or the port in torrcX
) in SELinux and firewalld
:
semanage port -a -t tor_port_t -p tcp 12345
firewall-cmd --zone=public --add-port=12345/tcp
firewall-cmd --runtime-to-permanent
After that, enable the torX
systemd unit:
systemctl enable --now torX
Repeat these steps for each relay you want to run.
Conclusion¶
Unlike a conventional VPN service, Tor takes advantage of volunteer-run relays to ensure privacy and anonymity, which you just set up.
While running a Tor relay does require a reliable system and for exits, a supportive ISP, adding more relays helps privacy while making Tor faster with fewer points of failure.
Author: Neel Chauhan
Contributors: Steven Spencer