CT-009: Running Tor obfs4 bridge relays
This is the 9th report in the Cypherpunk Transmission series.
Tor’s presence, when used in the default configuration, can be discovered by any observer. It is no secret that advanced adversaries are indeed actively denying private access to the open internet to many around the world.
Private bridge relays with Pluggable Transports support (like obfs4) are key to circumventing sophisticated censorship.
This guide shows how easy it actually is to become a PT obfs4 bridge relay operator and help increase the currently available number of Tor bridges (~2K).
- you have ssh access to a secured (CT-0031) VPS (Debian 11.5)
- box should have 24/7 internet connectivity & >1 MBit/s available bandwidth
- basic terminal knowledge
- ~30 mins free time
1. Install Tor
SSH into your server, update the packages database, and install tor:
sudo apt update && sudo apt install tor
2. Install obfs4
obfs4proxy package is available in stable-backports, so we need to make a few modifications to the default configuration.
2.1 Create obfs4proxy.pref
Let’s create a new
obfs4proxy.pref file in the /etc/apt/preferences.d/ directory:
sudo nano /etc/apt/preferences.d/obfs4proxy.pref
Paste the following lines in the empty file:
Explanation: tor meta, always run latest version of obfs4proxy Package: obfs4proxy Pin: release a=bullseye-backports Pin-Priority: 500
2.2 Enable backports
Now let’s enable backports in
sudo nano /etc/apt/sources.list
Add this new line to the file:
deb http://deb.debian.org/debian bullseye-backports main
2.3 Install obfs4proxy
Finally we can install obfs4:
sudo apt install obfs4proxy
Check the version with
obfs4proxy --version. It should be at least 0.0.14.
Note: you can alternatively skip 2.1 and run (at 2.3)
sudo apt install -t bullseye-backports obfs4proxy; if you have any issues, consider building obfs4 from source instead2.
3. Configure the bridge
Open the Tor config file with
sudo nano /etc/tor/torrc and replace its content with this:
BridgeRelay 1 # Replace "TODO1" with a Tor port of your choice. # This port must be externally reachable. # Avoid port 9001 because it's commonly associated with Tor and censors may be scanning the Internet for this port. ORPort TODO1 ServerTransportPlugin obfs4 exec /usr/bin/obfs4proxy # Replace "TODO2" with an obfs4 port of your choice. # This port must be externally reachable and must be different from the one specified for ORPort. # Avoid port 9001 because it's commonly associated with Tor and censors may be scanning the Internet for this port. ServerTransportListenAddr obfs4 0.0.0.0:TODO2 # Local communication port between Tor and obfs4. Always set this to "auto". # "Ext" means "extended", not "external". Don't try to set a specific port number, nor listen on 0.0.0.0. ExtORPort auto # Replace "<firstname.lastname@example.org>" with your email address so we can contact you if there are problems with your bridge. # This is optional but encouraged. ContactInfo <email@example.com> # Pick a nickname that you like for your bridge. This is optional. Nickname PickANickname
Modify at least TODO1, TODO2, and optionally
<firstname.lastname@example.org> and PickANickname.
I recommend setting
ORPort and the
ServerTransportListenAddr port to something >1024, like this:
ORPort 11043 ServerTransportListenAddr obfs4 0.0.0.0:10232
Save the file and exit with
Note: if you want to use ports smaller than 1024, consult Tor issue #183563.
Open up the two ports:
sudo ufw allow 11043 && sudo ufw allow 10232
We can now enable and start tor with
systemctl enable --now tor.service. If it was already running, use
systemctl restart tor.service to restart the service instead.
To confirm the bridge is operational, monitor the logs:
sudo journalctl -e -u tor@default
The output should be similar to this:
[notice] Your Tor server's identity key fingerprint is '<NICKNAME> <FINGERPRINT>' [notice] Your Tor bridge's hashed identity key fingerprint is '<NICKNAME> <HASHED FINGERPRINT>' [notice] Registered server transport 'obfs4' at '[::]:46396' [notice] Tor has successfully opened a circuit. Looks like client functionality is working. [notice] Bootstrapped 100%: Done [notice] Now checking whether ORPort <redacted>:3818 is reachable... (this may take up to 20 minutes -- look for log messages indicating success) [notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.
To test if your obfs4 bridge port is reachable to the rest of the world, do a TCP reachability test4.
Output should be:
TCP port is reachable!
Note: if you get a different, unexpected output, check your firewall configuration.
- keep your relay secure by installing (automatic) security updates
- your bridge should appear on Relay Search in a few hours5
- running and using bridges might not be compatible with your own threat model (CT-0016)
- bridges only make it harder (not impossible) for adversaries (ie. ISPs, govs) to determine if a user is connecting to Tor
- when compared to other Tor relay admins (ie. exit relays), bridge operators are probably the least exposed to legal troubles, but the risks are not inexistent
- bridge distribution can be changed7
- recommended reading: Tor dev manual8, Pluggable Transports9, and Whonix docs10
- number of bridges and relays are available on Tor Metrics11
- if you’re not using Debian, consult Tor’s bridge setup guide for other platforms12
- to connect to your own bridge manually, read Tor’s bridge post-install instructions13
That’s it, you are now a bridge operator, a valuable Tor contributor. Thank you for helping censored users connect to the Tor network. Resistance is not futile.
Let me know if you find this helpful and, depending on interest, I will do my best to post a new Cypherpunk Transmission report every (other?) Monday.
Questions, edits and suggestions are always appreciated @ /about/.