Setting up a chrooted Apache server with makejail on Debian Woody

$Revision: 1.8 $
$Date: 2003/08/29 07:56:20 $

Introduction

The chroot utility is often used to jail a daemon in a restricted tree. You can use it to insulate services from one another, so that security issues in a software package do not jeoparize the whole server. When using the makejail script, setting up and updating the chrooted tree is much easier.

Licensing

Copyright 2002-2003 Alexandre Ratti. This doc is dual-licensed under the GNU GPL 2 (GNU General Public License) and the GNU FDL 1.2 (GNU Free Documentation License). [Tell me more]

Installing the server

This procedure was tested on Debian GNU/Linux 3.0 (Woody) with makejail 0.0.4-1 (in Debian/testing).

  1. Log in as root and create a new jail directory:

    mkdir -p /var/chroot/apache

  2. Create a new user and a new group. The chrooted Apache server will run as this user/group, which isn't used for anything else on the system. In this example, both user and group are called chrapach.

    adduser --home /var/chroot/apache --shell /bin/false --no-create-home \
    --system --group chrapach


    TODO : I created a system user; it is a good idea?

  3. Install Apache as usual on Debian:

    apt-get install apache

  4. Set up Apache (eg. define your subdomains, etc.). In /etc/apache/httpd.conf, set the User and Group options to chrapach. Then restart Apache and make sure the server is working correctly. Now, stop the Apache daemon.

    User chrapach
    Group chrapach

    /etc/init.d/apache restart
    ...
    /etc/init.d/apache stop

  5. Install makejail (available in Debian/testing for now). You should also also wget et lynx as they are used by makejail to test the chrooted server.

    apt-get install makejail wget lynx

  6. Copy the sample config file for Apache.

    cp /usr/share/doc/makejail/examples/apache.py /etc/makejail.d/

  7. Edit /etc/makejail.d/apache.py. You need to set the chroot, users and groups options. To run this version of makejail, I also added a packages option. See the makejail doc. Here is the content of my file :

    chroot="/var/chroot/apache"
    testCommandsInsideJail=["/usr/sbin/apachectl start"]
    processNames=["apache"]
    testCommandsOutsideJail=["wget -r --spider http://localhost/",
                             "lynx --source https://localhost/"]
    preserve=["/var/www",
              "/var/log/apache",
              "/dev/log"]
    users=["chrapach"]
    groups=["chrapach"]
    packages=["apache", "apache-common"]
    userFiles=["/etc/password",
               "/etc/shadow"]
    groupFiles=["/etc/group",
                "/etc/gshadow"]
    forceCopy=["/etc/hosts",
               "/etc/mime.types"]
    

    TODO: some options do not seem to work properly. For instance, /etc/shadow and/etc/gshadow are not copied, whereas /etc/password et /etc/group are fully copied instead of being filtered.

  8. Create the chroot tree:

    makejail /etc/makejail.d/apache.py

  9. If /etc/password and /etc/group were fully copied, type:

    grep chrapach /etc/passwd > /var/chroot/apache/etc/passwd
    grep chrapach /etc/group > /var/chroot/apache/etc/group


    to replace them with filtered copies.

  10. Copy the Web site pages and the logs into the jail. These files are not copied automatically (see the preserve option in the config file).

    cp -Rp /var/www /var/chroot/apache/var
    cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache

  11. Edit the startup script for the system logging daemon so that it also listen to the /var/chroot/apache/dev/log socket. In /etc/init.d/sysklogd, replace:

    SYSLOGD=""

    with

    SYSLOGD=" -a /var/chroot/apache/dev/log"

    and restart the daemon (/etc/init.d/sysklogd restart).

  12. Edit the Apache startup script (/etc/init.d/apache). I had to hack the default startup script for it to run properly with a chrooted tree. You need to:

    See my file.
    TODO: should the first Apache process be run as another user than root (i.e. add --chuid chrapach:chrapach)? Cons: chrapach will need write access to the logs, which is awkward.

  13. In /etc/logrotate.d/apache, replace

    /var/log/apache/*.log

    with

    /var/chroot/apache/var/log/apache/*.log

  14. Start Apache (/etc/init.d/apache start) and check what is it reported in the jail log (/var/chroot/apache/var/log/apache/error.log). If your setup is more complex, (eg. if you also use PHP and MySQL), files will probably be missing. if some files are not copied automatically by makejail, you can list them in the forceCopy option in /etc/makejail.d/apache.py.

  15. Type "ps aux | grep apache" to make sure Apache is running. You should see:

    root 180 0.0 1.1 2936 1436 ? S 04:03 0:00 /usr/sbin/apache
    chrapach 189 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
    chrapach 190 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
    chrapach 191 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
    chrapach 192 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
    chrapach 193 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache

  16. Make sure the Apache processes are running chrooted :

    ls -la /proc/process_number/root/.

    where process is one of the PID numbers listed above (2nd column; 189 for instance). Entries for a restricted tree should be listed:

    drwxr-sr-x 10 root staff 240 Dec 2 16:06 .
    drwxrwsr-x 4 root staff 72 Dec 2 08:07 ..
    drwxr-xr-x 2 root root 144 Dec 2 16:05 bin
    drwxr-xr-x 2 root root 120 Dec 3 04:03 dev
    drwxr-xr-x 5 root root 408 Dec 3 04:03 etc
    drwxr-xr-x 2 root root 800 Dec 2 16:06 lib
    dr-xr-xr-x 43 root root 0 Dec 3 05:03 proc
    drwxr-xr-x 2 root root 48 Dec 2 16:06 sbin
    drwxr-xr-x 6 root root 144 Dec 2 16:04 usr
    drwxr-xr-x 7 root root 168 Dec 2 16:06 var

    To automate this test, you can type:

    ls -la /proc/`cat /var/chroot/apache/var/run/apache.pid`/root/.

    TODO: other tests that can be run to make sure the jail is closed?

Why I like this script: setting up the jail is not very difficult and the server can be updated in 2 lines:

apt-get update && apt-get install apache
makejail /etc/makejail.d/apache.py

See also


$Id: index-en.html,v 1.8 2003/08/29 07:56:20 alex Exp $
Available at http://www.gabuzomeu.net/alex/doc/apache/index-en.html