Apache Chroot · 4 min read · Dec 26, 2025

Chrooting Apache 2.4 con mod_unixd en Debian 8 (Jessie)

Esta guía explica cómo configurar mod_unixd con Apache 2.4 en un sistema Debian Jessie. Con mod_unixd, puedes ejecutar Apache en un entorno chroot seguro y hacer que tu servidor sea menos vulnerable a intentos de intrusión que intentan explotar vulnerabilidades en Apache o en tus aplicaciones web instaladas. El módulo mod_unixd es un reemplazo para el módulo mod_chroot, que se utilizaba en el antiguo apache 2.2.

1 Nota Preliminar

Asumo que tienes un sistema Debian 8 en funcionamiento con un Apache operativo, por ejemplo, como se muestra en este tutorial: Tutorial del servidor LAMP Debian 8 Jessie con Apache 2, PHP 5 y MariaDB. Además, asumo que tienes uno o más sitios web configurados dentro del directorio /var/www (por ejemplo, si usas ISPConfig).

El servidor que utilizo aquí tiene la dirección IP 192.168.1.100 y el nombre de host server1.example.com. Por favor, reemplaza estos valores con la dirección IP y el nombre de host de tu servidor dondequiera que aparezcan en el tutorial.

2 Configurando Apache

El módulo de apache mod_unixd que ofrece la función Chroot en Apache 2.4 es parte de los módulos centrales de Apache y está compilado estáticamente en el binario de Apache en Debian 8, por lo que no tenemos que instalar software adicional para usarlo.

Quiero usar el directorio /var/www como el directorio que contiene la cárcel chroot. El Apache de Debian utiliza el archivo PID /var/run/apache2.pid; cuando Apache está chrooted a /var/www, /var/run/apache2.pid se traduce a /var/www/var/run/apache2.pid. Por lo tanto, creamos ese directorio ahora:

mkdir -p /var/www/var/run  
chown -R root:root /var/www/var/run

Ahora debemos decirle a Apache que queremos usar /var/www como nuestro directorio chroot. Abrimos /etc/apache2/apache2.conf, y justo debajo de la línea PidFile, agregamos una línea ChrootDir:

nano /etc/apache2/apache2.conf
[...]
#
# PidFile: El archivo en el que el servidor debe registrar su número de identificación de proceso cuando se inicia.
# Esto debe establecerse en /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}
ChrootDir /var/www
[...]

A continuación, debemos decirle a nuestros vhosts que la raíz del documento ha cambiado (por ejemplo, un DocumentRoot /var/www se traduce ahora a DocumentRoot /). Podemos hacer esto cambiando la directiva DocumentRoot de cada vhost, o más fácil, creando un symlink en el sistema de archivos.


2.1 Primer Método: Cambiando el DocumentRoot

Supongamos que tenemos un vhost con DocumentRoot /var/www. Ahora debemos abrir la configuración del vhost de ese vhost y cambiar DocumentRoot /var/www a DocumentRoot /. En consecuencia, DocumentRoot /var/www/web1/web ahora se traduciría a DocumentRoot /web1/web, y así sucesivamente. Si deseas usar este método, debes cambiar el DocumentRoot para cada vhost individual.

2.2 Segundo Método: Creando Un Symlink En el Sistema de Archivos

Este método es más fácil, porque solo tienes que hacerlo una vez y no tienes que modificar ninguna configuración de vhost. Creamos un symlink apuntando de /var/www/var/www a /var/www:

mkdir -p /var/www/var  
cd /var/www/var  
ln -s ../../ www

Finalmente, debemos detener Apache, crear un symlink de /var/run/apache2.pid a /var/www/var/run/apache2.pid, y volver a iniciarlo:

service apache2 stop
ln -s /var/www/var/run/apache2.pid /var/run/apache2.pid  
service apache2 start

Eso es todo. Ahora puedes llamar a tus páginas web como antes, y deberían servirse sin problemas, siempre que sean archivos HTML estáticos o usen mod_php.

Voy a probar esto ahora con una página phpinfo(). Abre un nuevo archivo info.php con nano en la raíz del documento del sitio web predeterminado:

nano /var/www/html/info.php

y agrega el siguiente contenido:

Guarda el archivo y abre el nombre de host de tu servidor o la dirección IP en el navegador, seguido de /info.php. Ejemplo:

http://192.168.1.100/info.php

La siguiente página debería aparecer ahora cuando PHP esté funcionando correctamente:

Página de información de PHP.

Hasta ahora todo bien, pero ¿cómo sabemos si Apache realmente está chrooted? Intentemos acceder a un archivo que está fuera del chroot, usaré /etc/hosts aquí como ejemplo.

nano /var/www/html/testchroot.php

con este contenido:

' . $var;

y abre la URL del archivo de prueba en un navegador. El resultado es:

Prueba Chroot

Como puedes ver, el contenido del archivo /etc/hosts ya no se puede acceder desde este script PHP.

Elimina los archivos de prueba si no los necesitas más:

rm /var/www/html/testchroot.php  
rm /var/www/html/info.php

Si estás usando CGI, por ejemplo, Perl, Ruby, etc., entonces debes copiar el intérprete (por ejemplo, /usr/bin/perl, etc.) a la cárcel chroot junto con todas las bibliotecas necesarias por el intérprete. Puedes averiguar sobre las bibliotecas requeridas con el comando ldd, por ejemplo.

ldd /usr/bin/perl
root@server1:/var/www/html# ldd /usr/bin/perl  
linux-vdso.so.1 (0x00007ffe951f4000)  
libperl.so.5.20 => /usr/lib/x86_64-linux-gnu/libperl.so.5.20 (0x00007f1dafe54000)  
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1dafc50000)  
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1daf94f000)  
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1daf732000)  
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1daf387000)  
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f1daf150000)  
/lib64/ld-linux-x86-64.so.2 (0x00007f1db0214000)  
root@server1:/var/www/html#

o usar las herramientas jailkit para construir el entorno de la cárcel. Si has copiado todos los archivos requeridos, pero la página aún no funciona, deberías echar un vistazo al registro de errores de Apache /var/log/apache2/error.log. Por lo general, te dice dónde está el problema.

3 Enlaces

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.