Chroot se refiere a "change root", es decir, cambiar la raíz del
sistema de ficheros para que las llamadas al sistema se hagan desde esa
nueva raíz y los procesos no puedan ganar privilegios.
Las ventaja de usar chroot es clara como el agua, simplemente ganamos
seguridad, si comprometen a Apache no comprometen al sistema entero,
pensad en los CGI y el peligro potencial que encierran de tener acceso
por algún "bug" a vuestros sistemas de ficheros...
Otra ventaja clara es tener todo el entorno en una sola zona fácil de
mover y administrar, backup's,. etc.
Las desventajas:
Que es bastante más complejo de configurar si usamos PHP,
Perl...y solo se puede realizar si todo el árbol web puede existir bajo
un solo sistema de ficheros.
Una vez entrados en materia vamos a ver paso a paso como "enjaular" al apache:
1)Instalamos apache, ya sea desde las fuentes o el binario, como
es lógico debemos elegir el último Apache con el último nivel de
parcheo.
2)Configuramos que Apache se ejecute con su propio usuario y grupo, para esto lo creamos con el siguiente comando:
1.groupadd apache
2.useradd -c “Apache Server” -d /dev/null -g apache -s /bin/false apache
Estos comandos crean el usuario apache y el grupo apache,
el servidor apache en principio se ejecuta como nobody, este usario se
usa en muchos otros procesos por lo que si este en concreto es
comprometido, el intruso podría ganar acceso a todos los procesos que
se ejecuten bajo ese ID.
3)Creamos el árbol chroot:
#mkdir /chroot/httpd
#mkdir /chroot/httpd/dev
#mkdir /chroot/httpd/lib
#mkdir /chroot/httpd/etc
#mkdir -p /chroot/http/usr/sbin
#mkdir /chroot/httpd/usr/lib
#mkdir /chroot/httpd/usr/libexec
#mkdir -p /chroot/httpd/var/run
#mkdir -p /chroot/httpd/var/log/apache
#mkdir -p /chroot/httpd/home/httpd
Después asignamos los permisos a la estructura de directorios:
#chown -R root /chroot/httpd
#chmod -R 0755 /chroot/httpd
#chmod 750 /chroot/httpd/var/log/apache/
La estructura que usemos puede ser variada dependiendo de las
aplicaciones, usos, etc. Estas cuestiones son de vital importancia
puesto que hay que incluir las librerias que utilizan estas
aplicaciones para la ejecución correcta del entorno.
Una vez creados los directorios necesarios, crearemos el dispositivo null.
#mknod /chroot/httpd/dev/null c 1 3
#chown root.sys /chroot/httpd/dev/null
#chmod 666 /chroot/httpd/dev/null
Necesitamos el dispositivo null ya que apache una vez enjaulado
ve el directorio /chroot/httpd como si fuese el /, por lo que no puede
acceder al /dev/null o /var/log (por ejemplo).
Copiamos los ficheros necesarios:
Si hemos migrado de una instalación de Apache normal a una bajo
chroot tendremos que copiar los ficheros que nos serán necesarios para
arrancar Apache en su nuevo entorno. En primer lugar “bajamos” el
apache con killall httpd.
Copiamos los ficheros de configuración con el comando:
#cp -r /etc/apache /chroot/httpd/etc
Luego copiamos el DocumentRoot? y los CGI's:
#cp -r /home/httpd/html /chroot/httpd/home/httpd
#cp -r /home/httpd/cgi-bin /chroot/httpd/home/httpd
Ahora copiamos los binarios del demonio :-P “httpd” y si usamos los scripts de apache también.
#cp /usr/sbin/httpd /chroot/usr/sbin/
#cp /usr/sbin/apache* /chroot/usr/sbin
ATENCION:
Si usamos ssl hay que copiar el directorio /etc/ssl también, con el comando:
#cp -a /etc/ssl /chroot/httpd/etc
Debemos copiar de igual modo todos los módulos de nuestra instalación original.
#cp -r /usr/libexec/apache /chroot/httpd/usr/libexec/
Una vez copiado apache y el ssl si fuera necesario necesitamos
copiar todas las librerias compartidas que necesita nuestro servidor
web para funcionar. Para saber que librerias necesitamos ejecutamos el
comando:
#ldd /chroot/httpd/usr/sbin/httpd
Nos devolverá algo parecido a esto.
linux-gate.so.1 => (0xffffe000)
libpcreposix.so.0 => /usr/lib/libpcreposix.so.0 (0xb7f2d000)
libpcre.so.0 => /lib/libpcre.so.0 (0xb7eff000)
libaprutil-0.so.0 => /usr/lib/libaprutil-0.so.0 (0xb7ee9000)
libldap-2.3.so.0 => /usr/lib/libldap-2.3.so.0 (0xb7eb4000)
libnsl.so.1 => /lib/libnsl.so.1 (0xb7ea0000)
libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0xb7e89000)
libresolv.so.2 => /lib/libresolv.so.2 (0xb7e77000)
libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0xb7e46000)
libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0xb7d3c000)
liblber-2.3.so.0 => /usr/lib/liblber-2.3.so.0 (0xb7d30000)
libgdbm.so.3 => /usr/lib/libgdbm.so.3 (0xb7d2a000)
libdb-4.2.so => /usr/lib/libdb-4.2.so (0xb7c4b000)
libexpat.so.0 => /usr/lib/libexpat.so.0 (0xb7c2b000)
libapr-0.so.0 => /usr/lib/libapr-0.so.0 (0xb7c09000)
librt.so.1 => /lib/tls/librt.so.1 (0xb7c00000)
libm.so.6 => /lib/tls/libm.so.6 (0xb7bdb000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0xb7bad000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7b9a000)
libdl.so.2 => /lib/libdl.so.2 (0xb7b96000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7a68000)
/lib/ld-linux.so.2 (0xb7f43000)
La salida dependerá de como se compiló el apache para
generar el binario , tendremos que copiar los diferentes ficheros en
sus respectivos directorios en el chroot.
....
..
.
#cp /lib/libpcre.so.0 /chroot/httpd/lib/
#cp /lib/libm* /chroot/httpd/lib/
#cp /lib/libcrypt* /chroot/httpd/lib/
#cp /lib/libdb* /chroot/httpd/lib/
.
..
...
Asi lo hacemos con todos los ficheros que necesitamos en el chroot.
Estas librerias son necesarias para que apache tenga algunas
funcionalidades stándart en red y hay que añadirlas
también.
#cp /lib/libnss_compat* /chroot/httpd/lib/
#cp /lib/libnss_dns* /chroot/httpd/lib/
#cp /lib/libnss_files* /chroot/httpd/lib/
#cp /lib/libnsl* /chroot/httpd/lib/
Los ficheros de configuración del chroot en /chroot/httpd/etc
Para que el apache funcione correctamente necesitamos algunos
ficheros de /etc. Primero editamos los ficheros /etc/passwd y el
/etc/group, estos deben contener solo las entradas para el usuario y
grupo Apache.
Por ejemplo:
/etc/passwd:
apache:x:12347:12348:Apache Server:/dev/null:/bin/false
/etc/group:
apache:x:12347:
Necesitaremos algunos ficheros de configuración más:
#cp /etc/hosts /chroot/httpd/etc/
#cp /etc/host.conf /chroot/httpd/etc/
#cp /etc/resolv.conf /chroot/httpd/etc/
#cp /etc/nsswitch.conf /chroot/httpd/etc/
Para más seguridad podemos asignar el “bit inmutable” a estos ficheros.
#chattr +i /chroot/httpd/etc/hosts
#chattr +i /chroot/httpd/etc/host.conf
#chattr +i /chroot/httpd/etc/resolv.conf
#chattr +i /chroot/httpd/etc/nsswitch.conf
#chattr +i /chroot/httpd/etc/passwd
#chattr +i /chroot/httpd/etc/group
Para que se escriban en el log los eventos con la hora correcta
copiaremos el fichero /etc/localtime a /chroot/httpd/etc/localtime
Por defecto el demonio de syslogd escribe sólo en /var/log, el
demonio httpd en chroot escribirá en /chroot/httpd/var/log, tendremos
que decirle al syslogd que monitorice este directorio también. Para
cambiar esto tenemos que editar el script /etc/rc.d/rc.syslog o
/etc/rc.d/init.d/syslog dependiendo de la distribución.
Para /etc/rc.d/init.d/rc.syslog hay que cambiar el demonio syslogd -m 0 a sylogd -m 0 -a /chroot/httpd/dev/log.
Para /etc/rc.d/rc.syslog cambiar:
echo -n “ /usr/sbin/syslogd” /usr/sbin/syslogd
a
echo -n “ /usr/sbin/syslogd” /usr/sbin/syslogd -m 0 -a chroot/httpd/dev/log
Creamos los ficheros de log necesarios:
#touch /chroot/httpd/var/log/apache/access_log
#touch /chroot/httpd/var/log/apache/error_log
#chmod 600 /chroot/httpd/var/log/apache/*
#chattr +a /chroot/httpd/var/log/apache/*
Finalmente necesitamos cambiar el script de inicio al chroot. Dependiendo de la distribución tendremos que editar:
/etc/rc.d/rc.httpd o /etc/rc.d/init.d/httpd y cambiar el comando
que arranca el httpd para leer /usr/sbin/chroot /chroot/httpd/
/usr/sbin/httpd.
Ya hemos finalizado el chroot para el demonio de Apache.
Si algo va mal un comando muy útil es “strace”, con el comando:
#strace chroot /chroot/httpd /usr/sbin/httpd 2> httpd.strace
Redirigimos la salida al fichero “httpd.strace” para poder revisar a modo de log el problema que esta ocurriendo.
Fin del procedimiento de CHROOT.
Para cualquier mejora o comentario:
elduende@electroduende.org
El artículo es una traducción del original escrito por Mike Peters en http://www.linux.com/article.pl?sid=04/05/24/1450203.