sábado, 10 de mayo de 2008

SFTP y chroot(): Al fin una forma fácil con OpenSSH

Las últimas versiones de OpenSSH (5.0/5.0p1 actualmente) liberada hace poco, posée la capacidad de permitir configurar jaulas selladas para los usuarios a través de una nueva función de chroot() incorporada.

Normalmente, configurar una jaula "chrooted" es un trabajo tedioso y bastante complejo, y aún lo es más cuando tenemos que configurar acceso SSH hacia dicha jaula. Por otro lado, dependiendo de las herramientas y funciones que pongamos a disposición de los usuarios dentro de la jaula, la misma puede ser vulnerada de diversas formas. Todos saben que dejando un compilador C y permitiendo ejecutar chroot() dentro de la jaula (solo root puede hacerlo, pero si en la jaula dejamos usuarios con acceso shell, y dejamos servicios o ejecutables vulnerables y que permitan escalado de privilegios, seguramente la jaula va a ser vulnerada. También puede serlo si dejamos comandos SETUID accesibles), se puede escapar fácilmente de la misma casi sin esfuerzo.

La idea detrás de esta capacidad de OpenSSH es poder limitar el acceso de usuarios a descargar archivos desde una parte del disco del servidor anfitrión, evitando que puedan navegar por cualquier lado cuando usando SFTP.

Hasta hace relativamente poco tiempo, no era posible dar acceso SFTP a través de OpenSSH sin dar acceso shell. Esto significa que cuando creábamos una cuenta para un usuario que solo debía acceder a un directorio para subir o bajar archivos, le estábamos dando también acceso shell, lo cual es una bomba de tiempo. Con el servidor interno de SFTP de OpenSSH de la versión 4.8 (se puede declarar el uso de este servidor en el sshd_config con la directiva Subsystem internal-sftp) se puede resolver ese dilema.

Para configurar el acceso SFTP chrooted con OpenSSH entonces, se crea un directorio en el servidor, y se le asignan privilegios de solo lectura:

root@server:~ # mkdir /var/jaula
root@server:~ # chmod a=rx /var/jaula
root@server:~ # ls -la /var/jaula
total 8
dr-xr-xr-x 2 root root 4096 May 10 06:39 .
drwxr-xr-x 4 root root 4096 May 10 06:39 ..

Luego se crea un grupo de usuarios que tendrá acceso de solo lectura a dicho directorio:

root@server:~ # groupadd sftponly

Después se crean usuarios dentro de este grupo, los cuales no deberán tener shell asignado:

root@server:~ # useradd -g sftponly -G sftponly -s /bin/false usuario1
root@server:~ # passwd usuario1
Changing password for usuario1.
New Password:
Reenter New Password:
Password changed.

Y por último, editamos la configuración del OpenSSH (en la mayoría de los linux es en /etc/ssh/sshd_config) para que enjaule a los usuarios que pertenecen al grupo sftponly en el directorio definido anteriormente:

Match group sftponly
    ForceCommand internal-sftp
    ChrootDirectory /var/jaula

Una vez hecho esto, recargamos la configuración del OpenSSH y ¡voilá!

Cuando un usuario perteneciente al grupo sftponly se loguee utilizando su cliente sftp, no podrá salir del directorio /var/jaula, así que podremos darle acceso a descargar archivos en forma segura sin que sus datos viajen en texto plano por la red de redes.

No es necesario cargar ningún archivo o subdirectorio especial en /var/jaula, lo cual rivaliza con una jaula chrooted tradicional.

Lamentablemente, esta configuración no sirve para ser utilizada con scp, así que solo podremos contentarnos con dar acceso SFTP, pero ya esto solo es mucho más fácil de hacer que antes.

¡Disfrútenlo! :-)

EOF

2 comentarios:

casd dijo...

hola, una consulta tengo una pc con opensuse 10 con oracle, hacemos un back de la db en una carpeta especifica y quiero q una persona entre por sftp y copie para respaldar ese archivo, pero mi problema es q puede navegar por toda las carpetas.. hice lo q pusiste en el blog pero cuando me conecto me rechaza la conexion al servidor.
agregue en sshd_config
Match User sftpuser
ForceCommand internal-sftp
ChrootDirectory /backup
antes he creado las carpetas como lo especificaste. desde ya muchas gracias por tu tiempo,

Gustavo Castro Puig dijo...

Camilo:

Bueno, en realidad habría que revisar los logs a ver si algo aparece. Te recomiendo aumentar el LogLevel a DEBUG en el /etc/ssh/sshd_config, reiniciarlo y volver a intentar la conexión.
Luego, revisas el /var/log/messages (o el log que hayas designado para almacenar los registros del SSHD) y verificas qué es lo que está pasando. Si quieres, puedes postearme la parte del log donde aparece el intento.
Debes tener en cuenta que la versión del OpenSSH debe ser igual o superior a la 5.0 para utilizar esta función de chroot().

Saludos,
Gustavo.

 
Gustavo Castro

Crea tu insignia