Running a Tor relay on a Raspberry Pi

The Onion Relay (Tor) is an essentially important piece of infrastructure that helps keep the Internet free. It’s a system of relays that allow users to access the Internet by hopping through several different connections, thus bypassing firewalls and concealing their identity. It can be used to get around censorship blockades, test network security, post information anonymously, and a whole bunch more. It also remains one of the few technologies that’s safe from massive spying programs, such as those by the NSA. Tor relays can run on any computer with Internet access, and today I’ll show you how to set up your own relay on a home network using a Raspberry Pi.

I’ve thought about running my own Tor relay before, but it was the Electronic Frontier Foundation’s Tor Challenge that finally got me to do it. I’ve got a Raspberry Pi sitting around that’s not doing a whole lot at the moment, so I decided to use it. It took me a few hours to get this running, but I’ve cooked it down into reusable code snippets that you can paste straight into your terminal window to get things up and running. You’ll be done in about 15 minutes, albeit with a few breaks in between for compiling. There are a few steps you’ll need to do manually, mostly at the beginning and the end, but they’re easy, few and far between.

To complete this recipe, you will need the following:

  • Raspberry Pi
  • Micro-USB power cable to power the Pi
  • LAN cable to connect the Pi to your router
  • Monitor, keyboard, mouse for the initial setup

Of course, you could do this recipe with any Internet-capable computer, but the Raspberry Pi is a great choice. Why? The Pi is tiny and cheap. You can buy it for around 30€ and it only uses 5 watts of power, so it’ll hardly make a dent in your power bill. Also, the hard drive is an SD card. Hook it up the way you want to have it, make an image, and save it – if it gets hacked or something else happens to it, just flash it to another SD card and you’re good to go again. It also has a huge community so you’ll be able to get help easily if you have any problems. And it runs plain old Linux, so you can basically run any software on it – including Tor – just like you would on a normal Linux box.

Setting up the Raspberry Pi

Skip this if you already have a Raspberry Pi working and you want to continue using that system. Otherwise, this is a very quick guide to getting your Raspberry Pi up and running. It is in no way meant to replace other guides on the Internet.

Installing Raspbian

Raspbian is a special Linux distribution that’s adapted to Raspberry Pi. I chose to install it using NOOBS, which is the way most people go when they get started with a Pi. You just download the zip file from the Raspberry Pi site, format your SD card to use FAT32 (e.g. with GParted or a similar tool), and unzip NOOBS onto the root directory of the SD card. The SD card should contain the contents of the zip file, not a folder containing its contents. If the SD card has a folder called e.g. NOOBS_v1_3_2 which contains recovery.elf, recovery.img and a few other files, you need to move all of those files to the zip file’s top directory.

Now that you’ve done that you can put the SD card in the Raspberry Pi, connect the Pi to a monitor using an HDMI cable, and plug the Pi in to install your distribution. I chose Raspbian, because that’s the most common distribution on Raspberry Pi.

Once you’ve selected the options you like, the Pi unpacks the distribution and sets it up for you. This will take a while – maybe 20 minutes – so go read a book or something and come back later. When you’re done, the Pi will restart and the setup will continue in interactive mode. There’s not a lot you have to do here, but you need to make sure that you turn SSH on so you can log onto your Pi remotely. As soon as you’ve done that, you can finish the setup. The Pi will boot into a terminal. You can shut it down now with the following command:

sudo shutdown

Setting up SSH access with a static IP

Once the Pi has shut down, disconnect it from your power supply and connect it to your router with the LAN cable, then reconnect the power supply. It will boot up and automatically connect to the router and thus to the Internet.

Of course, you could run your server using WLAN, but that’s a bit more of a pain and a lot slower. If you connect your Pi to your router with LAN, you can pretty much let it run and forget about it, which is why I suggest doing it that way.

The rest of the steps can be done from the safety and comfort of your normal computer. The Pi should be ready to access by SSH. First, though, you’ll need to find its IP address. One of the easier ways of doing this is to navigate to your router’s webpage. It’s often located at http://192.168.178.1/, so try that link first. Every router presents a different page, so this part of the walkthrough will be pretty general.

