$Revision: 1.8 $
$Date: 2003/08/29 07:56:20 $
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.
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]
This procedure was tested on Debian GNU/Linux 3.0 (Woody) with makejail
0.0.4-1 (in Debian/testing).
Log in as root
and create a new jail directory:
mkdir -p /var/chroot/apache
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?
Install Apache as usual on Debian:
apt-get install apache
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
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
Copy the sample config file for Apache.
cp /usr/share/doc/makejail/examples/apache.py /etc/makejail.d/
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.
Create the chroot tree:
makejail /etc/makejail.d/apache.py
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.
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
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
).
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:
CHRDIR
variable at the top of the file;start
, stop
, reload
,
etc. sections;add a line to mount and unmount a/proc
tree within the
jail.
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.
In /etc/logrotate.d/apache
, replace
/var/log/apache/*.log
with
/var/chroot/apache/var/log/apache/*.log
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
.
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
ls -la /proc/process_number/root/.
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
makejail
homepage
(this script was written by Alain Tésio)makejail
, Pascal Brugier, easter-eggs.org, 21/03/2002
$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