2023/07/04

Reflexiones sobre rbash

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
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
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é:

ForceCommand rbash

Tiene la ventaja de restringir a todos por si alguno se te escapa, pero si querías tener uno que haga de administrador, vas a tener que ponerle específicamente que pueda ejecutar sudo.
 
La específica para cada usuario es poner no-pty  en  .ssh/authorized_keys
a la key con la que se autentica.Queda algo asi:


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
rbash con no-tty en authorized_keys

 

no login
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.

 

 

2023/06/18

Aprovechando pantallas obsoletas: la idea

Desde hace rato que la acumulación de netbooks de 2GB y tablets con android 4.x me viene haciendo mal y el demonio interno me dice que aproveche al menos las pantallas, asi que me puse.

Mi contexto histórico relacionado: había incursionados hace muuuuucho tiempo en utilizar dual head mediante el uso de dos placas de video cuando tenían una sola salida. También había investigado, sin éxito, el usar una misma computadora con dos placas de video, dos mouses y dos teclados como si fueran dos.

Luego, intenté nuevamente usar las pantallas peladas, pero como hablan LVDS, quedó fuera de mi alcance.

Luego, con éxito, usar varias máquinas a la vez.

Como siempre, empecé preparando un mensaje con preguntas, en este caso dirigido al chat de cybercirujas, que decía algo así como:

"Tengo un problema, aparte de la cara. El contexto es que querría usar esas notebooks pedorritas de 1 o 2gb RAM por sus pantallas, pero sin ejecutar nada más que linux base + xwindows. Por ejemplo para tener abierto en mi máquina principal un firefox con una cuenta de mail alternativa y visualizarlo en la notebook. Si además funciona el portapales, es un plus."

Como siempre, continué con la técnica de preguntar bien para aprender, escribí un montón de mensajes alternativos y seguí pistas en Internet hasta que comprendí bien el problema y algunas posibles soluciones y esto es a lo que llegué, no voy a contar toda la historia porque la verdad es que no la recuerdo.

Comencemos por la topología y mis requerimientos, habiendo un nodo principal y uno o más secundarios.

 

Topología


Principal ---> Secundarios

La idea es ejecutar en Principal una aplicación y que se visualice en Secundario, esto es porque los secundarios pueden no tener la potencia o carecer del contexto. Es un plus mantener la interacción desde Principal, pues Secundario puede estar lejos del alcance o sin dispositivos de entrada.

Con contexto me refiero a que puedo tener una VM que está conectada a una VPN, puedo mostrar el escritorio de esa VM en Secundario pero no puedo ejecutarlo ahí y menos tener la conexión a la VPN.

 

Una manera de expresar esto es:

 

Interacción -> Ejecución -> Visualización

 

Lo que deseo es:

 

Principal -> Principal -> Secundario

 

Requerimientos

 

  • Van con nombres para luego verlos en una tabla comparativa.

 

Incondicionales

 

  • Render Remoto: Usar la pantalla remota.

 

Negociables

 

  • Input en Principal: que tome el teclado y el mouse de la principal.
  • Ejecución en Principal: el contexto de ejecución debe ser en Principal
  • Visibilidad Permanente: que independientemente de lo que haya en Principal, por ejemplo al cambiar de escritorio, se siga viendo.

 

Adicionales

 

  • Modo Render Aplicación: que se visualice una ventana en particular.
  • No SSH a Principal: que no se ingresen credenciales del principal en el secundario.
  • Modo Render Total: que se muestre todo el desktop. Podría servir como un facilitador de navegación, pero si es el único modo es poco útil.
  • Integración: que haya integración con el display principal como si fuera un monitor más.

 

Transversal

 

Y existe un requerimiento adicional que es un plus:

  • Autónomo: Sin interacción física con el equipo remoto, tal que el dispositivo puede estar en un lugar de incómodo acceso o sin periféricos de entrada.


Recursos disponibles


  • navegador con http: vendría a ser el más portable, pero siempre ocupa una ventana en Principal, se parece conceptualmente a lo que hice con xzoom en el sentido que se toma algo que se está visualizando y se transmite, en el caso de xzoom a una ventana local.
  • xwindows: es el más natural, pero implica que haya xwindows en los Secundarios, cosa que a veces puede ser dificultoso.
  • vnc: permite desde una máquina ver y potencialmente interactuar con otra.
  • ssh: permite acceder de modo remoto y seguro y meter xwindows en un tunel.
  • x2x: permite con teclado y mouse saltar de un escritorio a otro remoto que tenga xwindows.

 

Un poco de análisis


Para cumplir con Principal -> Principal -> Secundario, mi sueño sería que en Principal yo lance algo, aparezca en Secundario y pueda seguir interactuando desde Principal.

 

x2x (Principal -> Secundario -> Secundario)

 

Usar x2x queda descartado pues la aplicación se ejecuta en Secundario y en mi caso en particular, como tengo tres monitores en L, el escritorio remoto sólo se puede recorrer con esa misma forma en L. Recuerdo hace un tiempo haber visto el código fuente de x2x a ver si podía darme cuenta por donde tendría que investigarlo y me superó. Pero anotemos que podría servir para la interacción.

 

VNC (Principal -> Secundario -> Secundario)

 

VNC queda descartado por la misma ejecución en Secundario. También anotemos que podría servir para la interacción.

 

Deskscreen y WEYLUS (Principal -> Principal -> Secundario)


En un video ví estas opciones. Usan el navegador del lado de Secundario.

WEYLUS es la única opción que ofrece Integración, pero sólo con chipset Intel, el cual no tengo.

Tienen como problema sólo mostrar lo que se está viendo, si te pasás a otro desktop, deja de visualizar. Se soluciona con "always on visible workspace", lo que no es ninguna solución pues el objetivo era que no ocupe pantalla en Principal. Si lo que te interesa es mostrar en Secundario, como por ejemplo para compartir con otras personas en una red local, te servirían.

https://deskreen.com/lang-en

https://github.com/H-M-H/Weylus

 

ssh -X (Principal -> Secundario -> Principal)

 

Para esto con conviene usarlo al revés, Secundario -> Principal -> Secundario, con lo cual tenemos la ejecución en Principal y visualización en Secundario, solo nos falta ver el asunto de la interacción. No me gusta porque hace falta que el Secundario se autentique frente al Principal y no es autónomo.

 

La solución

 

Esos "descartado" de antes no eran definitivos y si hacemos unas combinaciones, tenemos algo que aunque un poco complicado de poner en marcha y utilizar, cumple bastante bien.

La combinación es instalar o aprovechar el xwindows del Secundario. Desde Secundario con ssh -X abrir la aplicación y luego con x2x o VNC desde Principal interactuar. Por el bug de x2x, nos quedamos con VNC.

+----------------+        +--------------+
| Principal      +---VNC--> Secundario   |
| +------------+ |        | +----------+ |
| | Aplicación <-- ssh -X --+ Terminal | |
| |            | |        | +----------+ |
| |            | |        |  +--------+  |
| |            +--xwindows---> render |  |
| |            | |        |  +--------+  |
| +------------+ |        |              |
+----------------+        +--------------+

 

Comparativa



DeskscreenWEYLUSx2xvnc + ssh -X
render remotosisisisi
input en principalsisisisi
ejecución principalsisinosi
visibilidad permanentenonosisi
render aplicaciónsinosisi
no ssh a principalsisisino
render totalsisinono
integraciónnopotencialfalla por "L"no


Esto sigue en la implementación