This document describes setting up Tor in a linux chroot environment. It has been tested with:

but should work on any linux distribution.

It will explain the compilation, installation and configuration of Tor on a linux-system. It will result in a Tor-Installation which will be run in a chroot-environment by the special user tor. The homefolder of this user will be /home/tor and the path of the chroot-environment will be /home/tor/chroot. Tor itself will be installed to /home/tor/chroot/tor and its configuration-file will be in /home/tor/chroot/tor/etc/tor/torrc.

This so installed Tor will be able to work as a Tor-client and/or server.


First you need to get a copy of the latest Source tarballs of Tor and unpack it:

gpg tor-
tar -xzvf tor-

Now you can configure and compile it:

cd tor-
./configure --prefix=/tor

Next you should create a special user which will later run the tor process. On debian or debian-based distributions you can create the user with:

sudo adduser --disabled-login --gecos "Tor user,,," tor

On other distributions with other adduser implementations the above could fail. If so you can take a look at the man-page of your adduser command or use the low-level useradd command to create it:

sudo useradd -d /home/tor -s /bin/false tor

After that we move the compiled tor-version to the chroot-directory:

sudo mkdir -p $TORCHROOT
sudo make install prefix=$TORCHROOT/tor exec_prefix=$TORCHROOT/tor


Shared libraries

We need to copy all libraries which tor needs into the chroot-environment. Tor needs libevent which might be available in your distribution with the packages: libevent1 and libevent-dev or just libevent. If it's not available for your distribution compile it from source: . If you have the libevent go on to copy over the required libraries:

