Changes between Version 50 and Version 51 of doc/OpenbsdChrootedTor
- Timestamp:
- Mar 1, 2018, 4:38:47 AM (12 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
doc/OpenbsdChrootedTor
v50 v51 4 4 5 5 == Running Tor in a chroot under OpenBSD == 6 7 6 We have taken the instructions on the Tor Project wiki as a starting point, and have adapted them to suit OpenBSD. We assume basic Unix shell skills and some familiarity with using OpenBSD; the FAQs and man pages are highly recommended. 8 7 … … 10 9 11 10 = Preliminaries = 12 13 11 = Filesystem = 14 15 12 From the mount(8) man page: 16 13 17 nodev Do not interpret character or block special devices on 18 the file system. This option is useful for a server 19 that has file systems containing special devices for 20 architectures other than its own. 14 ` 21 15 22 The installer marks fstab entries for partitions created during installation as nodev by default; only the root filesystem, where /dev lives, is not. This presents a problem for Tor in a chroot, because Tor needs to use three device special files: /dev/random, /dev/urandom and /dev/null. The usual way of making device files available in a chroot is to use the mknod(8) command in the chroot, but if the chroot lives on a filesystem mounted nodev (likely under OpenBSD) this will not work as expected when Tor tries to use the device. 16 nodev Do not interpret character or block special devices on[[BR]] the file system. This option is useful for a server[[BR]] that has file systems containing special devices for[[BR]] architectures other than its own. 17 18 ` The installer marks fstab entries for partitions created during installation as nodev by default; only the root filesystem, where /dev lives, is not. This presents a problem for Tor in a chroot, because Tor needs to use three device special files: /dev/random, /dev/urandom and /dev/null. The usual way of making device files available in a chroot is to use the mknod(8) command in the chroot, but if the chroot lives on a filesystem mounted nodev (likely under OpenBSD) this will not work as expected when Tor tries to use the device. 23 19 24 20 A discussion of disk partitioning and configuration is beyond the scope of this document. The FAQ on Disk Partitioning in the Installer has links to the relevant documentation. If you wish to make a small partition available for use as a chroot area this is where to start. … … 26 22 For our purposes here we will take another approach: create a small filesystem stored in a regular user file and mount it without the nodev option. The vnconfig(8) command is the key. Let's start by being careful and looking at what, if any files have been attached to vnd(4) devices: 27 23 28 $ doas vnconfig -l 29 vnd0: covering /home/me/something/file.img on sd0k, inode 4783121 30 vnd1: not in use 31 vnd2: not in use 32 vnd3: not in use 24 $ doas vnconfig -l[[BR]] vnd0: covering /home/me/something/file.img on sd0k, inode 4783121[[BR]] vnd1: not in use[[BR]] vnd2: not in use[[BR]] vnd3: not in use 33 25 34 26 A couple important points: 35 27 36 37 38 28 * by default there are four vnd devices configured; 29 * if one is in use and you vnconfig it again it is overwritten, so you need to know which ones are not in use; 30 * nothing in the system will use a vnd device by default. 39 31 40 32 In the above example vnd0 is already in use. This means we should use vnd1 for the chroot; we'll use vnd1 for the rest of this document to stay consistent, but the point is: use an unused vnd device for the chroot filesystem. … … 42 34 First, prepare a file to hold the disk image and attach it as vnd1: 43 35 44 $ dd if=/dev/zero of=chroot.img bs=1m count=50 45 $ doas vnconfig vnd1 chroot.img 36 $ dd if=/dev/zero of=chroot.img bs=1m count=50 $ doas vnconfig vnd1 chroot.img 46 37 47 38 Next, use disklabel(8) to add a partition of the right type that takes up all of the virtual disk; for simplicity we use the interactive editor (-E option); in the transcript below user input is entered after the > prompt: 48 39 49 $ doas disklabel -E vnd1 50 Label editor (enter '?' for help at any prompt) 51 > a a 52 offset: [0] 53 size: [102400] 54 FS type: [4.2BSD] 55 > w 56 > q 57 No label changes. 40 $ doas disklabel -E vnd1 [[BR]]Label editor (enter '?' for help at any prompt)[[BR]]> a a[[BR]]offset: [0][[BR]]size: [102400][[BR]]FS type: [4.2BSD] [[BR]]>w[[BR]]>q [[BR]]No label changes. 58 41 59 42 Finally, create a filesystem on the partition we just created (/dev/vnd1a): 60 43 61 44 $ doas newfs /dev/rvnd1a 62 45 63 46 At this point you can mount /dev/vnd1a somewhere in your filesystem and use it for the chroot; we will mount it under /home/tor/chroot below. Once you are done using the chroot (no Tor process running anymore), you can do the following to clean up: 64 47 65 $ doas umount /home/tor/chroot 66 $ doas vnconfig -u vnd1 48 $ doas umount /home/tor/chroot[[BR]]$ doas vnconfig -u vnd1 67 49 68 50 == Ports Tree == 69 70 51 We assume you have the ports tree unpacked under /usr/ports. Read the anoncvs documentation and follow its instructions for getting a copy of the ports tree. 71 52 … … 75 56 76 57 == Basic Chroot Setup == 77 78 58 There are several elements that must be taken into account: 79 59 80 81 82 83 84 60 * shared libraries; 61 * the password database; 62 * device nodes; 63 * directory structure and ownership; 64 * Tor software and configuration. 85 65 86 66 First off, set an environment variable to point at the base directory of the chroot. We use this everywhere in subsequent commands: 87 67 88 68 $ TORCHROOT=/home/tor/chroot 89 69 90 70 Note that this only sets this variable in your current shell. If you switch terminals or shells then you'll have to set it again. … … 92 72 Add a “tor” user and home directory: 93 73 94 $ doas useradd -d /home/tor -s /sbin/nologin tor 95 $ doas mkdir /home/tor 96 $ doas chown tor:tor /home/tor 74 $ doas useradd -d /home/tor -s /sbin/nologin tor[[BR]]$ doas mkdir /home/tor[[BR]]$ doas chown tor:tor /home/tor 97 75 98 76 Mount our little filesystem under /home/tor/chroot: 99 77 100 $ doas mkdir /home/tor/chroot 101 $ doas chown tor:tor /home/tor/chroot 102 $ mount /dev/vnd1a /home/tor/chroot 78 $ doas mkdir /home/tor/chroot[[BR]]$ doas chown tor:tor /home/tor/chroot[[BR]]$ mount /dev/vnd1a /home/tor/chroot 103 79 104 80 == Compile Tor and Install in Chroot == 105 106 81 We'll now use the ports tree to grab the Tor source code, verify it is the right stuff, unpack it, patch it (if necessary) and build it: 107 82 108 $ cd /usr/ports/net/tor 109 $ env SUDO=doas make 83 $ cd /usr/ports/net/tor[[BR]]$ env SUDO=doas make 110 84 111 85 This will download, verify, extract and patch the tor source code and leave it in a port-specific directory under the ports build area, /usr/ports/pobj. It will also ensure that everything needed to build the port is installed. We set the SUDO environment variable in the make invocation in case any ports on which Tor depends on must be installed prior to building; this tells the ports system to become root at the appropriate times to install pacakges that are created as a by-product of chasing down these dependencies. As of this writing there is only one dependency (libevent) for Tor but as that changes these instructions should remain valid. … … 115 89 Next, we change working directories to the root of the source tree: 116 90 117 $ cd `make show=WRKSRC` 118 $ doas make install prefix=$TORCHROOT exec_prefix=$TORCHROOT sysconfdir=$TORCHROOT/etc 91 $ cd `make show=WRKSRC`[[BR]]$ doas make install prefix=$TORCHROOT exec_prefix=$TORCHROOT sysconfdir=$TORCHROOT/etc 119 92 120 93 The make show=FOO idiom is useful in the ports tree generally; it shows you the full expansion of a make(1) variable used in the port's Makefile. The WRKSRC variable will contain the name of the working source tree directory, which is where we want to go. There is comprehensive documentation on this and the other variables used in ports Makefiles in the bsd.port.mk(5) man page. 121 Shared Libraries 94 95 '''Shared Libraries''' 122 96 123 97 We must deal with shared libraries both for the tor binary and for a system utility that we will copy into the chroot, pwd_mkdb(8). We also need ldconfig(8) in the chroot: 124 98 125 $ doas mkdir $TORCHROOT/sbin 126 $ doas cp /sbin/ldconfig $TORCHROOT/sbin 127 $ doas mkdir -p $TORCHROOT/usr/sbin 128 $ doas cp /usr/sbin/pwd_mkdb $TORCHROOT/usr/sbin 99 $ doas mkdir $TORCHROOT/sbin[[BR]]$ doas cp /sbin/ldconfig $TORCHROOT/sbin[[BR]]$ doas mkdir -p $TORCHROOT/usr/sbin [[BR]]$ doas cp /usr/sbin/pwd_mkdb $TORCHROOT/usr/sbin 129 100 130 101 We must copy all shared libraries that both pwd_mkdb and tor need into the right places under the chroot. We define a shell function called shlibpaths to make the commands easier to type: 131 102 132 $ shlibpaths () { 133 ldd $1 | sed -e 1,3d | awk '{print substr($7,2)}' 134 } 135 $ tar -C / -cf - `shlibpaths $TORCHROOT/bin/tor` | doas tar -C $TORCHROOT -xf - 136 $ tar -C / -cf - `shlibpaths $TORCHROOT/usr/sbin/pwd_mkdb` | doas tar -C $TORCHROOT -xf - 103 $ shlibpaths () { 104 ldd $1 | sed -e 1,3d | awk '{print substr($7,2)}' 105 } [[BR]]$ tar -C / -cf - `shlibpaths $TORCHROOT/bin/tor` | doas tar -C $TORCHROOT -xf -[[BR]]$ tar -C / -cf - `shlibpaths $TORCHROOT/usr/sbin/pwd_mkdb` | doas tar -C $TORCHROOT -xf - 137 106 138 107 The shlibpaths function works like so: 139 108 140 ldd(1) spits out the raw list of shared libraries; 141 sed(1) removes the first three lines of output, which are noise for our purposes; 142 awk(1) pulls out the seventh whitespace-separated column and prints all but the first character, making the path to the shared library relative to root. 109 ldd(1) spits out the raw list of shared libraries;[[BR]]sed(1) removes the first three lines of output, which are noise for our purposes;[[BR]]awk(1) pulls out the seventh whitespace-separated column and prints all but the first character, making the path to the shared library relative to root. 143 110 144 111 The -C option to tar(1) tells tar to change directories to the given place before doing anything else. In both cases the tar command at the head of the pipe packs up the shared libraries in question and the tar command at the tail of the pipe unpacks them under the chroot. … … 146 113 Now all the shared libraries that tor and pwd_mkdb depend on are in $TORCHROOT/usr/lib and $TORCHROOT/usr/local/lib. We must now run ldconfig in the chroot to set up the /var/run/ld.so.hints file: 147 114 148 $ doas mkdir -p $TORCHROOT/var/run 149 $ doas chroot $TORCHROOT /sbin/ldconfig /usr/lib /usr/local/lib 115 $ doas mkdir -p $TORCHROOT/var/run $ doas chroot $TORCHROOT /sbin/ldconfig /usr/lib /usr/local/lib 150 116 151 117 Now that we have pwd_mkdb usable in the chroot, set up a minimal password database: 152 118 153 $ doas sh -c "grep ^tor /etc/passwd > $TORCHROOT/etc/passwd" 154 $ doas sh -c "grep ^tor /etc/group > $TORCHROOT/etc/group" 155 $ doas sh -c "grep ^tor /etc/master.passwd > $TORCHROOT/etc/master.passwd" 156 $ doas sh -c "grep ^_shadow /etc/group >> $TORCHROOT/etc/group" 157 $ doas chroot $TORCHROOT /usr/sbin/pwd_mkdb /etc/master.passwd 119 $ doas sh -c "grep ^ tor /etc/passwd > $TORCHROOT/etc/passwd"[[BR]]$ doas sh -c "grep ^ tor /etc/group > $TORCHROOT/etc/group"[[BR]]$ doas sh -c "grep ^ tor /etc/master.passwd > $TORCHROOT/etc/master.passwd"[[BR]]$ doas sh -c "grep ^ _shadow /etc/group >> $TORCHROOT/etc/group"[[BR]]$ doas chroot $TORCHROOT /usr/sbin/pwd_mkdb /etc/master.passwd 158 120 159 121 Set up device nodes that Tor needs: 160 122 161 $ doas mkdir $TORCHROOT/dev 162 $ doas mknod -m 644 $TORCHROOT/dev/random c 45 0 163 $ doas mknod -m 644 $TORCHROOT/dev/urandom c 45 2 164 $ doas mknod -m 666 $TORCHROOT/dev/null c 2 2 123 $ doas mkdir $TORCHROOT/dev[[BR]]$ doas mknod -m 644 $TORCHROOT/dev/random c 45 0[[BR]]$ doas mknod -m 644 $TORCHROOT/dev/urandom c 45 2[[BR]]$ doas mknod -m 666 $TORCHROOT/dev/null c 2 2 165 124 166 125 At this point the software and basic system configuration in the chroot is complete. 167 126 168 127 == Configure Tor == 169 170 128 Create a minimal Tor configuration in the chroot: 171 129 172 $ doas sh -c "cat > $TORCHROOT/etc/tor/torrc" 173 User tor 174 DataDirectory /var/lib/tor 175 GeoIPFile /share/tor/geoip 176 PidFile /var/run/tor/tor.pid 177 Log notice file /var/log/tor/log 178 ^D 130 $ doas sh -c "cat > $TORCHROOT/etc/tor/torrc" [[BR]]User tor[[BR]]DataDirectory /var/lib/tor[[BR]]GeoIPFile /share/tor/geoip[[BR]]PidFile /var/run/tor/tor.pid[[BR]]Log notice file /var/log/tor/log[[BR]]^!^D^ 179 131 180 132 Create the run-time directories needed by tor and make sure they are owned by the tor user and have the right permissions: 181 133 182 $ doas mkdir -p $TORCHROOT/var/run/tor 183 $ doas mkdir -p $TORCHROOT/var/lib/tor 184 $ doas chmod 700 $TORCHROOT/var/lib/tor 185 $ doas mkdir -p $TORCHROOT/var/log/tor 186 $ doas chown tor:tor $TORCHROOT/var/run/tor 187 $ doas chown tor:tor $TORCHROOT/var/lib/tor 188 $ doas chown tor:tor $TORCHROOT/var/log/tor 134 $ doas mkdir -p $TORCHROOT/var/run/tor[[BR]]$ doas mkdir -p $TORCHROOT/var/lib/tor[[BR]]$ doas chmod 700 $TORCHROOT/var/lib/tor[[BR]]$ doas mkdir -p $TORCHROOT/var/log/tor[[BR]]$ doas chown tor:tor $TORCHROOT/var/run/tor[[BR]]$ doas chown tor:tor $TORCHROOT/var/lib/tor[[BR]]$ doas chown tor:tor $TORCHROOT/var/log/tor 189 135 190 136 == Start Tor == 191 192 137 Finally, you should be able to start Tor in the chroot: 193 138 194 139 $ doas chroot $TORCHROOT /bin/tor 195 140 196 141 This should produce output that looks something like: 197 142 198 Oct 04 16:46:55.116 [notice] Tor 0.3.0.10 (git-c33db290a9d8d0f9) running on OpenBSD with Libevent 2.0.22-stable, OpenSSL LibreSSL 2.6.3 and Zlib 1.2.3. 199 Oct 04 16:46:55.116 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning 200 Oct 04 16:46:55.126 [notice] Read configuration file "/etc/tor/torrc". 201 Oct 04 16:46:55.192 [notice] Opening Socks listener on 127.0.0.1:9050 143 Oct 04 16:46:55.116 [notice] Tor 0.3.0.10 (git-c33db290a9d8d0f9) running on OpenBSD with Libevent 2.0.22-stable, OpenSSL LibreSSL 2.6.3 and Zlib 1.2.3.[[BR]]Oct 04 16:46:55.116 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning [[BR]]Oct 04 16:46:55.126 [notice] Read configuration file "/etc/tor/torrc".[[BR]]Oct 04 16:46:55.192 [notice] Opening Socks listener on 127.0.0.1:9050 202 144 203 145 It will also produce a verbose log of its operation in $TORCHROOT/var/log/tor/log. 204 146 205 You can interrupt Tor when run this way by pressing ^C. If you want Tor to fork into the background and run as a daemon, add one more line to your torrc file: 147 You can interrupt Tor when run this way by pressing ^C. If you want Tor to fork into the background and run as a daemon, add one more line to your torrc file:^ 206 148 207 $ doas sh -c "echo RunAsDaemon1 >> $TORCHROOT/etc/tor/torrc"149 $ doas sh -c "echo RunAsDaemon 1 >> $TORCHROOT/etc/tor/torrc" 208 150 209 151 If you start Tor with the above command after adding that line it will start silently and continue running. To shut it down use the PidFile we configured above: 210 152 211 $ doas sh -c "kill `cat $TORCHROOT/var/run/tor/tor.pid`"153 $ doas sh -c "kill `cat $TORCHROOT/var/run/tor/tor.pid` " 212 154 213 155 At this point your chroot'ed Tor installation is working and listening for SOCKS connections on port 9050. 214