negative zero

Using Multiple Tor Circuits

2019 September 15

[privacy] [tech] [tor] [tutorial]


This guide assumes you're using SystemD. Here, we will set up multiple Tor circuits we can connect to simultaneously on different ports.

The configuration settings for Tor are stored in /etc/tor/. As we can see from /etc/tor/README

Multiple instances of Tor can be run simultaneously using different configuration files. For example, tor@custom.service will use the configuration file "/etc/tor/custom.torrc".

The README file also explains how to do this. I wanted to add multiple instances, so I wrote a script to automate it for a given name and port number. The example used in the README had the name "custom" and used port 9051. I wrote the following script, which I called add-tor-process:

#!/bin/sh
if [ $EUID -ne 0 ]; then
	echo "Please run as root."
	exit
fi

name=""
port=""

while getopts 'n:p:' f
do
	case $f in
		n) name=$OPTARG ;;
		p) port=$OPTARG ;;
	esac
done

if [[ "$name" == "" || "$port" == "" ]]; then
	echo "Usage: add-tor-process -n name -p port"
	exit
fi

touch /etc/tor/$name.torrc
echo "SOCKSPort $port" >> /etc/tor/$name.torrc
echo "dataDirectory /var/lib/tor/$name" >> /etc/tor/$name.torrc
mkdir /var/lib/tor/$name
chown toranon:root /var/lib/tor/$name

This script must be run as root because it needs to create files and directories in locations owned by root. We also need to ensure there is a name and a port for each run.

I already had an SELinux rule to allow Tor connections on port 9051, but if you use SELinux, you'll need to add rules for other ports, or it will prevent you from running Tor proxies on those ports. I added the following line to my script:

semanage port -a -t tor_port_t -p tcp $port

Finally, I wanted a script which would (re)start all Tor circuits with a single command. I called this script start-tor and put it in the same directory:

#!/bin/sh
if [ $EUID -ne 0 ]; then
	echo "Please run as root."
	exit
fi
systemctl restart tor.service

Then I added a line to the end of my add-tor-process script:

echo "systemctl restart tor@$name.service" >> /etc/tor/start-tor

Now, when I run add-tor-process to add a new process, it will automatically add that process to the start-tor script so that I can have my computer (re)start all the Tor circuits. (I can, of course, still start or restart them individually.)

Here's my full add-tor-process script:

#!/bin/sh
if [ $EUID -ne 0 ]; then
	echo "Please run as root."
	exit
fi

name=""
port=""

while getopts 'n:p:' f
do
	case $f in
		n) name=$OPTARG ;;
		p) port=$OPTARG ;;
	esac
done

if [[ "$name" == "" || "$port" == "" ]]; then
	echo "Usage: add-tor-process -n name -p port"
	exit
fi

touch /etc/tor/$name.torrc
echo "SOCKSPort $port" >> /etc/tor/$name.torrc
echo "dataDirectory /var/lib/tor/$name" >> /etc/tor/$name.torrc
mkdir /var/lib/tor/$name
chown toranon:root /var/lib/tor/$name
semanage port -a -t tor_port_t -p tcp $port
echo "systemctl restart tor@$name.service" >> /etc/tor/start-tor
echo "Done"

To add a new Tor circuit, I can run (for example, a process called "process" on port 9055):

sudo ./add-tor-process -n process -p 9055