sudo mkdir $TORCHROOT/lib
sudo cp `ldd $TORCHROOT/tor/bin/tor | awk '{print $3}'|grep "^/"` $TORCHROOT/lib
sudo cp /lib/libnss* /lib/libnsl* /lib/ /lib/libresolv* /usr/lib/ /usr/lib/* $TORCHROOT/lib

On Ubuntu is in /lib and depending on your hardware architecture may be in /lib64

sudo cp /lib/* $TORCHROOT/lib
sudo mkdir $TORCHROOT/lib64
sudo cp /lib64/ $TORCHROOT/lib64/

Device nodes

Tor needs access to /dev/(u)random and /dev/null if run as a daemon so you need to create them in the chroot-environment:

sudo mkdir $TORCHROOT/dev
sudo mknod -m 644 $TORCHROOT/dev/random c 1 8
sudo mknod -m 644 $TORCHROOT/dev/urandom c 1 9
sudo mknod -m 666 $TORCHROOT/dev/null c 1 3

Configuration files

Now some files which are needed by some functions are copied into the chroot-environment:

sudo mkdir $TORCHROOT/etc
sudo sh -c "grep ^tor /etc/passwd > $TORCHROOT/etc/passwd"
sudo sh -c "grep ^tor /etc/group > $TORCHROOT/etc/group"
sudo cp /etc/nsswitch.conf /etc/host.conf /etc/resolv.conf /etc/hosts $TORCHROOT/etc
sudo cp /etc/localtime $TORCHROOT/etc


We need to copy a tor-configuration-skeleton on its place in the chroot:

sudo cp $TORCHROOT/tor/etc/tor/torrc.sample $TORCHROOT/tor/etc/tor/torrc

(Tor will look for this file in various places based on your platform:

Since chroot needs to be run as root, but Tor does not we configure Tor to drop its privileges after start. With adding the following line into the $TORCHROOT/tor/etc/tor/torrc file:

User tor

we tell Tor to drop its privileges to the user with the name tor. We also have to enable the data-directory explicitly:

DataDirectory /var/lib/tor2

tell Tor where to look for 'geoip' for ip-to-country lookups:

GeoIPFile /tor/share/tor/geoip

and should configure the Pid-and Log-file:

PidFile /var/run/tor/
Log notice file /var/log/tor/log

These directories need to be created and owned by the user who shall run Tor:

sudo mkdir -p $TORCHROOT/var/run/tor
sudo mkdir -p $TORCHROOT/var/lib/tor
sudo mkdir -p $TORCHROOT/var/lib/tor2
sudo mkdir -p $TORCHROOT/var/log/tor
sudo chown tor:tor $TORCHROOT/var/run/tor
sudo chown tor:tor $TORCHROOT/var/lib/tor
sudo chown tor:tor $TORCHROOT/var/lib/tor2
sudo chown tor:tor $TORCHROOT/var/log/tor


You are now ready with setting up a Tor-Installation in a chroot environment and can start that tor-instance with:

sudo chroot $TORCHROOT /tor/bin/tor

This should produce the following output:

Apr 10 11:42:22.466 [notice] Tor v0.2.0.35 . This is experimental software. Do not rely on it for strong anonymity. (Running on Linux i686)
Apr 10 11:42:22.477 [notice] Initialized libevent version 1.4.8-stable using method epoll. Good.
Apr 10 11:42:22.479 [notice] Opening Socks listener on

You can abort it now again with pressing CTRL+c on your keyboard. As last advice you should add:

RunAsDaemon 1

to your Tor-configuration. This is specially needed by some of the following init-Scripts.

You are now finished and can configure your tor-chroot installation in the file /home/tor/chroot/tor/etc/tor/torrc like setting it up as a relay and so..

Starting on boot

This part is quite distribution specific, but modifications to the given init-scripts should be applicable to other Linux distributions and *nix operating systems.

Here are init-scripts which allow it easily to start the tor-chroot installation on boot.


See the following article for a quick and easy setup in ArchLinux:

The below guide for ArchLinux is outdated; ArchLinux no longer uses initscripts and now uses systemd More info here:

Move the following file to /etc/rc.d/ and give it a name you like, e.g.: tor-chroot. After that you can start and stop tor with:

sudo /etc/rc.d/tor-chroot start|stop|restart

To make it autostart on boottime add tor-chroot to the DAEMONS list in your /etc/rc.conf.



. /etc/rc.conf
. /etc/rc.d/functions

# Relative to TORCHROOT:

PID=`pidof -o %PPID $TORPATH`
case "$1" in
		stat_busy "Starting Tor Daemon"
		[ -z "$PID" ] && /usr/sbin/chroot $TORCHROOT $TORPATH &>/dev/null
		if [ $? -gt 0 ]; then
			add_daemon tor
		stat_busy "Stopping Tor Daemon"
		[ ! -z "$PID" ] && kill $PID &> /dev/null
		if [ $? -gt 0 ]; then
			rm_daemon tor
		$0 stop
		sleep 3
		$0 start
		echo "usage: $0 {start|stop|restart}"
exit 0
# vim: ft=sh ts=2 sw=2

CentOS 6.4 x86_64 Chroot Setup

Install tor from the repos:

yum install tor 

Use the following script to setup the chroot (for browser mode):

# modified from:
export TORCHROOT=/opt/torchroot

mkdir -p $TORCHROOT
mkdir -p $TORCHROOT/etc/tor
mkdir -p $TORCHROOT/dev
mkdir -p $TORCHROOT/usr/bin
mkdir -p $TORCHROOT/usr/lib64
mkdir -p $TORCHROOT/var/lib

cp /etc/hosts           $TORCHROOT/etc/
cp /etc/host.conf       $TORCHROOT/etc/
cp /etc/localtime       $TORCHROOT/etc/
cp /etc/nsswitch.conf   $TORCHROOT/etc/
cp /etc/resolv.conf     $TORCHROOT/etc/
cp /etc/tor/torrc       $TORCHROOT/etc/tor/
sed -i 's/^#*\(DataDirectory \/var\/lib\/tor\)/\1/g' $TORCHROOT/etc/tor/torrc

cp /usr/bin/tor         $TORCHROOT/usr/bin/

ln -s /usr/lib64 $TORCHROOT/lib64
for F in $(ldd  -r /usr/bin/tor | awk '{print $3}'|grep --color=never "^/" | sed 's/^.*\(\/lib[0-9]*\/[a-z]*\).*/\/usr\1*/g'); do   /bin/cp -f ${F}  $TORCHROOT/${F%/*}/.  ;  done

