Version 15 (modified by trac, 10 years ago) (diff)


## Copyright (c) 2004 Steven J. Murdoch. ## Distributed under the MIT license, ## See ./LegalStuff for a full text [:../:up to Tor]

The documentation for Tor suggests running it in a chroot but I have not found this to be entirely trivial and I couldn't find any documentation on how to achieve this.

This document describes how I set up Tor to run in a chroot on Debian GNU/Linux 3.0 (Woody) with a 2.4.18 Debian kernel, but it should be applicable to other Tor versions and most of it will be the same for other Linux distributions. The original version of these instructions was posted on the or-dev mailing list.


Unpacking and compilation

gpg tor-
tar -xzvf tor-
cd tor-
umask 022
./configure --prefix=/tor

The prefix at the configure stage is the one used at runtime, so should be set relative to the chroot. I didn't use / as the prefix since that would result in the hard-coded paths starting with // which should work under *nix, but IIRC they break in Windows. For example, in the torrc.sample file you would have the following line: RouterFile //etc/tor/dirservers.

Copying files

sudo adduser --disabled-login --gecos "Tor user,,," tor
sudo mkdir $TORCHROOT
sudo make install prefix=$TORCHROOT/tor exec_prefix=$TORCHROOT/tor

I firstly created a new user for the purposes of running Tor. Running the install within the chroot would be difficult since I would need to install a shell and other commands the makefile used, so I ran it outside, but set the install-time prefix to be different than the runtime prefix. I had to set both prefix and exec_prefix because the Makefile had exec_prefix hard-coded.

System setup

Shared libraries

ldd $TORCHROOT/tor/bin/tor
sudo mkdir $TORCHROOT/lib
sudo cp /usr/lib/ /usr/lib/ \
 /lib/ /lib/ /lib/ $TORCHROOT/lib
sudo cp /lib/libnss* /lib/libnsl* /lib/libresolv* /usr/lib/ $TORCHROOT/lib

I used ldd to find out which shared libraries were needed, and copied them over to $TORCHROOT/lib. To keep things simple, I put libraries in /lib since /lib and /usr/lib are hardcoded into the Linux dynamic linker. If you put them in other places then you will need to set LD_LIBRARY_PATH (see notes). The libraries libnss* and libnsl* were not listed in the ldd output, but if they are not included then getpwnam() and gethostbyname() will fail.

From Tor 0.0.9 libz is needed so you should also copy over /usr/lib/, but I haven't tried this myself yet.

Device nodes

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

Tor needed access to /dev/(u)random so I created these. Also /dev/null is needed if Tor is run as a daemon.

Configuration files

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
sudo mkdirhier $TORCHROOT/var/run

switch_id() calls getpwnam() which needs /etc/group and /etc/passwd so I copied these over too. Also getpwnam() and gethostbyname() needs nsswitch.conf /etc/host.conf, /etc/resolv.conf, /etc/hosts and access to /var/run. To get the timezone correct /etc/localtime is needed.

Tor configuration

sudo cp $TORCHROOT/tor/etc/tor/torrc.sample $TORCHROOT/tor/etc/tor/torrc
sudo sh -c "echo -e 'User tor\nGroup tor' >> \

Since chroot needs to be run as root, but Tor does not, I set the config file to switch UID/GID on startup. `


sudo chroot $TORCHROOT /tor/bin/tor

which produced the following output:

Oct 16 22:17:34.243 [notice] tor_init(): Tor v0.0.8.1.\ This is experimental software. Do not use it if you need anonymity. Oct 16 22:17:34.345 [notice] add_single_log():\ Successfully opened LogFile '/var/log/tor/log', redirecting output.

Starting on boot

This part is quite Debian specific, but modifications to it should be applicable to other Linux distributions and *nix operating systems.

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
sudo update-rc.d tor defaults 19
sudo /etc/init.d/tor start

This downloads my modifications to Peter Palfrader's Debian 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. Running update-rc.d will set up the start and stop links in the correct runlevel directories.

Setting up as a server

sudo mkdirhier $TORCHROOT/var/lib/tor
sudo chown tor.tor $TORCHROOT/var/lib/tor

# Set up server details, including the data directory:
# "DataDirectory /var/lib/tor"
sudo vim $TORCHROOT/tor/etc/tor/torrc

sudo /etc/init.d/tor restart

This creates the data directory and ensures it is owned by the tor user. The default location in the torrc.sample is inside the install prefix, unlike the log and pidfile locations so I change this to be /var/lib/tor. You will also have to set up the other server configuration options (Nickname, Address, ORPort, ORBindAddress, ExitPolicy). Then mail the file $TORCHROOT/var/lib/tor/fingerprint as described in configuring a server.


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. Also there may be other files required that I haven't copied into the chroot. I have tested it as a client and it seems to work OK, but I haven't tried it as a server yet.

Anchor(ldpath)? 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"

-- Steven J. Murdoch