¿Cuáles son las implicaciones de seguridad de systemd en comparación con systemv init?

15

Estoy empezando a aprender sobre el sistema init, así que solo conozco las características de alto nivel de ambos.

He notado un montón de problemas con el sistema, incluso algunas personas que afirman que el sistema fue creado para introducir intencionalmente vulnerabilidades!

El argumento que veo con más frecuencia es que systemd introduce un vector de ataque nuevo, grande (y desconocido). Por otro lado, me parece que un sistema como systemd es en realidad algo bueno porque es un código estandarizado en lugar de scripts de inicio ad-hoc. En este sentido, veo similitudes con el kernel. Claro, todos pueden crear su propio sistema operativo fácil de leer, pero ¿no es mejor reutilizar el mismo código para que una gran cantidad de globos oculares lo estén monitoreando?

¿Estoy en el camino correcto aquí? ¿Hay problemas que no estoy considerando?

    
pregunta nur0n0 17.08.2017 - 21:00
fuente

3 respuestas

16

(en su mayoría) las personas no inyectan vulnerabilidades deliberadamente, ocurren por accidente. A medida que aumenta el volumen de código, aumenta el número de defectos. Pero no es solo el tamaño: el número de errores aumenta con la complejidad del código y aumenta más rápido que de forma lineal. Así que más código es una mala noticia para la seguridad.

La superficie de ataque de systemd es mucho más grande que initd, la configuración predeterminada tiene múltiples interfaces.

Una gran molestia para mí es la filosofía de diseño; la intención es que systemd proporcione una forma más unificada para que los distribuidores integren servicios. Pero esto significa eliminar el control sobre el sistema de los administradores de sistemas (más allá del impacto de reemplazar un ecosistema complejo pero bien entendido). Deliberadamente, es difícil o imposible lograr algo que podría hacerse con initd (tenga en cuenta que hay muchas opciones para los administradores de servicios que se ejecutan bajo initd - djb daemontools, upstart, initng, rund, procd, openrc ... La mayoría de los cuales resuelven los problemas de paralelización / dependencia que limitan el sistema sysv rc init).

Gran parte de la lógica de la puesta en marcha de un sistema Unix se implementa en shell scripts. Esto hace que sea mucho más fácil no solo realizar una ingeniería inversa de la operación, sino también instrumentarla y ampliar las capacidades. Systemd mueve más lógica a binarios y se basa más en una configuración compleja y mal documentada .

La combinación de una reducción deliberada del nivel de control por parte del administrador del sistema y la falta de asistencia al administrador del sistema en su tarea hace que sea más difícil para ellos realizar su trabajo, lo que incluye garantizar la seguridad del sistema.

Una consecuencia adicional de toda esta complejidad en PID 1 significa que debe reiniciar el sistema con mucha más frecuencia. Además del impacto en la disponibilidad, esto también significa mover su sistema a través de una serie de estados interinos, que pueden exponer temporalmente las vulnerabilidades que son difíciles de detectar en un sistema homeostático. El uso de daemon-reexec para solucionar esto trae un nuevo conjunto de problemas.

El modelo de dictador benevolente para la vida parece funcionar bien para el kernel de Linux, pero no es así como funciona el resto de la industria del código abierto. De hecho, tal vez sea la excepción la que prueba la regla: el código abierto funciona porque nadie está a cargo, no a pesar de que nadie esté a cargo. Systemd asume el control sobre un lote de la funcionalidad en un sistema Linux, sin embargo, funciona como una comunidad relativamente pequeña. Y de acuerdo con el premio pwnie parece ser algo interno: no hay mucho de globos oculares en el código: nadie escucha cuando se plantean inquietudes sobre el código.

    
respondido por el symcbean 18.08.2017 - 00:33
fuente
5

Systemd es en realidad una colección de varias partes, y para que una comparación tenga sentido, debes comparar las partes que realmente corresponden entre sí.

Primero veamos el inicio de SysV: este es un programa muy pequeño que se ejecuta como el primer proceso después del arranque que realiza una configuración muy básica, luego lee un archivo de configuración ( /etc/inittab ) e inicia uno o más programas configurados en él. , opcionalmente reiniciándolas al salir. También abre algunos canales de comunicación ( /dev/initctl , manejadores de señales) que hacen posible cambiar el nivel de ejecución actual, un cambio del cual dará como resultado que se ejecuten algunos otros programas, nuevamente como está configurado en /etc/inittab .