/bin/cp -f /lib64/*     /lib64/*     /lib64/libnss*     /lib64/libnsl*     /lib64/libresolv*      $TORCHROOT/lib64/
/bin/cp -f /usr/lib64/* /usr/lib64/* /usr/lib64/libnss* /usr/lib64/libnsl* /usr/lib64/libresolv*  $TORCHROOT/usr/lib64/
/bin/cp -f /usr/lib64/libssl* /usr/lib64/libcrypto* /usr/lib64/libevent* $TORCHROOT/usr/lib64/

cp -r /var/lib/tor      $TORCHROOT/var/lib/
chown -R toranon:toranon $TORCHROOT/var/lib/tor

sh -c "grep --color=never ^tor /etc/passwd > $TORCHROOT/etc/passwd"
sh -c "grep --color=never ^tor /etc/group > $TORCHROOT/etc/group"

mknod -m 644 $TORCHROOT/dev/random c 1 8
mknod -m 644 $TORCHROOT/dev/urandom c 1 9
mknod -m 666 $TORCHROOT/dev/null c 1 3

Execute in the chroot environment with:

chroot --userspec=toranon:toranon /opt/torchroot  /usr/bin/tor


This downloads some modifications to Debian's official Tor init script and a small wrapper which will perform the chroot. The scripts are not on the wiki so that they are not maliciously modified:

sudo wget -O /etc/init.d/tor
sudo wget -O /etc/default/tor
sudo wget -O $TORCHROOT/tor/bin/tor-chroot
sudo chmod 755 /etc/init.d/tor /etc/default/tor $TORCHROOT/tor/bin/tor-chroot

After that you can start and stop tor with:

sudo /etc/init.d/tor start|stop|restart|reload|force-reload

Running update-rc.d will set up the start and stop links in the correct runlevel directories to make it autostart while booting:

sudo update-rc.d tor defaults 19

Updating Tor

If a new version of Tor is released and you want to update your Tor-Installation in the chroot just do the following. Download the new version and unpack it. After that you need to configure it the same way you did with the first installation and compile it:

./configure --prefix=/tor

And now you just have to install it to the correct place:

sudo make install prefix=$TORCHROOT/tor exec_prefix=$TORCHROOT/tor

That's it.

Final Notes

  • Presumably torify will be run outside of the chroot, but its config file location is set to be relative to the chroot by ./configure. I can't think of any neat way to fix this.
  • The library situation is a bit fragile. There may be some other libraries, like libnss_compat which don't show up in ldd but are required. The above has been tested for running as client and server and should work with them for the given tor-version. Later tor-versions may need other files and libraries.
  • If you put shared libraries outside of /lib and /usr/lib you need to set LD_LIBRARY_PATH, but sudo drops the LD* environment variables for security reasons. If you want to put libraries in, say /tor/lib, you need something like: sudo su -c "export LD_LIBRARY_PATH=/tor/lib; chroot $TORCHROOT /local/bin/tor"
  • An alternate approach to LD_LIBRARY_PATH for configuring non-default library locations is to setup etc/ and etc/ in the chroot tree, include sbin/ldconfig and run chroot $TORCHROOT /sbin/ldconfig -v in order to generate etc/ The dynamic linker utilizes for locating libraries. This is helpful when tor is built from source then installed under /usr/local and a desire to mimic the locations of parent system files in the chroot tree exists.
  • Minimalists may observe via lsof that is not loaded in the active tor program image and be tempted to omit it, but note that this library is dynamically loaded by pthread_exit() from when tor rotates keys and restarts once each week. Without the tor process may terminate with SIGABRT and the relay state may be lost. Successful operation is tested by issuing pkill -HUP tor when tor is running to induce an immediate restart.
Last modified 6 months ago Last modified on Oct 23, 2013 6:32:52 AM