Chrooting a service is a way of limiting a service (or user) environment to only accessing what it should and not gaining access (or information) that could lead to root access. By running the service as another user than root (nobody, apache, named) an attacker can only access files with the permissions of this user. This means that an attacker cannot gain root access even if the services has a security flaw.
Some services like
# emerge -apv www-servers/monkeyd
Once it's installed, files must be copied over to the chroot, and the libraries
that
# ldd /usr/bin/monkey linux-gate.so.1 => (0xffffe000) libpthread.so.0 => /lib/libpthread.so.0 (0xb7eed000) libc.so.6 => /lib/libc.so.6 (0xb7dd9000) /lib/ld-linux.so.2 (0xb7f1e000)
The files that showup with absolute paths must be copied over for the program to work. Let's go ahead and copy them over:
# mkdir /chroot/lib # cp -p /lib/{libpthread.so.0,libc.so.6,ld-linux.so.2} /chroot/lib/
Now that the dynamic libraries are copied over, the actual files that the program uses must be copied over as well. This includes things such as configuration files and server modules. To help eleviate the stress of going through and finding every single file a program needs, I've created this simple script which uses equery to copy over the needed files:
#!/bin/bash for files in $(equery -q -C files $1 | grep "^\/" | grep -v "\.d") do if [ ! -e $2${files} ] ; then if [ -d ${files} ] ; then echo "Creating directory $2${files}..." mkdir -p $2${files} else echo "Copying over file $2${files}..." cp -p ${files} $2${files} fi fi done
This script takes 2 arguments. The first is the name of the package, and the
second is the location to the chroot (without the leading slash). Here is an
example output using
# chroot_setup.sh www-servers/monkeyd /chroot Creating directory /chroot/etc... Creating directory /chroot/etc/monkeyd... Copying over file /chroot/etc/monkeyd/modules.conf... Copying over file /chroot/etc/monkeyd/monkey.conf... Copying over file /chroot/etc/monkeyd/monkey.mime... Creating directory /chroot/usr... Creating directory /chroot/usr/bin... Copying over file /chroot/usr/bin/monkey... Creating directory /chroot/usr/lib... Creating directory /chroot/usr/lib/debug... Creating directory /chroot/usr/lib/debug/usr... Creating directory /chroot/usr/lib/debug/usr/bin... Creating directory /chroot/usr/share... Creating directory /chroot/usr/share/doc... Creating directory /chroot/usr/share/doc/monkeyd-0.9.1... Copying over file /chroot/usr/share/doc/monkeyd-0.9.1/ChangeLog.txt.gz... Copying over file /chroot/usr/share/doc/monkeyd-0.9.1/HowItWorks.txt.gz... Copying over file /chroot/usr/share/doc/monkeyd-0.9.1/MODULES.gz... Copying over file /chroot/usr/share/doc/monkeyd-0.9.1/README.gz... Creating directory /chroot/var... Creating directory /chroot/var/log... Creating directory /chroot/var/log/monkeyd... Creating directory /chroot/var/www... Creating directory /chroot/var/www/localhost... Creating directory /chroot/var/www/localhost/cgi-bin... Copying over file /chroot/var/www/localhost/cgi-bin/test.pl... Creating directory /chroot/var/www/localhost/htdocs... Creating directory /chroot/var/www/localhost/htdocs/docs... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.en.html... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.es.html... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.fr.html... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.pt-br.html... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.ru.html... Copying over file /chroot/var/www/localhost/htdocs/docs/monkey+php.sv.html... Creating directory /chroot/var/www/localhost/htdocs/imgs... Copying over file /chroot/var/www/localhost/htdocs/imgs/logonooficial.jpg... Copying over file /chroot/var/www/localhost/htdocs/imgs/titulo.jpg... Copying over file /chroot/var/www/localhost/htdocs/index-monkey.html... Creating directory /chroot/var/www/localhost/htdocs/php... Copying over file /chroot/var/www/localhost/htdocs/php/index.php...
Now that the environment is setup, the init.d script must be adjusted to handle the chroot environment. Here is an example change I made to the monkeyd init.d file to handle this:
- /usr/bin/monkey -D &> /dev/null + chroot /chroot /usr/bin/monkey -D &> /dev/null - start-stop-daemon --stop --quiet --pidfile ${MONKEY_PID} + start-stop-daemon --stop --quiet --pidfile /chroot/${MONKEY_PID} - rm -f ${MONKEY_PID} + rm -f /chroot/${MONKEY_PID}
However, when attempting to start monkeyd, the service fails. In order to find
out why,
# strace -o strace.log chroot /chroot/ /usr/bin/monkey(problem file) unlink("/var/run/monkey.pid") = -1 ENOENT (No such file or directory) open("/var/run/monkey.pid", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No such file or directory) write(1, "Error: I can\'t log pid of monkey"..., 33) = 33
So in order to fix this, we create the appropriate /var/run directory:
# mkdir -p /chroot/var/run
There were a couple of other files missing, all of them I transfered over as shown here:
# cp -p /etc/nsswitch.conf /chroot/etc/ # cp -p /etc/passwd /chroot/etc/ # cp -p /etc/group /chroot/etc/ # cp -p /lib/libnss_compat.so.2 /chroot/lib/ # cp -p /usr/lib/libnsl.so /chroot/usr/lib/libnsl.so.1 # cp -p /usr/lib/libnss_nis.so /chroot/lib/libnss_nis.so.2 # cp -p /usr/lib/libnss_files.so /chroot/lib/libnss_nis.so.2 # cp -p /lib/libgcc_s.so.1 /chroot/lib/
And now that the problematic files are handled, go ahead and start the init.d script:
# /etc/init.d/monkeyd start * Starting monkeyd ... [ ok ]
And just to make sure:
# ps aux | grep monkey nobody 24007 0.0 0.0 1684 572 ? Ss 01:55 0:00 /usr/bin/monkey -D root 24009 0.0 0.1 2664 752 pts/2 R+ 01:55 0:00 grep monkey # wget http://localhost:2001/index-monkey.html --02:11:29-- http://localhost:2001/index-monkey.html => `index-monkey.html' Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:2001... connected. HTTP request sent, awaiting response... 200 OK Length: 2,610 (2.5K) [text/html] 100%[==========================================================================================================================>] 2,610 --.--K/s 02:11:29 (49.78 MB/s) - `index-monkey.html' saved [2610/2610]
And to be extra safe, verify that the init.d script can stop the service as well:
# /etc/init.d/monkeyd stop * Stopping monkeyd ... [ ok ]
And that's it! You've now setup your chroot'ed service.
Another way of creating a more secure environment is by running a virtual machine. A virtual machine, as the name implies, is a process that runs on top of your real operating system providing a hardware and operating system environment that appears to be its own unique machine. The security benefit is that if the server running on the virtual machine is compromised, only the virtual server is affected and not the parent installation.
For more information about how to setup User Mode Linux consult the