Your router will probably present you with a password page. Enter your password to log on and check the links the following page has. You’re looking for something like “Home network.” If you click on that you should be able to access a list of devices in your home network, their IPs and how they’re connected. Look for one named “raspberrypi” connected by LAN. You should be able to access it using its IP address and the user you set up (if you followed the default settings, your username will be “pi”):

# Syntax is ${USER}@${IP_ADDRESS}, check your router for the IP or use your hostname
ssh pi@raspberrypi

If you like, open up the option for the Pi’s connection on the router page and give it a static IP address. If you do, you can write down the IP address and never have to look it up again.

All of the following commands should be performed on the Pi, i.e. in the SSH window that you’re accessing the Pi with, unless noted otherwise.

Bringing the Pi up to date

Now you should update the software on your Pi, because the image you installed will probably be a bit behind on the newest packages.

sudo apt-get update
sudo apt-get upgrade

This step will probably run for a while. Afterwards, set the correct timezone, following the prompts that this command produces:

sudo cp /usr/share/zoneinfo/`tzselect` /etc/localtime

This command executes tzselect, which will ask you some questions to produce a string pointing to your correct timezone, and then use that to find a timezone file. It copies that file to /etc/localtime, which the system uses to set its timezone.

Now your Pi is up to date and ready to rare, so you’re good to go!

Downloading and installing Tor

First off, you’ll need a few dependencies that aren’t preinstalled in Raspbian. These can be installed easily enough like this:

sudo apt-get install libevent-dev libssl-dev ufw

Since we’re compiling the sources anyway, we might as well clone the source repository so that updating later is easier. You can clone Tor like this:

git clone https://git.torproject.org/tor.git

This will clone the master branch of the Tor sources into a subdirectory, tor. Since master is a development branch, though, you’ll want to check out the newest release branch. You can check for the newest release like this:

cd tor
git branch -a

This will show you a list of all of the available branches. Some of them will be labeled with “maint-*”, which means maintenance, one will be called “master” and others will be the various releases, shown as “release-*”. At the time I wrote this tutorial, release-0.2.5 was the most recent, so I checked it out with:

git checkout release-0.2.5

This swaps out the code in the repository folder for the last stable release for version 0.2.5.

Now you have the correct version of the code, so it’s time to configure, build and install the software. Again, from within the tor directory, we do:

./autogen.sh
./configure
make
sudo make install

This will take a while, so go do something else and check back in a half hour or so. When it’s done, Tor will be installed system-wide on your Pi.

Configuring Tor

Before we start using Tor, we have to configure some options. When we install Tor from its sources, the options are stored in /usr/local/etc/tor, so we’ll write a config file to that directory like this. I’ve included some variables that you’ll need to set for yourself, because this is the configuration for your very own instance of Tor, not something generic.

# This uses the variables $NICKNAME and $CONTACT_INFO
# Set them like this:
# VARIABLE="the value it should have"
# before you run the following lines.
echo "Log notice file /var/log/tor/notices.log
RunAsDaemon 1
ORPort 9001
Nickname $NICKNAME
RelayBandwidthRate 1 MB
RelayBandwidthBurst 1 MB
ContactInfo $CONTACT_INFO
DirPort 9030
ExitPolicy reject *:*" >> torrc

This echoes the quoted lines into a new file called torrc. It’s a very basic setup that includes a few essential options that you need to get your Tor relay running, and you may want to change it. For a full list of the available options and more explanations, see the Tor manual. There’s also an example file stored on your Pi at /usr/local/etc/tor/torrc.sample that you can refer to. The configuration I show does the following:

  • Log notice file: Let notices be logged to /var/log/tor/notices.log
  • RunAsDaemon: Run Tor as a daemon, so I can close the shell that called it without exiting Tor
  • ORPort: Set the port to listen for connections from Tor clients and servers to 9001
  • Nickname: Set the nickname of this Tor relay
  • RelayBandwidthRate: Set the bandwidth I allow for incoming relayed connections to 1 MB
  • RelayBandwidthBurst: Kind of like RelyBandwidthRate, but in both directions
  • ContactInfo: My contact info, important so that Tor can contact me if it needs to
  • DirPort: Set port for directory service to 9030
  • ExitPolicy: Reject exit requests for all IPs and ports. This makes the server into a pure relay, rather than an exit node.

