miércoles, 13 de marzo de 2019

Acceso por SFTP con jaula chroot, sin acceso SSH



Cómo permitir a un usuario subir/borrar archivos por SFTP a un directorio de un servidor Linux en el cual no tiene permisos, con la peculiaridad de que el servidor está sirviendo una página web.



Escenario:

- Un servidor Linux sirviendo una página web.
- Un directorio llamado "uploads", el cual contiene imágenes mostradas en la página web.
- La necesidad de que un usuario pueda subir imágenes a ese directorio.
- Que el usuario pueda conectarse por SFTP al servidor web, pero no por SSH.
- Que el usuario no pueda acceder a ningún otro directorio a parte de "uploads".

Para resolver esta necesidad, accedí al servidor y averigué los permisos del directorio "uploads":

WEBSERVER:/ # ls -la /srv/www/htdocs/web.com/sites/default/uploads total 76 dr-xr-x--x 5 wwwrun root 4096 Mar 12 16:29 . drwxr-xr-x 4 wwwrun root 4096 Apr 26 2018 .. drw-r--r-- 4 wwwrun root 4096 Oct 29 2016 files drwxr-xr-x 33 wwwrun root 4096 Mar 12 16:30 uploads

Vi que la carpeta uploads tenía como propietario el usuario "wwwrun", como grupo propietario "root" y como permisos de lectura/escritura/ejecución: drwxr-xr-x / 755.


Crear usuario



A partir de aquí, he creado el usuario "nombre_usuario", el cual será el encargado de subir contenido:

WEBSERVER:/ # useradd nombre_usuario

Luego le he dado un password:

WEBSERVER:/ # passwd nombre_usuario

A continuación, he creado una carpeta que servirá como ubicación inicial (home) para las conexiones SFTP del usuario "nombre_usuario":

WEBSERVER:/ # mkdir -p /sftp/nombre_usuario


Jaula chroot



Como he comentado anteriormente, no queremos que el usuario pueda ver otras carpetas del servidor, por lo tanto, vamos a enjaularlo (chroot) en el directorio que acabamos de crear.

Para que esto funcione, es importante que todas las carpetas de la ruta hacia la home del usuario tengan de propietarios root:root (en este caso, tanto /sftp como /sftp/nombre_usuario) así como permisos 75X (con 775 no funciona, por ejemplo). Si los permisos no están configurados de esta forma y usamos una jaula chroot, nos encontraremos con el siguiente error al conectarnos por SFTP:

WEBSERVER:/ # sftp nombre_usuario@192.168.1.1 password: Connection to 192.168.1.1 closed by remote host. Couldn't read packet: Connection reset by peer


Acceso SFTP sí, acceso SSH no



A parte de enjaular al usuario, necesitamos que éste pueda conectarse a la máquina por SFTP pero no por SSH. Para satisfacer ambas necesidades, podemos usar una directiva Match de OpenSSH con los siguientes parámetros:

- ForceCommand internal-sftp limita al usuario a realizar solamente conexiones SFTP.
- ChrootDirectory /sftp/nombre_usuario no permite salir del directorio /sftp/nombre_usuario:

WEBSERVER:/ # vi /etc/ssh/sshd_config [...] Match User nombre_usuario ChrootDirectory /sftp/nombre_usuario ForceCommand internal-sftp AllowTcpForwarding no

Recordar que cada vez que modifiquemos el archivo sshd_config debemos reiniciar el servicio ssh:

WEBSERVER:/ # service ssh restart

Ahora modificamos el directorio home del usuario, ya que al conectarse por SFTP, el usuario ve como directorio raíz su directorio ChrootDirectory (/sftp/nombre_usuario) y en ese directorio no existe la ruta "/home/nombre_usuario". Por lo tanto, usamos usermod -d para indicar que este usuario se conectará a su propia raíz (usamos un 'vacío' - dos comillas dobles - para indicar raíz):

WEBSERVER:/ # usermod -d "" nombre_usuario

Llegados a este punto, comprobamos que el usuario puede conectarse por SFTP, pero que al tratar de conectarse por SSH, el sistema no se lo permite:

WEBSERVER:/ # ssh nombre_usuario@192.168.1.1 Password: This service allows sftp connections only. Connection to 192.168.1.1 closed.


Bind mount



El siguiente paso es permitir a "nombre_usuario" ver el contenido del directorio "/srv/www/htdocs/web.com/sites/default/uploads". Para ello, realizaremos un "bind mount" de la siguiente manera.

1. Creamos un directorio dentro de la carpeta home del usuario, que servirá como punto de montaje:

WEBSERVER:/ # mkdir /sftp/nombre_usuario/uploads

2. Montamos la ruta a la que queremos acceder sobre el directorio "uploads" que acabamos de crear:

WEBSERVER:/ # mount -o bind /srv/www/htdocs/web.com/sites/default/uploads /sftp/nombre_usuario/uploads

Una vez hecho esto, probamos a conectarnos por SFTP con el usuario "nombre_usuario" y comprobamos que el usuario ve una carpeta "uploads". Si entramos, veremos el contenido de la carpeta montada (es decir, el contenido de /srv/www/htdocs/web.com/sites/default/uploads).

Si quisieramos que el usuario accediera directamente a /uploads al conectarse por SFTP, podríamos forzarlo modificando el home del usuario mediante:

WEBSERVER:/ # usermod -d /uploads nombre_usuario


Permisos de escritura



Por último, otorgamos permisos de escritura a "nombre_usuario" en la carpeta de destino:

1. Cambiamos el grupo propietario de la carpeta final (/srv/www/htdocs/web.com/sites/default/uploads) a "users" ("nombre_usuario" pertenece al grupo "users"):

WEBSERVER:/ # chown wwwrun:users /srv/www/htdocs/web.com/sites/default/uploads

2. Permitimos al grupo propietario escribir en la carpeta:

WEBSERVER:/ # chmod 775 /srv/www/htdocs/web.com/sites/default/uploads

A partir de este momento, ya cumplimos con lo que se nos ha pedido:

- Que un usuario pueda subir contenido a la carpeta uploads por SFTP.
- Que el usuario no pueda iniciar conexiones SSH.
- Que el usuario no pueda salir de su directorio (ni de uploads).
- Que la web siga mostrando el contenido de "uploads".
1

1 comentario:

  1. muy buen tuto...para dar permisos al grupo chmod g+w www-data

    ResponderEliminar