por Mark Nielsen (homepage)
Sobre el autor:
Mark trabaja como consultor independiente, dedicando su tiempo a causas
como GNUJobs.com, escribir artículos, escribir software libre, y trabajando
como voluntario en eastmont.net.
Taducido al español por:
Roberto Hernando (homepage)
Contenidos:
|
Chroot de todos los servicios en Linux
Resumen:
Mediante el 'chroot' de los servicios del sistema mejora la seguridad limitando
el daño que un intruso podría causar en el sistema.
Introducción
¿Qué es chroot? Básicamente chroot redefine el universo para un programa.
Más exactamente redefine el directorio raíz o "/" para un programa o una
sesión. Básicamente todo lo que esté fuera del directorio en el que usamos chroot no existe
para el programa o el shell.
¿Por qué esto es útil? Si alguien entra sin autorización en nuestro ordenador,
no será capaz de ver todos los ficheros de nuestro sistema. El no ser capaz
de ver nuestros ficheros limita los comandos que puede utilizar y tampoco
le permite explotar otros ficheros que serían inseguros. El único inconveniente
es que según creo no impide mirar en las conexiones de red y en otras cosas.
Por tanto, tendríamos que hacer algunas cosas más que no se tratan a fondo
en este artículo:
- Asegurar los puertos de red.
- Tener todos los servicios corriendo como un servicio bajo una cuenta
que no sea la de root.
Además, tener todos los servicios con chroot.
- Transferir los logs de sistema a otra máquina.
- Analizar los ficheros de log.
- Analizar intentos de detección aleatoria de puertos en nuestro
ordenador.
- Limitar los recursos de cpu y de memoria para un servicio.
- Activar quotas para las cuentas de usuario.
Por lo que considero chroot (con un servicio no-root) una línea defensiva
es porque si alguien se introduce con una cuenta sin privilegios, y no hay
ficheros que pueda usar para entrar como root, entonces sólo puede
dañar el área al que ha accedido. Además, incluso si el área al que hubiera accedido
fuera propiedad de la cuenta de root, tendría menos posibilidades
para el ataque. Obviamente, hay algo erróneo si alguien tiene la posibilidad
de introducirse con nuestra cuenta, pero está bien ser capaz de limitar el daño
que puede hacer.
POR FAVOR RECUERDE
que mi forma de hacer esto probablemente no sea 100% segura.
Es mi primer intento de hacer esto, y si parece que todo funciona bien
por separado, sería fácil pulir las asperezas. Esto sólo es un boceto para
un HOWTO que quiero hacer sobre chroot.
¿Cómo vamos a hacer chroot a todo?
Bien, creamos un directorio, "/chroot" y colgamos todos
nuestros servicios de ahí como sigue:
- Syslogd será hecho chroot con cada servicio.
- Apache estará en /chroot/httpd.
- Ssh estará en /chroot/sshd.
- PostgreSQL estará en /chroot/postmaster.
- Sendmail será hecho chroot, pero no puede correr
bajo una cuenta sin privilegios, desafortunadamente.
- ntpd será chroot en /chroot/ntpd
- named será chroot en /chroot/named
Cada servicio debería estar completamente aislado.
Mi script Perl para crear entornos chroot.
Config_Chroot.pl.txt se
debe renombrar Config_Chrooot.pl después de descargarlo. Este script
perl permite listar los servicios instalados, ver los ficheros de configuración,
configurar un servicio, e iniciar y parar los servicios. En general, esto es lo
que se debe hacer:
- Crear el directorio chroot.
mkdir -p /chroot/Config/Backup
- Descargar Config_Chroot.pl.txt
en /chroot/Config_Chroot.pl
- Cambiar la variable $Home en el perl script si no se está usando
/chroot como directorio personal.
- Descargar mis ficheros de configuración.
Hay que tener en cuenta que: Sólo lo he probado en
RedHat 7.2 y RedHat 6.2.
Modificar el script perl para nuestra distribución.
Había escrito un artículo gigantesco sobre Chroot, pero con mi script Perl,
se ha vuelto mucho menor. Principalmente, noté después de hacer
chroot a varios servicios que todos ellos tenían ficheros y
configuraciones similares para hacer chroot. La manera más sencilla
de imaginarse qué ficheros es necesario copiar para un servicio particular
es mirar en la página de manual y también escribir "ldd /usr/bin/file" para
los programas que utilizan librerías. También se puede hacer chroot al servicio
que se está instalando e iniciarlo manualmente para ver qué errores
se obtienen o bien mirando los ficheros de log.
Normalmente, para instalar un servicio hay que hacer:
cd /chroot
./Config_Chroot.pl config SERVICIO
./Config_Chroot.pl install SERVICIO
./Config_Chroot.pl start SERVICIO
Haciendo chroot a Ntpd
Ntpd simplemente es un servicio de tiempo que permite mantener
nuestra máquina y otras máquinas sincronizadas en tiempo real. Es
muy fácil hacerle chroot.
cd /chroot
# Descomentar la siguiente línea si no se usa mi fichero de configuración.
#./Config_Chroot.pl config ntpd
./Config_Chroot.pl install ntpd
./Config_Chroot.pl start ntpd
Haciendo chroot a DNS o a named
Ya está hecho, compruébelo
http://www.linuxdoc.org/HOWTO/Chroot-BIND8-HOWTO.html
o
http://www.linuxdoc.org/HOWTO/Chroot-BIND-HOWTO.html
O, si prefiere usar mi script,
cd /chroot
# Descomentar la siguiente línea si no se usa mi fichero de configuración.
#./Config_Chroot.pl config named
./Config_Chroot.pl install named
./Config_Chroot.pl start named
Haciendo chroot a Syslog con servicios y mis quejas.
Quiero hacer chroot a syslogd. Mi problema es que syslogd utiliza
por defecto /dev/log, que no puede ser visto por los servicios con
chroot. Por eso, no he podido hacer chroot a syslogd de una forma
sencilla. Aquí están las posibles soluciones:
- Hacer chroot a syslogd con todos los servicios. Lo estoy probando
actualmente, y sí, he conseguido los log. No me gusta esta forma porque
tengo un servicio funcionando como root.
- Ver si podemos conectarnos a un sitio externo que nos facilite
los logs.
- Enviar los logs a un fichero y no a través de syslogd. Posiblemente
sea la opción más segura, aunque un intruso podría jugar con los logs.
- Configurar el syslogd principal para buscar en varios lugares para
obtener todos los servicios. Se usa la opción -a de syslogd para hacer esto.
Mi única solución para hacer seguro syslogd fue hacerle chroot con todos
los servicios. Querría un tipo de solución en la que se pudiera tener logs
en una cuenta sin privilegios de root usando su propio entorno chroot, como
podría ser un puerto de red. Posiblemente se pueda hacer, pero tengo que
pararme donde estoy y pensar después una solución mejor.
Si no se quiere tener un syslogd separado para cada servicio, con
el syslogd principal que se está ejecutando en nuestro sistema hay que
añadir el siguiente comando cuando syslogd arranque:
syslogd -a /chroot/SERVICIO/dev/log
Si tuviera ssh y dns ejecutándose sería algo así
syslogd -a /chroot/ssh/dev/log -a /chroot/named/dev/log -a /dev/log
Una última nota sobre Syslogd, me gustaría hacerlo correr bajo una cuenta
que no fuera la de root. He intentado un par de cosas sencillas, pero no
han funcionado y me he rendido. Si pudiese correr syslogd bajo una
cuenta distinta de la de root con cualquier servicio, mis propósitos de seguridad
estarían satisfechos. Posiblemente, incluso teniendo los logs en otra máquina.
Haciendo chroot a Apache
Es muy sencillo. Una vez que lo configuré, pude ejecutar scripts Perl. Ahora
mi fichero de configuración es más bien grande porque he tenido que
incluir Perl y las librerías PostgreSQL en el área con chroot. Algo a tener en
cuenta, si nos estamos conectando a una base de datos, debemos asegurar
que nuestro servicio de base de datos está corriendo en el dispositivo de
loopback 127.0.0.1 y especificar que el host es 127.0.0.1 en nuestros
scripts Perl para el módulo DBI. Aquí hay un ejemplo de cómo conectarse
a la base de datos usando conexión persistente en apache:
$dbh = DBI->connect('dbi:Pg:dbname=DATABASE',"","", {PrintError=>0});
if ($dbh ) {$dbh->{PrintError} = 1;}
else
{$dbh = DBI->connect('dbi:Pg:dbname=DATABASE;host=127.0.0.1',"","",
{PrintError=>1});}
Código fuente:
http://httpd.apache.org/dist/httpd/
Hay que compilar e instalar apache en el sistema principal en /usr/local/apache.
Después usar el script perl.
cd /chroot
# Descomente la siguiente línea si no usa mi fichero de configuración
# ./Config_Chroot.pl config httpd
./Config_Chroot.pl install httpd
./Config_Chroot.pl start httpd
He cambiado mi fichero http.conf para que tenga esta apariencia:
ExtendedStatus On
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
<Location /server-info>
SetHandler server-info
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
Ahora, sólo hay que ir a
http://127.0.0.1/server-status
o
http://127.0.0.1/server-info
desde nuestro navegador
y comprobar que funciona.
Haciendo chroot a Ssh
Antes de nada lo ideal sería redirigir el puerto ssh del 22 al 2222.
Después, al arrancar ssh, hay que hacerlo escuchar en el puerto
2222 bajo una cuenta que no sea la de root. Para la conexión ssh
inicial queremos tener cuentas seguras con contraseñas sólo para
permitir la entrada, pero para nada más. Después de entrar, se tiene
un segundo programa ssh corriendo en el puerto 127.0.0.1:2322 con
en el que permitiremos conectarse al sistema real -- el segundo
programa ssh debería escuchar SOLAMENTE en el dispositivo de loopback.
Ahora esto es como yo lo haría. No vamos a hacerlo así. La única cosa que
vamos a hacer es hacer chroot a ssh para este ejemplo. Queda como
ejercicio para el lector poner sshd bajo una cuenta sin privilegios e instalar
un segundo sshd que escuche en el dispositivo de loopback para permitir
a la gente entrar en el sistema real.
Una vez más, téngase en cuenta que sólo vamos a hacer chroot a ssh
y hay que preocuparse sobre las consecuencias de hacer esto (no podremos
ver nuestro sistema por completo si sólo hacemos esto). Además, lo ideal sería
ser capaces de configurarlo para que guarde los logs fuera del sistema. También,
podríamos utilizar OpenSSH, pero estoy usando el SSH comercial por simplicidad
(que no es una buena excusa).
Código fuente:
http://www.ssh.com/products/ssh/download.cfm
Instalar ssh en /usr/local/ssh_chroot. Después usar el script Perl.
cd /chroot
# Descomente la siguiente línea si no usa mi fichero de configuración
# ./Config_Chroot.pl config sshd
./Config_Chroot.pl install sshd
./Config_Chroot.pl start sshd
Supongo que una cosa realmente buena con poner ssh bajo un entorno
con chroot es que si queremos usarlo para reemplazar un servidor ftp,
se tendrá un acceso limitado a nuestro área.
Rsync y SCP van muy bien juntos para permitir a la gente subir ficheros.
No me gusta mucho poner un servidor ftp permitiendo la entrada al
sistema. Muchos servidores ftp también están con chroot, pero
todavía envían las contraseñas en claro, lo que no me gusta.
Haciendo chroot a PostgreSQL
Esto es casi tan simple como perl, excepto que requiere unas cuantas librerías
más. De todas formas, no es muy duro hacerlo. Una cosa que he tenido que
hacer es poner PostgreSQL abierto a la red, pero sólo al dispositivo de loopback.
Desde que se hizo chroot, otros servicios con chroot no podían acceder, como
el servidor web apache. He compilado Perl en PostgreSQL, por lo que he
tenido que añadir muchas cosas de Perl en mi fichero de configuración.
Código fuente:
ftp://ftp.us.postgresql.org/source/v7.1.3/postgresql-7.1.3.tar.gz
Compilar e instalar apache en nuestro sistema principal en /usr/local/postgres.
Después usar el script Perl.
cd /chroot
# Descomente la siguiente línea si no usa mi fichero de configuración
# ./Config_Chroot.pl config postgres
./Config_Chroot.pl install postgres
./Config_Chroot.pl start postgres
Haciendo chroot a Sendmail
Adelante, ejecute mi script.
cd /chroot
# Descomente la siguiente línea si no usa mi fichero de configuración
# ./Config_Chroot.pl config sendmail
./Config_Chroot.pl install sendmail
./Config_Chroot.pl start sendmail
Ahora, ¿hay inconvenientes? Sí. Todavía se está ejecutando como
root. ¡Maldición!
Además, algunos ficheros son creados de nuevo por /etc/rc.d/init.d/sendmail
cuando se inicia. Mi script no controla esto. Cada vez que se hagan cambios
a sendmail bajo /etc/mail, es necesario copiar también esos cambios
en /chroot/sendmail/etc. Se podría enlazar /var/spool/mail a
/chroot/sendmail/var/spool/mail con lo que el programa sendmail
y los usuarios (cuando estén conectados) verían los mismos ficheros.
Lo bueno es que siempre podremos enviar correo, el único problema
es al recibirlo. De este modo, he conseguido instalar sendmail con apache
sin ningún problema. Algunos de mis scripts perl envían correo, y además,
he necesitado los ficheros de sendmail copiados en el área chroot para
apache.
Otras cosas a las que hacer chroot.
Ésta es mi filosofía:
- Todo debería hacerse chroot, incluyendo sendmail, ssh, apache,
postgresql, syslog, y cualquier servicio corriendo en la máquina.
- Todo debería ponerse bajo una cuenta sin privilegios (podría ser necesario
redirigir puertos protegidos a puertos no protegidos). Esto incluye sendmail
y syslog.
- Los logs deberían enviarse a otra máquina.
- Se debería configurar una partición para cada servicio para limitar
el tamaño de disco que un hacker puede usar si decide escribir ficheros.
Se puede usar un dispositivo de loopback para montar ficheros como
sistemas de ficheros para alguno de estos servicios si se han agotado
las particiones.
- Root debería poseer todos los ficheros inmutables.
Ahora, al empezar con sendmail y syslogd, sigo pensando que deberían
ejecutarse bajo una cuenta sin privilegios. Para sendmail esto debería ser
posible, pero he encontrado muchísimas dificultades para ejecutarlo con
una cuenta sin privilegios. No he conseguido ejecutar sendmail con una
cuenta sin privilegios, y pienso que es un grave error. Sé que hay problemas
para hacerlo, pero creo que TODO se puede conseguir. Teniendo en cuenta
los permisos de los ficheros, no veo porqué sendmail necesita ejecutarse como
root. Habrá alguna razón que se me escapa, pero dudo si alguno de los obstaculos
será insalvable.
Para syslog, no lo he intentado, pero diría que los logs deberían ser ejecutados
bajo una cuenta sin privilegios y no sé si esto es posible. Al menos he sido capaz
de conseguir hacer chroot a syslog para cada servicio.
Todos los servicios deberían instalarse con cuentas sin privilegios. Incluso NFS. Todo.
Sugerencias
- Usar 2 logins para ssh y tener corriendo dos demonios sshd.
- Piense cómo conseguir ejecutar sendmail u otro programa de correo con
una cuenta sin privilegios.
- Quitar las librerías innecesarias de /lib. He copiado todo para simplificármelo.
La mayoría no las necesito.
- Conectarse remotamente a syslogd y encontrar si podemos
unir syslogd a un puerto de red y conseguir todos los servicios conectados
a ese puerto de red en el dispositivo de loopback. Ver si podemos tener
syslogd corriendo bajo una cuenta sin privilegios.
Conclusión
Pienso que chroot está bien para todos los servicios. Creo que es
un gran error no hacer chroot de todos los servicios bajo cuentas no-root.
Desearía que lo hicieran las distribuciones grandes, o una distribución pequeña:
CUALQUIER distribución. Mandrake comenzó tomando cosas de RedHat y
extendiéndolas, luego quizás, alguien podría tomar Mandrake y extenderla
mediante chroot. Nada impide que alguien retome el trabajo de otro en GNU/Linux,
por lo que creo que es posible. Si alguna empresa quisiera hacer chroot a
todo y crear un entorno sencillo para controlar los servicios con chroot,
¡harían una distribución fantástica! Recordemos la corriente que ahora
está siguiendo Linux, la gente no quiere ver la línea de comandos, por lo
que todo se está haciendo en entornos gráficos, no necesitan ver las tripas
y realmente no necesitan conocer lo que está pasando -- sólo necesitan
ser capaces de configurarlo y saber que funciona.
Estoy un 100% convencido de que todos los servicios deberían
ser hechos chroot con cuentas sin privilegios y que cualquier
distribución que no lo haga para mí no es conveniente para
utilizarla en un entorno en producción. Voy a hacer chroot a todo,
mientras sea posible -- puede que lo consiga.
He pensado crear un HOWTO sobre chroot. He enviado una petición
para que alguien me ayude a convertir este artículo en formato LyX
para que lo pueda poner en los HOWTOs para Linux.
Referencias
-
Si este artículo tuviese algún cambio estaría disponible en
http://www.gnujobs.com/Articles/23/chroot.html
Formulario de "talkback" para este artículo
Cada artículo tiene su propia página de "talkback". A través de esa página puedes enviar un comentario o consultar los comentarios de otros lectores
2002-07-10, generated by lfparser version 2.21