Now we need to make that file available system-wide for Tor to find. We give it to the root user and move it to the folder where Tor will find it:

sudo chown root:root torrc
sudo mv torrc /usr/local/etc/tor/

Now, when Tor starts, it will read that config and know what to do.

In order to be able to keep better track of what Tor is doing, I chose to add a user named tor that is responsible for the process. You can do that like this:

sudo adduser tor

Finally, you need to make the directory that the log is written to and give the tor user access to it, so it can write the log outputs there.

sudo mkdir /var/log/tor
sudo chown tor /var/log/tor

Starting Tor on boot

The Raspberry Pi powers down when the power supply is interrupted – if I unplug it, for example, or if the power somehow goes out. It automatically restarts when it has power again. I don’t like having to log onto the Pi in order to restart Tor whenever this happens – even though this doesn’t happen a lot – so I set it up to start as soon as the Pi boots up. You can do the next step in a text editor if you want – I wrote it this way, which is kind of weird, so you can just paste it into your terminal and have the same result.

# This cats the shebang line of another script into our new one
cat /etc/init.d/alsa-utils | head -n 1 >> tor-start
# This command starts tor as the user tor
echo "sudo -u tor tor" >> tor-start
# Make script executable, move to right place, register with init.d
chmod +x tor-start
sudo chown root:root tor-start
sudo mv tor-start /etc/init.d
sudo update-rc.d tor-start defaults

Now Tor will be started by the user tor whenever your Pi boots.

Configuring your router

Even though Tor is set up on your Pi, it won’t be able to work as a server yet because your router still is blocking all connections to it. We’ll fix that by opening up the router page again. Look for a section called something like “Port forwarding”, which might be located in the section “Internet”, and add two entries: One for ORPort and one for DirPort. They need to match the ports that you wrote to your config file and pass through TCP requests to the correct computer, in this case the Raspberry Pi. It should be easy to find and set the options, but because each router is different, you’ll need to look around to find out how to do it on yours.

Testing that everything worked

Now you’ve got a running Pi that’s reachable by SSH. It’s up to date, Tor is set up, and your router is forwarding requests to the correct ports, so your little Tor server is reachable. To activate Tor, restart your Pi:

sudo reboot

Wait a few minutes and then reconnect to your Pi by SSH. Tor should now be running – you can check for its process like this:

ps -A | grep tor

You should see a line of output that looks like this:

 2115 ?        00:01:53 tor

It shows the process ID, the TTY, the process’ runtime and its command. If you don’t see anything at all, Tor’s not running, so revisit the sections on setting up Tor.

Now it’s time to check if Tor can reach the outside world by checking the logfile. We configured it to be written to /var/log/tor/notices.log. You can see the entire content like this:

cat /var/log/tor/notices.log

That’s a lot of output, though. What you’re looking for are two lines that should say something like this:

