Con Openssh y a través del fichero de configuración sshd_config, podemos establecer una jaula (chroot) para los usuarios que se conecten vía sftp al servidor. Es posible hacerlo a nivel general, por usuario o por grupos.
El siguiente ejemplo muestra como configurar una jaula sftp para el usuario «foo», donde %h es $HOME del usuario, se podría establecer otro directorio de acceso si fuera necesario. Especificamos otras opciones como evitar el forward de X, deshabilitar los túneles, etc:
/etc/ssh/sshd_config
Match User foo ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no PermitTunnel no X11Forwarding no
Con una configuración estándar, intentamos acceder con el usuario por sftp:
$ sftp localhost foo@localhost's password: Write failed: Broken pipe Couldn't read packet: Connection reset by peer
No hemos podido, podemos ver información relevante sobre el problema en el log auth.log:
Nov 12 19:20:25 lab01 sshd[11839]: pam_unix(sshd:session): session opened for user foo by (uid=0) Nov 12 19:20:26 lan01 sshd[11998]: fatal: bad ownership or modes for chroot directory "/home/foo" Nov 12 19:20:26 lab01 sshd[11839]: pam_unix(sshd:session): session closed for user foo Nov 12 19:21:02 lab01 su[11827]: pam_unix(su:session): session closed for user foo
El problema se reproduce con cualquier combinación de permisos estándar:
drwxr-x--- 2 foo foo 4096 2014-10-23 19:23 foo
drwxr-xr-x 2 foo foo 4096 2014-10-23 19:23 foo
drwx------ 2 foo foo 4096 2014-10-23 19:23 foo
La clave de la situación es que estamos accediendo con chroot activado. Para que esto sea posible y evitar un posible escalado de privilegios y poder salir del chroot la ruta establecida en el parámetro ChrootDirectory debe tener como propietario al usuario root, y que además ni el grupo ni otros usuarios puedan escribir en ese directorio. En este caso, deberíamos modificar la home del usuario a los siguientes permisos y propietario:
# chown root.foo /home/foo/ # chmod 750 /home/foo/ # ls -l /home/ total 8 drwxr-x--- 4 root foo 4096 2014-11-12 19:22 foo
Y el acceso ya es correcto:
$ sftp localhost foo@localhost's password: Connected to localhost. sftp>
El problema de esta configuración es que el usuario que accede al servicio sftp nunca va a tener permiso de escritura en el directorio principal de la jaula. Siempre tendrá que tenerlo un nivel a partir del raíz del sftp, en este ejemplo puede escribir a partir del directorio «test»:
# ls -l /home/foo/ total 4 drwxr-xr-x 2 foo foo 4096 2014-11-12 19:32 test -rw-r--r-- 1 foo foo 0 2014-11-12 19:33 aqui_solo_lectura