Nos complace anunciar que estamos reimplementando las omnipresentes utilidades sudo y su en Rust. Sudo se desarrolló por primera vez en la década de 1980. A lo largo de las décadas, se ha convertido en una herramienta esencial para realizar cambios minimizando el riesgo para un sistema operativo. Pero debido a que está escrito en C, sudo ha experimentado muchas vulnerabilidades relacionadas con problemas de seguridad de memoria.
|
etiquetas: rust , sudo
Una sola clave para usuario y administrador. El usuario ejecutando a cada rato comandos se administrador. Es la receta perfecta para que te la cuelen.
Lo ideal es un usuario root con clave diferente y hacer su (no sudo) cuando sea necesario.
Si te lo curras, puedes limitar o configurar sudo con bastante profundidad.
Eso sí, no es mi caso.
#2 ¿Atrocidad? Dime como haces que alguien ejecute algo con otro usuario sin herramientas así. Que en el escritorio de un ordenador personal se den privilegios de administrador por medio de sudo no me parece tampoco una atrocidad.
- Vamos a hacer una cuchara de palo con una técnica novedosa y supermoderna.
- ¿ Va a quedar distinta ?
- No, va a quedar igual.
No critico con esto sudo, a mi no me parece tan mala herramienta, aunque yo no dejaría tocar a cualquiera el sudoers porque incluso queriendo ser restrictivo puede dejar puertas abiertas, y eso va a seguir pasando, esté escrito en rust, en go, o en el lenguaje que quieran.
- tengo un coche verde con 4 ruedas.
- tengo un coche verde con 4 ruedas + airbag, ABS, ESP...
A simple vista son iguales, pero uno de los dos es más seguro y menos propenso a sufrir accidentes.
-Tengo una cuchara de palo de hace décadas que ha tenido problemas de termitas.
-Vamos a hacer una cuchara de acero inoxidable para evitar las termitas.
-¿Va a quedar distinta?
-No, va a servir para lo mismo pero eliminamos los posibles futuros problemas de termitas.
En OpenBSD doas por diseño capa muchas cosas como variables de entorno o la persistencia.
No todos los casos de uso son iguales, las políticas de seguridad tampoco tienen que serlo.
Se supone que la seguridad en Linux/Unix consiste precisamente en evitar eso: que usuarios puedan ejecutar algo con otro usuario porque sí. Las "herramientas" que uses para eso son irrelevantes: si lo permites, estás puenteando la seguridad del sistema. Adórnalo con las palabras que prefieras, que estás haciendo exatcamente eso: puentear, y con ello invalidar, la seguridad del sistema.
Nadie debería poder ejecutar cosas con permisos diferentes a los de su propio usuario. Sólo root debería ser capaz de eso. Punto y final. Sudo es una guarrería. Que vale, que sí, que yo también lo uso en mi Ubuntu, que mola pasar de la seguridad de forma activa y consciente de queledenporculojajaja en nuestro laptop y nuestro desktop de casa, pero que no nos engañemos a nosotros mismos.
¿ Es imposible corregir esas vulnerabilidades en C?
¿ Solo Rust permite corregir esas vulnerabilidades?
- Tengo una cuchara de palo de madera de cerezo que ha tenido 1 problema de termitas en 30 años.
- Vamos a hacer una cuchara de palo de madera de almendro para evitar la raza de termitas que se alimentan de madera de cerezo.
- ¿Va a quedar distinta, va a hacer mejor a la herramienta y más segura de utilizar?
- No, va a quedar igual y va a ser igual de segura, pero eliminaremos los posibles futuros problemas de termitas que se alimentan de madera de cerezo.
- ¿Pero eso no lo habíamos arreglado ya en 2021 puliendo y pintando la cuchara de palo?
- Errr... sí, pero es que nos gusta mucho más la madera de almendro.
- ¿Pero no hay cosas más interesantes que hacer con esa madera que rehacer la cuchara de palo que ya tenemos, que funciona y que está estandarizada, revisada, mejorada y protegida?
- Es que nos gusta más la madera de almendra, la madera de cerezo es una mierda.
- Pero, ¿por qué es una mierda?
- Porque hay termitas que se comen la madera de cerezo en condiciones especiales de 25 grados Celsius, 12% de humedad ambiental y 0'95 atmósferas de presión.
- Pero, ¿es eso un riesgo tal que merezca la pena poner a un equipo de trabajo durante años a sustituir las cucharas de madera de cerezo por madera de almendro, o quizá sería mejor desarrollar otro tipo de cucharas de palo más modernas o funcionales y mantener mientras tanto las que ya tenemos, funcionan y son lo suficientemente seguras? ¿Qué garantías tenemos de que las nuevas cucharas de palo que nadie ha desarrollado todavía con madera de almendro van a ser 100% seguras de todo tipo de fallos frente a las de cerezo ya existentes?
- Las cucharas de madera de cerezo son una mierda. Las de madera de almendro funcionan más mejor y son mucho más seguras.
-
¿Cuales son tus alternativas?
Personalmente, yo no toco una versión de rust de sudo, ni con un palo. Todavía no sabemos muy bien el virus que tenemos en los equipos con el systemd, como para reemplazar ahora sudo.
¿Que aporta Rust?
Su manejo de memoria es seguro por diseño, no hay "nulos" como tal si no que se devuelven tipos opcionales y tienes que mirar explícitamente si hay valor para poder acceder a el y la gestion de errores por como está diseñado es también explicita... y así varias cosas.
¿Es imposible corregir vulnerabilidades de manejo de memoria en C?
No, solo necesitas que el programador se asegure de hacer las liberaciones cuando toca, de borrar memoria cuando toca, de no hacer accidentalmente doble frees, comprobar siempre si un valor no es nulo, no usar valores que ya has liberado... y así con un montón de cosas más. Vamos que todo lo que te aporta Rust de serie es "manual".
¿Solo Rust permite corregir esas vulnerabilidades?
No, hay varios lenguajes que se pueden considerar con memoria segura, ellos mismos lo dicen aquí www.memorysafety.org/docs/memory-safety/ (Go, Java, Python, C#, ...), pero en este caso que hablamos de sistemas lo más adecuado por su forma de ser es Rust y que puede interactuar facilmente con otras cosas hechas en C (por ejemplo el kernel o las librerías de sistema). Un su o sudo en Python huiría de ello, me quedaría con el de C, y en Go me parecería absurdo no es el campo para el que está diseñado Go a parte de tener un binario de varios MB para una función a priori simple (he puesto Go y Python como ejemplo ya que son mis lenguajes principales).
No soy yo fan de la reescritura de absolutamente todo lo que estaba en C en Rust, por ejemplo una reescritura del kernel de linux es inviable pero han empezado a admitir módulos de kernel en Rust como segundo lenguaje y eso está bien.
precisamente eso es mucho más peligroso potencialmente que usar sudo adecuadamente.
#18 sudo no invalida la seguridad de un sistema, únicamente su mal uso, de hecho es mucho peor las opciones de no usar sudo. Es mucho mejor darle permisos de sudo a, por ejemplo, hpacucli al usuario nagios que poner el bit suid al binario de hpacucli o que, desde luego, ejecutar nrpe con el usuario root.
www.youtube.com/watch?v=90Q5N1qT7BQ
Mira por ejemplo curl que hace estadísticas al respecto de las vulnerabilidades si están relaccionadas con temas de errores en C o de lógica/diseño: curl.se/dashboard1.html#c-vulns
Puedes usar suso correctamente e incluso en un entorno grande, con freeipa, donde estableces un contexto de seguridad en HBAC.
Un grupo de cuentas tiene derecho a ejecutar un grupo de comandos para un grupo de servicios en un grupo de computadoras.
Pablito, que es desarrollador web, puede ejecutar sobre ssh un reinicio de servicio httpd en los hosts en el grupo de desarrollo web. Y hacer un tail del log.
Obviamente hay otras maneras tal vez más cómodas de hacer eso, es solo un ejemplo.
La idea es auto contener en todo lo posible el código "crítico", por eso es preferible, no sólo a nivel de sostenibilidad de un sistema sino también de seguridad, tener unos pocos cientos de líneas de código para escalar privilegios con seteuid que no tener cientos de miles de líneas de código de múltiples servicios ejecutándose como root.
Pues con sudo es lo mismo, es mucho mejor tener este sistema, que está muy bien delimitado si se sabe lo que se hace, que tener que andar tocando permisos a cientos de archivos, en cientos de servidores, para cientos de usuarios y grupos, etc ... Esto, además de insostenible administrativamente, tarde o temprano dará lugar a problemas de seguridad críticos con toda seguridad.
Y además de todo eso un sudo no necesariamente vulnerable pero mal configurado por error puede llevar a problemas de seguridad, de hecho hay páginas bastante conocidas en el mundo de la seguridad cuyo único cometido es listar diferentes binarios el ecosistema opensource y explicar como y porqué son vulnerables a una mala configuración de sudo. De hecho en alguna de estas páginas además te explican también los riesgos de dar suid a ciertos binarios.
La pregunta es si los errores que habrá hasta estabilizarlos, compensarán los errores que se espera ahorrar en el futuro. Depende de la habilidad del programador. Posiblemente en el casdo genral no, porque programar en C sin meter errores de mal manejo de la memoria es algo bastante fácil. cc/ #10
Es un software que ha tenido diez bugs en los últimos ocho años. Pocos más seguros habrá. No tiene termitas.
Entiendo que en el caso de sudo o su, no se trata de un software nuevo, si no una reescritura en un lenguaje que es más seguro. O sea una solución madura, con un diseño maduro, escrito en un lenguaje más seguro desde el punto de vista de la memoria.
No és un simple software nuevo.
con sudo vas a limitar qué usuarios pueden ejecutar ese binario, con el suid bit cualquier usuario lo va a poder ejecutar con escalada de privilegios, por no hablar de que nadie te obliga a usar sudo para ejecutar ese binario, pero muchos binarios del sistema en distribuciones antiguas ya llevaban el bit suid configurado inicialmente, lo necesitaras o no.
"además de todo eso un sudo no necesariamente vulnerable pero mal configurado por error puede llevar a problemas de seguridad"
esta es la cuestión, el problema no es sudo, sino un mal uso o una mala configuración de la misma, y de esto no está exento ninguna otra pieza de software que necesite acceder a partes críticas de un sistema.
El suid tampoco es una cosa que se ponga a diestro y siniestro, pero no deja de ser una parte fundamental de sistema que se usa por ejemplo tanto en su como en sudo (no se si ya comenté esto antes), pero al usuario que preguntó le dije las posibilidades que había, sin hacer distinciones entre lo que es más o menos seguro.
De hecho además de sudo y el suid hay otro mecanismo que son las capabilities, que para ciertas cosas son mucho más adecuadas. Por ejemplo el comando ping debería requerir que el usuario fuera root, pero gracias a ellas se le pueden otorgar permisos únicamente para que toque lo que necesita a nivel de red, sin entregarle suid ni hacerle pasar por un sistema como sudo, y con la ventaja de que ante un fallo de seguridad del binario lo máximo que van a poder elevar son ciertas capacidades a nivel de red.
Como caso práctico he puesto nrpe. Si crees que mi razonamiento falla en algo te invito a que expliques cómo harías tú para configurar nrpe para monitorizar servicios, estados, usuarios, colas de correo, raids por HW, estados de CEPH, DRBD, reiniciar servicios, etc ...
Y si te queda tiempo para explicar cómo implementarías tú ansible para gestionar unos cuantos cientos de servidores.
Con la key de root
Como dicen más arriba, cada entorno es diferente, con diferentes necesidades en cuanto a la seguridad, lo que es buena idea en una Ubuntu en el portatil de tu madre no tiene por que serlo en un servicio crítico
No caigamos en falsos dilemas, si alguien quiere dedicar su tiempo y esfuerzo a reimplementar su y sudo en rust bienvenido sea.
Si al final de esto sale algo interesante se irá extendiendo y si no, quedará como un brindis al sol.
permit usuario as root cmd comando args ristra de argumentos.
El compilador está en desarrollo como lo está todavía GCC, que también tiene sus bugs y sus regresiones.
Y como alternativa a C, innecesario
Lo que dices del nagios, pues precisamente haciéndolo al revés, en vez de elevar por defecto lo que hay que hacer es reducir los permisos según lo que se esté monitorizando. Por ejemplo, si tienes un plugin que extrae datos de los logs de una aplicación lo que necesitas es permisos de la aplicación, los mínimos necesarios para acceder al archivo de log pero nunca root si no es necesario. De hecho en temas como nagios es especialmente peligroso cuando el admin se está haciendo sus plugins con lenguajes que no domina, e introduce vulnerabilidades. Recuerdo un caso que tuve con un cliente en el que su admin tenía un plugin en bash para parsear unos logs y encima lo corria como root, con lo que al injectarle ciertas cosas en los logs me podía abrir una shell inversa con permisos de root en la máquina.
Y así con todo, por ejemplo para el tema del raid hw, si estás usando el megacli o similar puedes meterlo en una ruta donde solo llegue tu agente y darle capabilities de cap_sys_admin, con las cuales tendrá los permisos necesarios para hacer sus consultas, pero nunca podría elevarse a root. Por simple comodidad se podría también usar sudo para esto, pero siendo muy restrictivo en los argumentos que se le permite utilizar al binario.
Hay cosas como por ejemplo de parar y arrancar servicios, me parece un buen ejemplo donde sudo encajaría bien. Esto lo mismo dentro de un tiempo cambia, como les de a los de systemd por tener su propio sistema de autorización pero por el momento sudo es bueno para esa tarea concreta.
Y lo que dices de ansible escapa el topic que estamos tratando, aún así soy RHCE, si tienes alguna duda en concreto del tema te la puedo resolver por privado.
El sudo se creó para que algunos usuarios pudieran ejecutar algunos comandos específicos con los privilegios de otro usuario (que puede o no ser el root) sin saber su clave.
Tener una clave independiente de root, compartida según tú, es una locura que te obliga a rotar esa clave cada dos por tres, por ejemplo porque se va (o despides) a un empleado que la tiene.
En mis servidores, no hay clave de root. Ni de ningún usuario, vamos. Claro que tampoco hay acceso directo en consola (no hay ningún usuario con el que puedas hacer login).
Es que eso es lo que yo veo mal: que con una sola clave hagas de usuario y también de root. Es más seguro que necesites dos claves diferentes.
En mis servidores, no hay clave de root
Yo sí tengo clave de root pero solo para consola. No permito login como root por SSH (en el /etc/sshd_config pones permit-root-login without-password). De esa forma por SSH nunca se puede entrar como root a no ser que sea con clave RSA, pero desde la consola sí, por las dudas.
A los usuarios sí les permito entrar por SSH con clave porque de todas formas al no tener sudo, necesitan saber una segunda clave (la de root) para poder hacer algo peligroso (con su). En algunos servidores he agregado un tercer paso: claves de un solo uso con Google authenticator (o cualquier otro compatible)
"Y lo que dices de ansible escapa el topic que estamos tratando"
¿que se escapa del topic, por qué exactamente, cómo lo resuelves sin sudo o sin become?
"aún así soy RHCE, si tienes alguna duda en concreto del tema te la puedo resolver por privado."
jajajajajajajajaj. No hace falta, gracias.
Como comentas tienes el parámetro become, el cual puedes configurar a tu gusto con become_method para elegir el método de escalada de privilegios. Pero ya me dirás tú que sentido tiene esto que estás preguntando cuando tu intento de flameo ha empezado porque he comentado a un usuario una de las diversas maneras de ejecutar con privilegios en linux. ¿A que quieres llegar, a que sudo es el método por defecto de ansible y por eso es mejor?
no, a lo que quiero llegar es a lo que comenté dos comentarios atrás, y yo no flameo, respondí a un usuario que decía que sudo es una "aberración" para la seguridad y que no debe usarse nunca, yo le respondí que en ciertos casos es mejor sudo que la alternativa, y entonces llegaste tú a dar lecciones que nadie te ha pedido y a tirarte el rollo con tus aires de superioridad.
Si no yo no hubiera entrado.
Pero eso no invalida que el mecanismo de bit suid existe, que es necesario a día de hoy ya que por ejemplo sudo y su lo necesitan, y que en ciertos casos se puede usar, no necesariamente dejando binarios con el bit activado al alcance de cualquiera, sino en un path solo accesible a x usuario.
Es que eso no lo ha dicho nadie, o yo no al menos.
No diciéndole la clave de root...
Esa es la necesidad que yo veo de que haya claves diferentes para usuarios y para root. Que se requieren siempre dos claves para tener privilegios.
¿O cómo das acceso durante unas horas para hacer algo concreto?
¿Y cómo sabes qué usuario concreto ha hecho algo?
Para hacer algo concreto justamente existe sudo. Se le da permiso para una aplicación en particular, no para todo. De esa forma te aseguras de que no tocará nada que tu no quieras que toque y reduces casi a cero la posibilidad de que meta una puerta trasera.
Nunca se debería permitir sudo a "*". Siempre tiene que ser a programas concretos. Si tiene que ejecutar varios comandos, le haces un script y le das sudo para ese script solamente.
¿Cómo haces la auditoría?
Deshabilitando su cuenta personal. Recuerda que como yo lo uso, siempre se requieren dos claves. No se puede entrar directamente como root a no ser que sea por la consola local. Por SSH cada usuario tiene su propia clave y después, si necesita, hace su.