Tor relay on a rpi2

This is a little walkthrough on using ansible to setup a tor relay (not an exit node) on a Raspberry Pi. It might be overhead to use ansible for this purpose but the initial goal was to experiment with ansible.

First go to Raspberry Pi download and download the raspbian iso. Then flash it to your SD card and start your Raspberry Pi. A comprehensive guide is available here. You might also want to follow the config setup doc here which explains the different options of the raspi-config tool.

Once you have your Raspberry Pi up and running, let's setup ansible to install and set up a tor relay.

To get the latest version of ansible, run the following on Debian/Ubuntu. For other distribution, follow the ansible installation from source doc:

$ sudo apt-get update && sudo apt-get install python-pip python-dev git -y
$ sudo pip install PyYAML jinja2 paramiko
$ git clone https://github.com/ansible/ansible.git --recursive /tmp/ansible
$ cd /tmp/ansible
$ sudo make install
$ sudo mkdir -p /etc/ansible
$ sudo cp /tmp/ansible/examples/hosts /etc/ansible/.
$ cd -
$ sudo rm -rf /tmp/ansible

Then make sure you're running the latest version with

$ ansible --version
ansible 2.2.0

We will be using ansible-playbook in order to run the different tasks on the Raspberry Pi.

Create a playbook in a file named rpitor.yml and copy the following lines to it:

- hosts: rpitor
  vars:
    torport=TODO
    dirport=TODO
    nodename=TODO

We will then need to complete this file with specific tasks that are to be executed from your host computer to your Raspberry Pi to setup the tor relay.

These are the options you need to fill in in the above file (the TODO):

  • torport: this is the port on which tor will be listening (it must be forwarded from your firewall/router)
  • dirport: this is the port to listen for directory requests (must as well be forwarded from your firewall/router)
  • nodename: this is the name of your node (be creative)

Update the system and install the packages

The following tasks will install the needed packages to run tor; add those lines to the playbook.

- name: rpi update
  shell: rpi-update
  become: true

- name: update and upgrade
  apt:
    update_cache=yes
    upgrade=dist

- name: install packages
  apt:
    name={{ item }}
    state=installed
  with_items:
    - tor
    - tor-arm

- name: stop tor
  service:
    name=tor
    state=stopped

Tweak the system

Some configs need to be set in order to run a tor relay. Feel free to adapt those to your likings.

- name: update limits
  pam_limits:
    domain=*
    limit_type=-
    limit_item=nofile
    value=120000

- name: set nic buffer size
  shell: /sbin/ifconfig eth0 txqueuelen 20000
  become: true

- name: set configs permanent
  lineinfile:
    dest=/etc/rc.local
    regexp="^/sbin/ifconfig eth0 txqueuelen 20000$"
    line="/sbin/ifconfig eth0 txqueuelen 20000"
    insertbefore="^exit 0$"
  become: true

- name: set sysctl settings 1/6
  sysctl:
    name=vm.min_free_kbytes
    value=16384
    state=present

- name: set sysctl settings 2/6
  sysctl:
    name=net.netfilter.nf_conntrack_max
    value=1000000
    state=present

- name: set sysctl settings 3/6
  sysctl:
    name=net.core.rmem_max
    value=26214400
    state=present

- name: set sysctl settings 4/6
  sysctl:
    name=net.core.wmem_max
    value=26214400
    state=present

- name: set sysctl settings 5/6
  sysctl:
    name=net.core.rmem_default
    value=26214400
    state=present

- name: set sysctl settings 6/6
  sysctl:
    name=net.core.wmem_default
    value=26214400
    state=present

Setup tor

Finally create the tasks that will setup tor and start it.

- name: set rights
  file: dest=/var/lib/tor owner=debian-tor recurse=yes

- name: stat logrotate for tor
  stat: path=/etc/logrotate.d/tor
  register: logrotate_stat

- name: disable logrotate for tor
  command: mv /etc/logrotate.d/tor /etc/logrotate.d/tor.disabled
  when: logrotate_stat.stat.exists
  become: true

- name: setup torrc
  template:
    src=/tmp/torrc.j2
    dest=/etc/tor/torrc
  become: true

- name: enable tor
  service:
    name=tor
    enabled=yes

- name: start tor
  service:
    name=tor
    state=restarted

The jinja template used for the torrc file is the following and has to be saved in a file named /tmp/torrc.j2 (it is referenced in the above setup torrc task):

Log notice file /var/log/tor/notices.log
RunAsDaemon 1
ControlPort 9051
ORPort {{ torport }}
DirPort {{ dirport }}
Nickname {{ nodename }}
ExitPolicy reject *:* # no exits allowed
User debian-tor
DisableDebuggerAttachment 0
AvoidDiskWrites 1
SocksPort 0

For more information on the different options used on your tor relay, see the official doc and the FAQ.

Running the playbook

Now it's time to actually execute this playbook so that all the above defined tasks will be applied on the Raspberry Pi.

Copy your public ssh key to your Raspberry Pi:

$ ssh-copy-id pi@<rpi-IP>

And make sure you're able to ssh to your Raspberry Pi with your key.

create the inventory file:

$ echo '[rpitor]' > /tmp/torpi.hosts
$ echo '<rpi-IP>' >> /tmp/torpi.hosts

and then run the playbook:

$ ansible-playbook -u pi -i /tmp/torpi.hosts rpitor.yml

You can of course run the same playbook multiple times since ansible provides idempotency (running multiple times will end up with the same result).

Final steps

Now you can reboot your Raspberry Pi to make sure you're running the latest kernel.

Also make sure you opened the needed ports on your firewall, torport and dirport set in the rpitor.yml file.

In order to monitor your tor relay, you can use the arm tool: sudo -u debian-tor arm.

Once your relay is running, you can get information about your relay on atlas.