Lighttpd sobre chroot con php5 en Debian 6

Bueno, últimamente me ha dado por enjaular un servidor web que tenemos en Antares, y me topado con algunas cosas que los how-to’s que hay por ahí no comentan.

Enjaular (chrootear) el servidor web, sirve para que si de alguna forma alguien rompe / hackea el servidor web, no pueda acceder al resto del servidor. Se queda encerrado dentro de lo que es el servidor web. Para ello se ejecuta el servidor web dentro de una estructura de directorios aparte y sin capacidad de ver el resto del entorno del servidor.

Obviamente, no recomiendo seguir este proceso si solo necesitas el servidor web para hacer chorradas / pruebas. Esto es más si va a dejar un servidor web medio serio y la maquina tiene algún otro servicio aparte de la web que no quieras que te tiren.

Paso 1: Instalar lighttpd y php5

Habiendo logeado en la maquina y habiendo ejecutdo su root para entrar en modo superusuario, hay que instalar los paquetes lighttpd php5 php5-cgi php5-cli :

# apt-get install lighttpd php5-cgi php5-cli 

Nota: Si necesitas otros módulos php como php-gd, php-mysql, php-psql , etc… Se instalan igual

Paso 2:Preparar el sistema de ficheros

Creamos un directorio llamado /webroot:

# mkdir /webroot

Creamos un subdirectoio tmp :

# mkdir /webroot/tmp/
# chmod 1777 /webroot/tmp/

Creamos un directorio /etc para almacenar los ficheros de configuración necesarios:

# mkdir /webroot/etc

Crear un directorio de logs para lighttpd:

# mkdir -p /webroot/var/log/lighttpd
# chown www-data:www-data /webroot/var/log/lighttpd

Crear el directorio de cahce para lighttpd:

# mkdir -p /webroot/var/cache/lighttpd/compress/
# chown www-data:www-data /webroot/var/cache/lighttpd/compress/

Crear un directorio home para lighttpd:
# mkdir -p /webroot/home/lighttpd
# chown www-data:www-data /webroot/home/lighttpd
# chmod 0700 /webroot/home/lighttpd
# ls -dl /webroot/home/lighttpd
Debería de salir algo como t:

drwx------  2 www-data www-data 4096 Oct  5 23:15 /webroot/home/lighttpd

Este script (l2chroot) es útil para copiar las librerías compartidas del sistema a la jaula:

# wget http://www.cyberciti.biz/files/lighttpd/l2chroot.txt
# mv l2chroot.txt l2chroot
# cp l2chroot /bin # chmod +x /bin/l2chroot

Paso 3: Enjaulando PHP

Ahora toca copiar los ejecutables de PHP, extensiones y los ficheros que necestian (php-gd, php-psql, etc…) al directorio /webroot :

# mkdir -p /webroot/usr/bin
# cp /usr/bin/php5-cgi /webroot/usr/bin/
# cp /usr/bin/php5 /webroot/usr/bin/

Copiamos /etc/php5/cgi/php.ini al directorio /webroot/etc/  :

# cd /webroot/etc/
# cp -avr /etc/php5 .

Ahora copiamos otros ficheros de configuración a la jaula:

# cp /etc/hosts /webroot/etc/
# cp /etc/nsswitch.conf /webroot/etc/
# cp /etc/resolv.conf /webroot/etc/
# cp /etc/services /webroot/etc/
# cp /etc/localtime /webroot/etc/

Copiamos las librerías compartidas de PHP con el script de antes :
# /bin/l2chroot /usr/bin/php5
# /bin/l2chroot /usr/bin/php5-cgi

Ahora tenemos todas las librerias compartidas necesarias para PHP en el directorio de la jaula. Podemos verificar esto usando el comando ls. Peero aun así, es necesario copiar otro fichero mas de forma manual  – /lib/ld-linux.so.2:
# cp /lib/ld-linux.so.2 /webroot/lib

Paso 4: Metiendo las extensiones de PHP en la jaula

Para ver los ficheros que contiene una extensión, usamos dpkg para listar los ficheros del paquete que los instalo.
Copy php mysql extension from /usr/lib/php4/20050606 directory, use following command to determine exact location of mysql.so file:

# dpkg -L php5-gd
/.
/etc
/etc/php5
/etc/php5/conf.d
/etc/php5/conf.d/gd.ini
/usr
/usr/lib
/usr/lib/php5
/usr/lib/php5/20090626+lfs
/usr/lib/php5/20090626+lfs/gd.so
/usr/share
/usr/share/doc
/usr/share/doc/php5-gd

Copiamos los ficheros *.so de las extensiones de /usr/lib/php5/un_numero/loquesea.so a /webroot/usr/lib/php5/el_mismo_numero/loquesea.so y ficheros relacionasdo con el script l2chroot:

# mkdir -p /webroot/usr/lib/php5/20090626+lfs
# cp /usr/lib/php5/20090626+lfs/gd.so /webroot/usr/lib/php5/20090626+lfs/
# /bin/l2chroot /usr/lib/php5/20090626+lfs/gd.so

Repetimos el proceso con todas los módulos de PHP que queramos.

Paso 5: Configurar lighttpd para que se ejecute en la jaula

Primeros nos aseguramos que el modulo fastcgi este funcionando con:

# lighty-enable-mod fastcgi

Mostrando:

Available modules: auth cgi cml fastcgi proxy simple-vhost ssi ssl trigger-b4-dl userdir
Already enabled modules:
Enabling fastcgi: ok
Run /etc/init.d/lighttpd force-reload to enable changes

Configuramos lighttpd editando /etc/lighttpd/lighttpd.conf file:
# vim /etc/lighttpd/lighttpd.conf

The most importat part is server.chroot directive. Open config file:
# vim /etc/lighttpd/lighttpd.conf
Descomentamos / editamos la linea con server.chroot :
server.chroot = "/webroot"

Y además descomentamos o editamos la linea con server-document-root a :
server.document-root       = "/home/lighttpd"

Con la directiva server.chroot , hacemos que ningún usuario (exceptuando el root claro) ejecutando lighttpd dentro de webroot, pueda acceder a directorios fuera, ergo, efectivamente enjaulando el servidor web y el php.

Finalmente editamos un script del sistema para que lanze el modulo fastcgi correctamente. Editamos el fichero /etc/lighttpd/conf-enabled/10-fastcgi.conf y añadimos estas lineas  :

## Start an FastCGI server for php5 (needs the php5-cgi package)
fastcgi.server    = ( ".php" =>
((
"bin-path" => "/usr/bin/php5-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 2,
"idle-timeout" => 20,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)

Ahora para iniciar el servidor web hacemos :

# /etc/init.d/lighttpd start   (o restart si ya estaba funcionando previamente)

Finalmente para testear que todo va bien, dentro de /webroot/home/lighttpd/, creamos un fichero llamado test.php y copiamos dentro :

<?php
phpinfo();
?>

Ahora desde el navegador, accedemos a nuestra dirección y si todo va bien, deberíamos de tener una típica pagina de información sobre la configuración de PHP en nuestra maquina.

Si se tiene algún problema, o no funciona el servidor, se puede consultar los logs con tail /webroot/var/log/lighttpd/error.log . Si la información mostrada no es suficiente, se puede ejecutar el servidor a mano con #lighttpd -f /etc/lighttpd/lighttpd.conf -D para que muestre más información.

Fuentes :