Y eso es todo. Obviamente, esto no tiene una gran superficie de ataque, simplemente porque no hace casi nada. En el lado opuesto, todo lo que se requiere para administrar realmente un sistema típico se delega a programas externos: cómo iniciar y detener un servicio específico (por ejemplo, servidor web, base de datos, red ...), dependencias entre servicios (es decir, iniciar la base de datos primero) , solo entonces el servidor web), monitoreo más complejo (funcionalidad de vigilancia), eliminación de privilegios y sandbox, activación de servicio a pedido (por ejemplo, inetd), montaje de sistemas de archivos, ... Systemd integra gran parte de esta funcionalidad y, por lo tanto, es más complejo.

Ahora, integrar estas cosas en un lugar central tiene un gran potencial para reducir la complejidad y la fragilidad en general y, por lo tanto, hacer que el sistema sea más seguro. Tome las diversas funciones de "sandboxing", incluida la eliminación de privilegios, el acceso restringido a ciertos directorios, directorios temporales privados, espacios de nombres separados, aislamiento de red ... Para systemd, estos son bastante fáciles de implementar como parte de la configuración del entorno de servicios, que - Como administrador de servicios - Hay que hacerlo de todos modos. En contraste, con SysV init, tendría que usarse un programa separado; en la práctica, esto sería un conjunto de scripts de shell o se integraría en los servicios individuales, extendiendo así el código "arriesgado" en más lugares.

Además, systemd proporciona al administrador del sistema los medios para configurar estas funciones fácilmente (unas pocas líneas en un archivo de configuración), evitando que tengan que implementarlas ellas mismas (¡que en algunos casos incluso pueden implicar la modificación y recompilación de servicios!) . Por supuesto, en la práctica esto significa que no se usan en absoluto. Desde un punto de vista de seguridad, el formato de configuración de estilo ini también es una ventaja sobre los scripts de shell completos que se utilizan con SysV init.

En cuanto al modelo de desarrollo detrás de systemd: veo esto como una ventaja en comparación con la alternativa, porque hay un lugar central donde ocurre el desarrollo (¡y extensas pruebas!), que contrasta con la mezcla anterior de la mayoría de la distribución específica código. Incluso el núcleo inicial de SysV difería entre las distribuciones, ya que su flujo ascendente puede considerarse muerto. Y al contrario de lo que otros dicen, Systemd upstream es en realidad muy receptivo y está abierto a solicitudes de cambio razonables.

Dicho esto, puedo ver una situación en la que las cosas son diferentes, que es cuando las funciones proporcionadas por systemd no son necesarias, por ejemplo, si desea construir un enrutador o una puerta de enlace de red simple donde el conjunto de servicios necesarios es Conocido de antemano y nunca cambiará. Incluso allí, es posible que desee aprovechar las funciones de caja de arena fáciles de usar, y este es un caso especial que no se aplica a la gran mayoría de los sistemas.

    
respondido por el Marc Schütz 20.08.2017 - 11:57
fuente
-1

En cuanto a la cosa de los globos oculares: históricamente los guiones de init RC en el núcleo de RHEL y el clon de inicio "SYS V" básico, no era algo que se escribiera con una robustez extrema en mente, no es como lo hicieron en una pizarra. diseño de la máquina de estado allí. Y no habrías podido enviar parches para él en la mayoría de las principales distribuciones. Si no hay ninguna especificación escrita y un diseño real de sw en tu inicio, verás que la gente tiene miedo de cambiarlo.

Sin embargo, el impacto de la fragilidad era bastante bajo, al igual que el tamaño de las tareas individuales. Ejecutar un script. Ejecutar el siguiente. No tengo ningún archivo temporal. Ser apátrida internamente, excepto por un contador de carreras que hace que las cosas vayan hacia el "objetivo" deseado o hacia el opuesto.

