Supongamos que tenemos un linux al cual se accede por ssh. La situación normal es que a nivel de permisos tenemos root y el resto.
El usuario root puede hacer todo, listo.
Dentro de ese resto, manejando grupos y permisos podríamos más o menos manejar algún tipo de restricción. Una medida común es utilizar sudo, que habilita una lista de acciones que podrá ejecutar quien tenga los permisos.
Pero, ponele que en lugar de estar viendo como le permitimos a los usuarios hacer algunas tareas administrativas, estamos buscando restringir lo que ya pueden hacer. Si el usuario en realidad es una cuenta para que un script pueda ejecutar algunas consultas sobre el sistema, no hay motivo para que pueda ejecutar ningún otro comando que no corresponda a lo que va a hacer.
Para este requerimiento, se puede usar rbash.
Si, si, ahí los del fondo, escuché que existe selinux y apparmor, pero esas son palabras mayores, quedémonos con lo sencillo.
Lo que hace rbash es empezar por desabilitar un montón de comportamiento provisto por bash, acá está la lista completa, lo más importante es que no permite cd ni cambiar la ruta de invocación de comandos.
Además:
The restricted shell mode is only one component of a useful restricted
environment. It should be accompanied by setting PATH
to a value
that allows execution of only a few verified commands (commands that
allow shell escapes are particularly vulnerable), changing the current
directory to a non-writable directory other than $HOME
after login,
not allowing the restricted shell to execute shell scripts, and cleaning
the environment of variables that cause some commands to modify their
behavior (e.g., VISUAL
or PAGER
).
Sumado a eso, en .bashrc o similar hay que setear el PATH a una carpeta con symlinks a los ejecutables permitidos, según he visto que se hace.
Luego, se debe considerar que:
When a command that is found to be a shell script is executed
(see Shell Scripts), rbash
turns off any restrictions in
the shell spawned to execute the script.
Estoy citando pues como tengo casi nula experiencia con rbash, me siento irresponsable. Pero mi ínfima experiencia algo me ha hecho pensar.
Vamos ahora al escenario concreto, quiero:
- que exista una cuenta
- que tenga shell restringido
- a la que sólo se pueda acceder vía ssh
- esto implica no login por consola ni "desplazamiento lateral" tipo su o login
Este comando lo hace:
$ sudo adduser --shell /usr/bin/rbash --disabled-login prueba
Si estás modificando un usuario existente, editás /etc/password para que tenga el shell correcto y /etc/password para deshabilitar el login.
También se hace con
$ sudo passwd -l prueba
Que le agrega a "!" al password existente.
De un modo u otro lo controlás con:
$ sudo grep prueba /etc/passwd /etc/shadow
/etc/passwd:prueba:x:1001:1001:,,,:/home/prueba:/usr/bin/rbash
/etc/shadow:prueba:!:19542:0:99999:7:::
Solo vía ssh, hay que habilitar la key ya que se trata de clientes script, no de personas ingresando claves, aunque con la key un usuario puede entrar.
$ ssh-keygen -f prueba.key -t ecdsa
En la carpeta del usuario prueba, hay que crear .ssh con rwx------ y el archivo authorized_keys con permisos rw------- y el contenido de prueba.key.pub.
rbash en acción |
El problema que hay acá es que si ejecutás:
$ ssh prueba@localhost -t bash
sshd ignora el shell de /etc/passwd y te da un shell irrestricto.
rbash bypass |
Se arregla de dos maneras, una global y otra específica para cada usuario.
La global es poner en sshd_config esta línea, que no la probé:
no-pty ssh-ed25519 AAAAC3NzaC1....
El problema es que perdés el prompt y bash completion, algo completamente irrelevante para un script.
rbash con no-tty en authorized_keys |
no login |
Mis reflexiones
Porque no password al azar
Se podría poner un password al
azar, pero al ser un password existente hay una increíblemente remota
posibilidad de que alguien le acierte. También que al azar sea un password en un diccionario. O que en el momento de la creación haya leak.
Es mejor poner "!" antes que usar azar pues es un indicador visual y fácil de controlar de modo automático que luego no cambie la situación.
Es mejor dejar solo "!" pues agrega que no haya ninguna posibilidad de login.
Porque no ForceCommand rbash
Si la idea es que en ese equipo no haya ningún usuario remoto sin rbash, de acuerdo con ForceCommand rbash. Pero eso implica que al menos a algún usuario hay que habilitarle que pueda ejecutar sudo, además de las reglas de sudoers.
Me parece más sencillo configurar no-pty en .ssh/authorized_keys para cada usuario a restringir.
Igual en este aspecto mi opinión no es tan fuerte como con el punto anterior. De hecho, mientras escribo esto, no puedo dejar de notar que ForceCommand rbash + sudo responde más a la política de denegar todo y luego permitir de a uno, como que cambiaría de idea muy fácil... listo, ya cambié de idea.
Igual mi instinto algo me dice a favor de no-pty, por el lado de evitar una denegación de servicio. Si vuelvo a cambiar de idea, lo registraré.
Mi posición actual es, depende del perfil de uso del equipo, si es de uso general y hay que restringir a un usuario de servicio, no-pty, si nadie debería acceder salvo ciertas tareas de mantenimiento, ForceCommand rbash + sudo.
Disclaimer
No tomes este post como ninguna autoridad de cómo implementar correctamente rbash, no he investigado la parte de las variables de entorno ni sometido a pruebas exhaustivas.
No hay comentarios:
Publicar un comentario