Feb 22, 2010

Enjaular usuarios (chroot) por ssh/sftp/scp con jailkit

Enjaular a un usuario dentro de un sistema Linux viene a ser lo mismo que restringirle el acceso a un determinado árbol de directorios. Por ejemplo, podemos enjaular a un determinado usuario dentro de su propio home, y que no pueda acceder al resto de directorios de la raíz (/etc, /var, /bin, etc.).

La idea es construirle un entorno con una serie de comandos básicos (ls, cp, ...) que queramos que pueda usar, así como las librerías de las que dependen dichas órdenes.

En el presente artículo vamos a construir un directorio enjaulado (/srv/jail) en el que encerraremos al usuario user1 y le daremos acceso a través de SSH, SFTP y SCP. Para ello emplearemos la aplicación jailkit, disponible en los repositorios RPMForge. Utilizaremos una distribución CentOS 5.4 de 64 bits.

[root@centos ~]# wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.x86_64.rpm

[root@centos ~]# rpm -Uhv rpmforge-release-0.5.1-1.el5.rf.x86_64.rpm

[root@centos ~]# yum install jailkit

En primer lugar utilizaremos la herramienta jk_init para crear el directorio que definiremos como jaula y añadiremos las herramientas de conexión que se podrán utilizar. También copiaremos la shell que utilizará el usuario user1. Para ello emplearemos el comando jk_cp, ya que aparte de copiar la shell, copiará también las librerías necesarias.

[root@centos ~]# jk_init -v -j /srv/jail jk_lsh ssh sftp scp

[root@centos ~]# jk_cp -v -f /srv/jail /bin/bash

[root@centos ~]# ls -l /srv/jail/
total 48
drwxr-xr-x 2 root root 4096 feb 5 16:52 bin
drwxr-xr-x 2 root root 4096 feb 5 16:49 dev
drwxr-xr-x 3 root root 4096 feb 5 16:52 etc
drwxr-xr-x 2 root root 4096 feb 5 16:49 lib
drwxr-xr-x 2 root root 4096 feb 5 16:52 lib64
drwxr-xr-x 6 root root 4096 feb 5 16:49 usr

Después añadiremos al sistema el usuario user1 y le asignaremos una password. También será necesario añadir el registro generado en /etc/passwd dentro del fichero passwd que se habrá creado en el entorno enjaulado.

[root@centos ~]# useradd user1

[root@centos ~]# passwd user1

[root@centos ~]# cat /etc/passwd | grep user1
user1:x:501:501::/home/user1:/bin/bash

[root@centos ~]# cat /etc/passwd | grep user1 >> /srv/jail/etc/passwd

A continuación vamos a enjaular al usuario user1 dentro de la jaula. Veremos como cambia automáticamente el directorio home y la shell asignada previamente.

[root@centos ~]# jk_jailuser -m -j /srv/jail user1

[root@centos ~]# cat /etc/passwd | grep user1
user1:x:500:500::/srv/jail/./home/user1:/usr/sbin/jk_chrootsh

Por último, añadiremos la siguiente configuración al fichero jk_lsh.ini

[root@centos ~]# cat /srv/jail/etc/jailkit/jk_lsh.ini
[user1]
paths= /usr/bin, /usr/lib/
executables= /usr/bin/scp, /usr/libexec/openssh/sftp-server

Si en este momento intentamos acceder a través de una sesión SCP, veremos que tenemos varios fallos al iniciar la sesión. Esto se debe a que el cliente SCP utiliza varias herramientas (ls, groups, sh e id) que no hemos añadido a nuestro entorno enjaulado.

Para añadirlas, utilizaremos el comando jk_cp que ya vimos en los párrafos anteriores. Lo mismo para cualquier herramienta que necesitemos agregar.

[root@centos ~]# jk_cp -v -f /srv/jail /bin/ls /usr/bin/groups /bin/sh /usr/bin/id

Si sólo hubiéramos querido darle acceso al usuario user1 a través del protocolo SFTP, tendríamos que haber ejecutado las siguientes órdenes:

[root@centos ~]# jk_init -v -j /srv/jail jk_lsh sftp

[root@centos ~]# useradd user1

[root@centos ~]# passwd user1

[root@centos ~]# jk_jailuser -m -j /srv/jail user1

[root@centos ~]# cat /srv/jail/etc/jailkit/jk_lsh.ini
[user1]
paths= /usr/bin, /usr/lib/
executables= /usr/bin/scp, /usr/libexec/openssh/sftp-server

