Setup your own private Tor Bridge with OBFS4Proxy for fun and profit on Google Compute Engine

September 08, 2018

Recently I discovered that my college’s Wi-Fi network (and most likely, their commercial firewall Fortinet is on their behalf, without their knowledge) is blocking connections to the Tor Directory Authorities, as well as blocking connections to the default bridges (also acknowledged as the hard-coded bridges) included with Tor Browser. Because I use Tor Browser as my primary internet browser this makes things a bit more difficult while I’m on campus. Luckily I took the time to learn about Tor Bridges and how to run my own.

This tutorial focuses on configuring a tor bridge server, it does not explain the basics of running a Linux Server and it assumes that you have basic Linux shell knowledge. If you have never used the Linux shell before I recommend completing the tutorial at Additionally, a lot of new user-friendly tutorials for various configuration tasks can be found at

Step 1: Getting a server…

The first thing you will need to do is get a server with high-speed internet connectivity. This should be located in a datacenter with stable power and high availability & fast networking - it’s also recommended to get a static IP Address (although a dynamic one which doesn’t change often should also be okay).

I can’t afford a server, they’re expensive, what can I do about this?

Luckily you don’t have to pay for an expensive server. Cloud computing providers such as Google Cloud, Microsoft Azure, and Amazon Web Services all offer a generous free tier including a low powered virtual server which is more than enough to run a small Tor Bridge for your personal use. It probably won’t be able to handle 100s of users but it should be able to handle you and a few of your friends and family members. I recommend using Google Compute Engine.

Why should I set up my own bridge rather than using a working public one?

If the public bridges designed through BridgeDB or Email work for you then use those. There are more people using them and depending on your observer you are more likely to blend in with the crowd than when you are the only user connecting to an IP Address. However the public bridges are sometimes slower, additionally, some censors (for example China) have the majority of public bridges blocked off. Lastly, you might not want to take away bandwidth from users whom a public bridge is their only option to connect to Tor due to costs or other reasons.

Step 2: Considerations

I want the bridge to draw as little attention as possible from my college’s network administrators so I choose to do the following to minimize risks:

  1. I set up the Virtual Machine on Google Cloud. While WHOIS does reveal the IP Address is a Google Cloud customer and not Google themselves, there are so many legitimate websites running on Google Cloud. Blocking all Google Cloud Customers would have collateral damage.
  2. OBFS4 is designed to look like an encrypted TLS Stream. Port 443 for HTTPS is the most common use case of TLS. Therefore I’ve chosen to access the bridge through port 443, a random four-digit port number might draw undesired attention from a passive network observer. Let’s remove that risk entirely. The main challenge here is not running Tor or OBFS4 as root while allowing it to use a port number below 1024, iptables for port forwarding addresses this (will explain further into the post)
  3. At the moment, it’s unclear if they try to port scan and/or connect to all ports on the virtual machine to detect Tor Bridges - I’m going to guess no as bridges from work without an issue (includes non-obfs4 ones).
  4. By setting up a Tor Bridge on Google Compute Engine, you give Google the ability to create a complete history of every time you connect to the Tor Network and how much data you transferred. Google still cannot see what you did while connected to Tor, however, you are still sharing timestamps of every time you connect to Tor as well as the amount of data transferred while connected to Tor. Everyone’s security threat model is different, consider this when deciding if Google Compute Engine is safe for you to use. Is this type of metadata worth protecting? What is the cost to protect it? How severe are the consequences if you fail to protect it?
  5. There are a few adversaries who will block an entire ISP (for example, Russia blocked Google & AWS IP Addresses in an effort to try and block telegram, see: just to block one service. Whenever possible setup a few bridges across different ISPs with a diverse range of IP Addresses, locations, and subnets instead of just one. This again depends on how much cash you have to burn to prevent your adversary from knowing you use Tor and stopping the connections. For most adversaries, a single obfs4 bridge at any ISP should suffice.
  6. There are some theoretical attacks where someone controlling both your middle node and exit node, could create a fingerprint of which bridges you use, and attempt to correlate traffic with behavioral information. I wouldn’t worry too much about this type of attack unless you are trying to protect yourself from the NSA or another powerful adversary.

Step 3: Spin-up your server

For this tutorial I’ve decided to use Google Compute Engine, any server will do, however, this is tested with Debian Strech on Google Compute Engine. So it’s time to create and power on your server. Connect to SSH and get let’s get started :)

Step 4: Initial configuration checklist

