computerscot.github.io

Tor obfs4 bridge with iat-mode=2

August 1, 2023

The basic instructions for setting up a bridge appear on the Tor Project website. This post shows how the instructions work in practice for one particular scenario: a censor-resistant configuration on an Ubuntu 22.04 server. The particular requirements here are inspired by comments on the Tor Project Forum on the needs of users in countries with extreme censorship.

Tor obfs4 bridges have a rarely used feature for obfuscating packet lengths:

This post outlines the process for setting up a private Tor obfs4 bridge with iat-mode=2 on both server and client. By using obfs4, on a bridge that is private, with obfuscated Inter-Arrival Time (IAT) due to variable-length packets, Tor is in its most highly obfuscated configuration.

The disadvantage of a private bridge is that only you and your friends can use it. You could make the bridge public, but then it would vulnerable to having its IP address scraped by certain countries. So consider the alternative of helping people in extremely censored countries. Once you've set up and tested your bridge, send your private bridge line to frontdesk@torproject.org. They will share your bridge with people who really need it!

Server

The server in the examples is running Ubuntu 22.04.

Install the prerequisite package:

apt update && apt upgrade -y
apt install -y apt-transport-https

Create a new file in /etc/apt/sources.list.d/ named tor.list. Since Ubuntu 22.04 is jammy, insert these entries:

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

Download the gpg key used to sign the packages:

wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null

Install the Tor packages:

apt update
apt install -y tor deb.torproject.org-keyring

Install the package for obfs4:

apt install -y obfs4proxy

Allow obfs4proxy to bind to privileged ports:

setcap cap_net_bind_service=+ep /usr/bin/obfs4proxy

Edit the default service file:

vi /lib/systemd/system/tor@default.service

Change the NoNewPrivileges line to read:

NoNewPrivileges=no

Edit the instance service file:

vi /lib/systemd/system/tor@.service

Repeat the process to change the NoNewPrivileges line to read:

NoNewPrivileges=no

After saving the amended file, run:

systemctl daemon-reload

Edit the Tor configuration file:

vi /etc/tor/torrc

Use the template below, making your own changes to public IPv4 address, both port numbers, contact info, and bridge nickname. You will need to open the ORPort and the ServerTransportListenAddr port in your server's firewall. The server public IPv4 Address was needed only because of the way the particular VPS vendor set up their networking. Normally Tor can determine it automatically. Also notice that the pluggable transport listening address was specified as tcp/9456 just as an example. As you can read on the Tor Project Forum, for some countries you can only use certain ports, e.g. tcp/80, tcp/443, or tcp/8080.

Log notice file /var/log/tor/log
ORPort 9123 IPv4Only
Address XX.XX.XX.XX
ExtORPort auto
BridgeRelay 1
PublishServerDescriptor bridge
BridgeDistribution none
ExitPolicy reject *:*
ServerTransportPlugin obfs4 exec /usr/bin/obfs4proxy
ServerTransportListenAddr obfs4 0.0.0.0:9456
ServerTransportOptions obfs4 iat-mode=2
ContactInfo you@example.com
Nickname YourBridgeNickname
ControlPort 9051
CookieAuthentication 1

An alternative is to replace the ORPort and Address lines with:

ORPort 127.0.0.1:auto
AssumeReachable 1

These make the ORPort completely hidden. It need not be opened in your server firewall, and it cannot be probed by censors.

Start your bridge running with your revised configuration:

systemctl restart tor@default

Check the logs:

tail /var/log/tor/log

The last few lines of the log should look something like this:

[notice] Bootstrapped 100% (done): Done
[notice] Now checking whether IPv4 ORPort XX.XX.XX.XX:9123 is reachable... (this may take up to 20 minutes -- look for log messages indicating success)
[notice] Self-testing indicates your ORPort XX.XX.XX.XX:9123 is reachable from the outside. Excellent. Publishing server descriptor.
[notice] Performing bandwidth self-test...done.

The reachability lines will not appear if you used the options to completely hide your ORPort.

Obtain a template for the bridge line:

cat /var/lib/tor/pt_state/obfs4_bridgeline.txt

It will look like this:

Bridge obfs4 <IP ADDRESS>:<PORT> <FINGERPRINT> cert=YYY...ZZZ iat-mode=2

Obtain your bridge fingerprint:

cat /var/lib/tor/fingerprint

Use the template and the fingerprint to compose the final Tor obfs4 bridge line. Remember it is the ServerTransportListenAddr port, not the ORPort, that the user needs to have in the bridge line.

Install the nyx relay monitor:

apt install -y python3-pip
pip3 install nyx

To invoke the nyx monitor:

nyx

After about three hours, you can see how your bridge looks from the Tor Project's point of view on the Tor Project Relay Search page.

After about twenty-four hours, you can display the bridge statistics report:

cat /var/lib/tor/stats/bridge-stats

There is a discussion of what the bridge stats mean on StackExchange.

Client

Download the Tor Browser installer for your platform from https://www.torproject.org/download. For situations where *.torproject.org is blocked, or if you need further help in downloading Tor, email frontdesk@torproject.org.

When Tor Browser starts up, click Configure Connection.

Click Add a Bridge Manually.

Enter your private obfs4 bridge line with the ending iat-mode=2.

Connect to the Tor network.

When I tested this, the connection got to 50% progress, and then there was a delay of about 2 minutes before the connection was complete. It may be necessary to wait a few minutes the first time you connect to your bridge.