Jun 07 14:45:48.000 [notice] Self-testing indicates your DirPort is reachable from the outside. Excellent.
Jun 07 14:45:48.000 [notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.

You can just grep those out like this:

cat /var/log/tor/notices.log | grep Excellent

If you see those two lines at least once, you know that your server is reachable and working. In about an hour or so you should be able to find your relay’s nickname on Globe. You can find mine here.

After you’re done, don’t forget to register your new relay with EFF so that the good folks there know that you support their campaign! Enjoy the warm, fuzzy feeling of knowing that you’re helping support freedom and anonymity in the Internet.

About

My name’s Daniel Lee. I've founded a company for planning solar power. I've worked on analog space suit interfaces, drones and a bunch of other things in my free time. I'm also involved in standards work for meteorological data. I worked for a while German Weather Service on improving forecasts for weather and renewable power production. I led the team for data ingest there before moving to EUMETSAT.

Tagged with: , ,
Posted in Uncategorized
8 comments on “Running a Tor relay on a Raspberry Pi
  1. Serofu says:

    I got stuck at the end of installation, just before configuring.
    ./configure my pi didn’t like this command. it didn’t know what to do with it. I did not see any errors during updates/upgrades. I did not see a configure file, but a configure.sc was listed. Any assistance would be welcome.
    Serofu

    Like

    • erget says:

      Did you checkout the release beforehand? And are you sure that you were in the tor folder when you tried to run ./configure? It will only work if run from within that folder.

      Like

      • Serofu says:

        Yes. First time I checked out 0.2.5, and a separate pi I tested 0.2.4 but still get stuck at the same place. I have confirmed I am in the tor folder.
        Linux raspberrypi 3.12.22+ #691 PREEMPT Wed Jun 18 18:29:58 BST 2014 armv6l
        The programs included with the Debian GNU/Linux system are free software;
        the exact distribution terms for each program are described in the
        individual files in /usr/share/doc/*/copyright.
        Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
        permitted by applicable law.
        Last login: Fri Jun 27 08:32:16 2014
        pi@raspberrypi ~ $ cd tor
        pi@raspberrypi ~/tor $ ls
        acinclude.m4 ChangeLog contrib Doxyfile.in LICENSE Makefile.am README src
        autogen.sh configure.ac doc INSTALL m4 Makefile.nmake ReleaseNotes
        pi@raspberrypi ~/tor $ ./configure
        -bash: ./configure: No such file or directory
        pi@raspberrypi ~/tor $ ls -la
        total 1508
        drwxr-xr-x 7 pi pi 4096 Jun 27 08:44 .
        drwxr-xr-x 5 pi pi 4096 Jun 27 08:38 ..
        -rw-r–r– 1 pi pi 8409 Jun 27 08:44 acinclude.m4
        -rwxr-xr-x 1 pi pi 339 Jun 27 08:42 autogen.sh
        -rw-r–r– 1 pi pi 830005 Jun 27 08:44 ChangeLog
        -rw-r–r– 1 pi pi 45961 Jun 27 08:44 configure.ac
        drwxr-xr-x 6 pi pi 4096 Jun 27 08:44 contrib
        drwxr-xr-x 3 pi pi 4096 Jun 27 08:44 doc
        -rw-r–r– 1 pi pi 59478 Jun 27 08:42 Doxyfile.in
        drwxr-xr-x 8 pi pi 4096 Jun 27 08:44 .git
        -rw-r–r– 1 pi pi 2977 Jun 27 08:44 .gitignore
        -rw-r–r– 1 pi pi 2084 Jun 27 08:42 INSTALL
        -rw-r–r– 1 pi pi 7719 Jun 27 08:44 LICENSE
        drwxr-xr-x 2 pi pi 4096 Jun 27 08:44 m4
        -rw-r–r– 1 pi pi 2316 Jun 27 08:44 Makefile.am
        -rw-r–r– 1 pi pi 310 Jun 27 08:42 Makefile.nmake
        -rw-r–r– 1 pi pi 796 Jun 27 08:44 README
        -rw-r–r– 1 pi pi 525738 Jun 27 08:42 ReleaseNotes
        drwxr-xr-x 9 pi pi 4096 Jun 27 08:42 src
        pi@raspberrypi ~/tor $

        Like

      • erget says:

        Oh, thanks – you caught me 🙂 I forgot the first step, which is to run autogen.sh. Strangely enough the INSTALL file mentions it, but not the README. I’ve updated the post accordingly. Thanks for the feedback and hope it works!

        Like

  2. Serofu says:

    Just an FYI, as of now, using N00Bs 1.3.9, after installing Rasbian, I ran:
    sudo apt-get update -y && sudo apt-get upgrade -y && sudo reboot

    After the reboot, I ran:
    sudo apt-get install tor

    A current tor client was installed and I was building a circuit in minutes.

    Like

    • erget says:

      I’d be very careful about doing this – on the Tor site they mention problems with installing Tor from repositories while running Raspbian: https://www.torproject.org/docs/debian

      This has to do with the way the Raspbian developers call their architecture “armhf”, which conflicts with a naming convention used in the Debian repositories. This means that packages install cleanly – but they don’t work because they were actually compiled for another processor architecture.

      For that reason, it’s recommended to build Tor from sources – like I show in the tutorial. Even if it installs cleanly you will apparently have trouble at runtime.

      Like

  3. Jim says:

    Hi, I know this is an old post but is there any reason these instructions wouldn’t work today?

    Like

Leave a reply to erget Cancel reply

From the archive