Before doing anything else you should make sure that the following tasks are taken care of:

  1. All system updates are installed.
  2. SSH Key Authentication is configured, Password Authentication should be disabled.
  3. Look over the various suggestions at and apply the ones you feel are relevant to you. Remember less can be more - decide what’s best for you.
  4. It might be worth whitelisting IP Addresses allowed to connect to SSH.

Step 5: Install any necessary software packages

If you are following along with this tutorial’s suggestions and are using Google Compute Engine you only need to run sudo apt-get install tor obfs4proxy, on other service providers you may also need to run sudo apt-get install iptables which we’ll use later in the tutorial for some port forwarding shenanigans.

Step 6: Configure the bridge

First things first let’s move the default torrc to a sample file so it’s not interfering with anything we configure. Run sudo mv /etc/tor/torrc /etc/tor/torrc.sample in your SSH Shell.

Now run sudo nano /etc/tor/torrc and start writing out your torrc. The torrc is one of the most simple configuration files I’ve seen. It’s pretty straight forward. Take a look at the following example:

# OBFS4 Tor Bridge Configuration
ExitPolicy reject *:*
RunAsDaemon 1
ORPort xxxx
BridgeRelay 1
PublishServerDescriptor 0
ServerTransportPlugin obfs3,obfs4 exec /usr/bin/obfs4proxy
ServerTransportListenAddr obfs4
ExtORPort auto
ContactInfo xxxx
Nickname xxxx

You need to pick random port numbers for ORPort and OBFS4 Port, along with setting a Nickname and providing a contact email address. You can safely leave the nickname and contact email address as xxxx since it’s a private bridge if you were running a public bridge you would want to set a recognizable nickname and email address so people can contact you if something isn’t working quite right on your bridge.

Something to consider: To minimize the enumeration risks of running a bridge I recommend picking completely random port numbers from your ORPort and OBFS4 port. While it’s not perfect and a full port scan could still reveal that you are running a bridge, the risk of detection by your adversary drops.

Your final torrc file will look something like the following:

# OBFS4 Tor Bridge Configuration
ExitPolicy reject *:*
RunAsDaemon 1
ORPort 8817
BridgeRelay 1
PublishServerDescriptor 0
ServerTransportPlugin obfs3,obfs4 exec /usr/bin/obfs4proxy
ServerTransportListenAddr obfs4
ExtORPort auto
ContactInfo Nathaniel Suchy <>
Nickname nsuchy

Next up we will need to add a few firewall rules to allow you to access the bridge from port 443.

sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 2888 -j ACCEPT
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 2888

Finally, run sudo service tor restart in your SSH Terminal and you’re ready to configure your client (Tor Browser).

Step 7: Configure your client (Tor Browser)

Finally, it’s time to configure Tor Browser to connect to your bridge. First things first open Tor Browser and open “Tor Network Settings”, check the box “Tor is censored in my country”, click “Provide a bridge I know” and paste your bridge line.

What’s my bridge line?

To get your bridge line run sudo cat /var/lib/tor/pt_state/obfs4_bridgeline.txt in your SSH Terminal. Your response should look like the following:

Bridge obfs4 <IP ADDRESS>:<PORT> <FINGERPRINT> cert=<CERT INCLUDED HERE> iat-mode=0

<IP Address> will be the IP Address provided to you by your service provider. <PORT> will be 443. <FINGERPRINT> can be found by running sudo cat /var/lib/tor/fingerprint in your SSH Terminal - the response will be your bridge’s nickname followed by a space and a string of text, your bridge line should only include that string of text (leave out the nickname and space). Finally, <CERT INCLUDED HERE> was already provided when getting your bridge line, no further action is required here. Your final bridge line will look like the following:

Bridge obfs4 A1B2C3D4E5F6G7H8I9JK0 cert=A1B2C3D4E5F6G7H8I9JK0 iat-mode=0

You can now give Tor Browser your bridge line and connect to the Tor Network :)

It’s stuck on connecting…

Make sure that your Google Compute Engine firewall rules allow “HTTPS” (TCP Port 443) if the port isn’t open and is blocked by the firewall no one can connect to your bridge and use what you just set up.

I’m still stuck

For more detailed information on configuring bridges, check out,, and

And if you are still confused after reading over all of this information, please join #tor at and someone there will help you.

Suggestions or Feedback?

I’m always open to your suggestions and/or feedback, if you have suggestions or feedback on this blog please send an email to I’d love to hear from you :)