18 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Ante todo gracias por la info. Muy buen post, muy útil y bien explicado.

    Lo he probado y funciona correctamente, execpto una cosa: cuando entro al servidor mediante un cliente scp no me deja transferir archivos desde local-remoto ni remoto-local, el mensaje de error es << Cannot execute SCP to start transfer. Please make sure that SCP is installed on the server and path to it is included in PATH. You may also try SFTP instead of SCP.
    Command failed with return code 1. >>

    El comando SCP está instalado, pues lo he añadido a la jaula con << jk_cp -v -f /srv/jail /usr/bin/scp >>

    Saludos.

    ReplyDelete
  3. Hola,

    a mí me funciona correctamente lo que comentas.

    Date cuenta que el artículo lo he realizado con un CentOS 5.4. Igual tú estás utilizando otra distribución de Linux y los paths que hay que definir en el fichero jk_lsh.ini no los has declarado correctamente...

    Además no hace falta volver a copiar el binario de scp ya que se instala al comienzo: "# jk_init -v -j /srv/jail jk_lsh ssh sftp scp".

    Un saludo,

    ReplyDelete
  4. Estas seguro de que entras mediante el protocolo SCP. El ejemplo que has puesto tambien permite acceder por SFTP, sin embargo, este protocolo no lo quiero utilizar, por tanto no he copiado ningun ejecutable relacionado con SFTP.

    Los PATHS son los correctos, lo he comprobado y sigue igual.

    ReplyDelete
  5. Sí, entro por SCP.

    Ésta es la prueba que he hecho: tengo un servidor llamado server donde tengo la jaula con el usuario user1, y otro PC (client) donde tengo un fichero llamado "file.txt", el cual he transferido por SCP al server:

    [root@client ~]# scp file.txt user1@10.5.5.217:/home/user1
    The authenticity of host '10.5.5.217 (10.5.5.217)' can't be established.
    RSA key fingerprint is f4:c0:65:22:0f:6e:27:d2:7d:55:79:c7:00:7d:5b:77.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '10.5.5.217' (RSA) to the list of known hosts.
    user1@10.5.5.217's password:
    file.txt 100% 3 0.0KB/s 00:00

    [root@server ~]# ls -l /srv/jail/home/user1/
    total 8
    -rw-r--r-- 1 user1 user1 3 mar 23 15:30 file.txt


    Y en sentido contrario lo mismo:

    [root@server user1]# scp file.txt root@10.5.5.216:/root/
    root@10.5.5.216's password:
    file.txt 100% 3 0.0KB/s 00:00

    ReplyDelete
  6. Ya he encontrado la solución: en mi caso me faltaba crear el dispositivo /dev/null en la jaula, por esa "tontería" fallaba :-)

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Excelente artículo, como siempre Javier.
    Se me plantea una duda existencial, porque en Centos 5 viene la versión de OpenSSH 4.3p2 ??? tengo entendido que a partir de la versión de OpenSSH 4.8 ya se permite "chrooting" sin necesidad de elementos adicionales como jailkit.
    A ver, no es la fin del mundo pero toca un poco la moral, con lo fácil que es modificar el ssh_config y añadir la directiva ChrootDirectory.

    ReplyDelete
  9. Es la forma de trabajar de CentOS/RHEL, nunca van con las últimas versiones de los paquetes, como sí pasa por ejemplo en Ubuntu Server.

    De esta manera tenemos un servidor no con los últimos paquetes disponibles, sino posiblemente con los más testeados, y eso muchas veces de cara a un entorno de Producción es altamente recomendable.

    De todos modos siempre te queda la posibilidad de actualizar por tu cuenta el paquete openssh-server...

    ReplyDelete
  10. Tengo un directorio en el home de un usuario enjaulado para que solo pueda acceder por SFTP al servidor, ese usuario tiene propiedad sobre un directorio y puede leer y escribir en él.

    He creado otro usuario (también enjaulado y accede por SFTP) y necesito que éste usuario acceda al directorio ubicado en el home del usuario anteriormente mencionado, sólo para leer/visualizar el directorio mencionado anteriormente, y su contenido.

    Lo he intentado con enlaces al directorio y no me ha funcionado. He cambiado permisos al directorio y no me ha funcionado. He agregado un usuario al grupo del otro y no me ha funcionado.

    Quedo atento a sus comentarios/indicaciones/sugerencias.

    ReplyDelete
  11. Lo que comentas no se puede hacer.

    Si creas un usuario enjaulado es para que no pueda salir de su jaula.

    Para lo que quieres hacer tendrás que crear un par de usuarios normales en el sistema y jugar con los permisos de sus grupos o bien utilizar ACLs.

    ReplyDelete
  12. Gracias por tu respuesta. Lo solucioné (por si a alguien más le sirve) de la siguiente manera: dejé la jaula que construí siguiendo tu tutorial (muchas gracias) y creé un alias que conduce a la jaula, desde el servidor apache. Así que el usuario que escribe, accede a través de la jaula y el usuario que sólo lee, accede mediante el navegador web. Hasta la próxima.

    ReplyDelete
  13. Estoy configurando un SFTP en redhat 5.4 el cual tiene openssh-4.3p2 y no me permite enjaular a los usuarios por medio del MATCH (tal y como lo hice en un fedora 13). Necesito instalar jailkit o es posible actualizar el openssh. En espera de su oportuna respuesta le agradezco la atención prestada. Saludos

    ReplyDelete
  14. Hola,

    podrías actualizar el paquete openssh-server (así como sus dependencias) a través de los RPMs disponibles en los repositorios de Fedora, pero tendrías que tener en cuenta que dejarías de tener soporte oficial para dicha aplicación por parte de Red Hat...

    Yo personalmente para este caso, instalaría jailkit.

    Un saludo,

    ReplyDelete
  15. Leí esta guía sobre la parte servidor de SFTP, y he aprendido de un montón de tutoriales como este. He aquí mi compendio para configurar mejor clientes y servidores:

    http://wiki.lapipaplena.org/index.php/Como_montar_accesos_SFTP

    (con especial cuidado sobre usuarios y permisos)

    ReplyDelete
  16. e seguido la guia exelente mente perfecta me sivio mucho pero hay alguna manera de agregar mas comandos a la jaula digamos mkdir o svn.
    espero alguien todabia ande por aqui ya llevan varios meses sin escribir aqui saludos

    ReplyDelete
  17. Para agregar más comandos a la jaula tienes que utilizar la herramienta jk_cp, ya que ésta se encarga de copiar también las librerías necesarias.

    # jk_cp -v -f /srv/jail /bin/mkdir

    ReplyDelete
  18. No loguea el usuario creado , despues de ingresar usuario / clave se cierra el winscp ¿que puede ser ?

    ReplyDelete