Search

Recent

Tags

Django chroot, securing your web application hosting

Filed under tips & tricks, security, Python on jun 03, 2010

For me the best way to run Django applications has proven to be mod_wsgi and Apache. This setup allows for scalable application pools to run as a seperate process, featuring threading and extra privilege separation, which is great.

To make your application even more hardened, you can use the mod_wsgi chroot feature, as discussed in this thread. This will make mod_wsgi do a chroot to the application jail before spawning the Python application. This ensures your application doesn’t have access to other parts of the filesystem but its own jail.

If you wish to still be able to use uploads, make sure you have a (world) writable /tmp directory in your chroot jail. You can use techniques like bind mounts if you want to expose parts of the file system in your jail.

Setting up the chroot

Your application has to be able to access the Python libraries from within the jail. There are several ways to setup your chroot, I just used ldd and some guessing. Note that copying the Python binary by itself is not mandatory, however I do find it convenient to be able to access the Python interpreter from within the jail.

~# mkdir /home/chroot/hosting{,etc,dev,usr,usr/bin,usr/lib,lib,tmp}
~# export CHROOT=/home/chroot/hosting
~# cd $CHROOT
hosting# alias CP='rsync -a'
hosting# $CP /usr/bin/python $CHROOT/usr/bin/
hosting# ldd $CHROOT/usr/bin/python | grep '=> /' | awk '{print $3}' | while read LIB; do
> mkdir $CHROOT/$(dirname $LIB)
> $CP $LIB $CHROOT/$LIB
> done
hosting# mknod $CHROOT/dev/null c 1 3
hosting# mknod $CHROOT/dev/zero c 1 5
hosting# echo "hosting" > $CHROOT/etc/hostname
hosting# grep ^demo /etc/passwd > $CHROOT/etc/passwd
hosting# grep ^demo /etc/group > $CHROOT/etc/group
hosting# chmod --reference=/tmp $CHROOT/tmp

Installing Python

Next we have to copy the Python library files:

hosting# mkdir -p $CHROOT/usr/lib
hosting# $CP /usr/lib/python2.6 $CHROOT/usr/lib/

Finally, install Django in your chroot. In my Ubuntu environment, the site-packages directory is called dist-packages, you can find out what directory to use by asking the distutils package:

hosting# python -c 'from distutils import sysconfig; print sysconfig.get_python_lib(0)'
/usr/lib/python2.6/dist-packages

Now extract Django in the appropriate path:

hosting# curl http://href.be/3 | tar -C /tmp -xf -
hosting# mv /tmp/Django-1.2.1/django $CHROOT/usr/lib/python2.6/dist-packages
hosting# rm -rf /tmp/Django-1.2.1

Setting up the application

Now you can setup your application as you normally would, except you will be using /home/chroot/hosting as base directory. To tell mod_wsgi to use the chroot jail, you can use a configuration like this:

<VirtualHost *:80>
  ServerName demo1.example.org

  WSGIDaemonProcess demo-1 user=demo1 group=demo1 display-name=%{GROUP} chroot=/home/chroot/hosting
  WSGIScriptAlias / /home/chroot/hosting/demo1/application/apache.py

  Alias /media/ /home/chroot/hosting/demo1/media/
</VirtualHost>

Python in the chroot

You can use the chroot(8) utility to switch to Python within the chroot environment. This can be of great use when debugging.

~$ sudo chroot /home/chroot/hosting /usr/bin/python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print os.listdir('/')
['tmp', 'usr', 'bin', 'dev', 'demo1', 'demo2', 'etc']

Nota Bene

Make sure you have set up the permissions correctly in your jail. If the project is owner by user demo1, you can make a seperate account demo1-www that runs the application in mod_wsgi. In this way, the application can not modify parts of the code.

Add to

Post your feedback

You can use this form to leave your feedback. Your insights are always appreciated.

Tools

View document source in text/plain