No había interfaces excepto el comando init o telinit. En un unix adecuado, un init 0 simpy termina a init, dejándote en el limbo. Linux (para mayor comodidad y facilidad de uso para las personas que no leen un manual) ya se había alejado del diseño simplista, y parece que nunca se tuvo en cuenta (lo siento) que el clon init debería ser una especie de "MIL -SPEC "calidad.

Ahora estamos teniendo lo mismo, y nuevamente, esas preocupaciones no son las más importantes, pero ahora toma una parte mucho más importante en el procesamiento de las tareas, en la forma en que interactúa con el kernel, en el sentido de que es accesible a usuarios no root. usuarios y en el que procesa la entrada fuera de cuando se realiza una tarea de inicio.

Esas son meras diferencias. El problema es que, de nuevo, aspectos como el endurecimiento o la falla del estado operativo seguro / fallido no se consideran elementos fundamentales. Hay algunas medidas en esa dirección (es decir, si se resuelven, reaparecen automáticamente si el tráfico malicioso las abandona) pero no mucho .

Ahora asumamos que el proceso de desarrollo y la capacidad de respuesta ante las inquietudes cambiarían. Eso sería genial. (después de haber trabajado con algunos en su alternativa, no creo que sucediera, ya que ninguno de los otros ha sido hostil de ninguna manera)

Entonces nos quedamos con un problema: la cosa de muchos globos oculares es cuestionable. En el sistema de inicio normal, debido a la falta de interfaces, el "vector de ataque" está implementando un script de inicio, que solo la raíz puede hacer. Luego se le permite hacer lo que considere necesario, y usted está a merced del autor en lo que respecta a la eliminación de privs. Si él sabe cómo usar su, será su, si no lo hace será sudo, y así sucesivamente. Pero la única forma en que atacará su sistema de inicio es si pone algo allí que sobrescriba el binario / script. Ni siquiera lo "persistirá" dentro , ya que cualquier variable que exportaría se aplastaría cuando se ejecute el siguiente script. El lenguaje (sh, idealmente, solo POSIX) es hasta el punto en el que obtuvo un segundo agujero por cada 10 años, y normalmente ninguno. Y, quiero enfatizar eso un poco, simplemente hay muy poco para atacar y no hay forma de que pueda atacarlo después de que el sistema haya terminado.

Esas diferencias están ahí. Pueden ser motivo de preocupación o no. Pero el argumento de "base de código compartido" es en su mayor parte discutible. El argumento de que se deshace de los envoltorios de priv priv drop tiene dos puntos de discusión. uno, que son malos diseños (nat nat es una cosa) o necesidades (ssh) y dos, que en el mundo británico hemos aprendido que para cualquier problema relacionado con la seguridad debemos priorizarlo entre nuestros peores problemas, y más bien Exagerar resolviéndolo que no. Esto no está pasando.

En este momento, pocas personas están buscando exploits, pero no es como este es un tema interesante para los investigadores de la sección. Una vez que eso sucede y se reúne con una base de miles de millones de dispositivos instalados que no se están parchando, estoy un poco preocupado. Podríamos tener beneficios en el mundo de la tecnología. Para las personas que se benefician de lo que sea que hagan nuestros sistemas, hay beneficios en la medida en que el reinicio automático de los servicios se está volviendo más común (porque aparentemente fue demasiado difícil de leer en daemontools para configuraciones que no son de alta disponibilidad), pero no quiero estar cerca Y necesitamos justificar si repetimos alguna mierda como CodeRed en nuestro inicio.

Mostrar cómo apagar ahora a diferencia de la huella de un solo script de shell (!) que se ejecuta en el arranque. La contramedida se ha vuelto un poco más complicada. Y en cuanto a daemon-reexec, todavía me pregunto por qué un zypper ps -s todavía vería las partes antiguas de systemd en la memoria posteriormente.

He omitido la comparación con SMF, uno de los desarrolladores de systemd llamado "Solaris" o algunos paralelos a AIX, como el registro binario y el SRC. SMF tuvo un proceso de diseño muy abierto, inclusivo, reflexivo y documentado, y creo que esa es la gran diferencia. No tengo idea de cómo eso será remendado.

    
respondido por el Florian Heigl 20.08.2017 - 04:38
fuente

Lea otras preguntas en las etiquetas