jueves, 6 de octubre de 2011

La obsolescencia del modelo Unix

La obsolescencia del modelo Unix:
Mucho ha llovido ya desde que Ken Thompson y Dennis Ritchie alumbraran en 1969 el sistema operativo Unix, padre de, entre otros, el sistema operativo Linux.


Conceptualmente, el modelo 'Unix' se basa en que, frente a programas multi-función con múltiples funcionalidades en un mismo programa, se apuesta por un amplio juego de comandos especializados que trabajan de forma cooperativa entre si.


Cualquier persona que haya usado durante algún tiempo Linux, le sonará la famosa 'pipe' | que permite concatenar la salida de un comando hacia otro y en base a eso, construir complejos comandos para generar una tarea.


Yo siempre he sido defensor convencido de ese modelo, de hecho en las ocasiones que me ha tocado desarrollar para un entorno Windows (que por norma general promueve justo lo contrario, programas multi-disciplinares y el uso intensivo de hilos), me ha tocado enfrentarme a equipos 'nativos' que han mostrado oposición al modelo que yo defendía.


Generalmente, una vez explicado que desarrollar en modo-Unix tiene la ventaja de aislar los componentes evitando que el fallo de uno tire al resto, y que a la hora de depurar errores, resulta mucho mas sencillo aislar problemas, he terminado por salirme con la mía, y en los casos en los que no, he cedido de muy mala gana.


Pero visto el panorama actual de Linux, me veo obligado a replantearme mis principios. ¿Motivo? hacer las cosas tan modulares no es escalable y desde el punto de vista de la seguridad, un entorno actual Linux es ingobernable.


Dos ejemplos:


Sistema Linux actual, con un entorno gráfico cargado, un navegador, procesador de texto, cliente de mensajería y algunas consolas abiertas:


$ ps aux | wc -l
293


Mismo entorno bajo Windows (evidentemente y por definición NO es idéntico)


>tasklist /svc | find /c /v "zzzzzzzzzzzzzzzzzzzzzzzzzz"
61


** Este comando lista los procesos y le entrega la salida al comando Find, el flag /c cuenta el total de líneas y el /v excluye toda línea que contenga "zzzzzzzzzzzzzzzzzzzzzzzzzz" con lo que el comando significa: cuenta todas las líneas que no tengan ese patrón lo que a la postre da el total de procesos ya que ninguno se llama así


La diferencia es evidente: 293 procesos VS 61. Absolutamente imposible de gestionar desde el punto de vista de la seguridad. De hecho, tengo muy claro que a día de hoy, en caso de 'rootear' un sistema Linux, mas que plantearse que rootkit es mejor o peor, resulta mucho más fácil buscar un nombre inocuo (chrome-plugin-helper, por ejemplo) y hacer que se entierre entre la maraña de procesos.


Más aun, Windows implementa de una forma bastante efectiva el firmado digital de ejecutables, lo que facilita notablemente discernir que procesos son mas o menos sospechosos.


En el caso de Linux, si bien la mayoría de paquetes van firmados con una clave GPG, esto no está integrado en las herramientas de gestión de procesos con lo que tienes que ir a mano (o hacerte un script, como ya publiqué aquí) para que haga esa comprobación.


En muchas ocasiones se ha intentado portar el modelo de firma digital de ejecutables y módulos del kernel, pero casi todos estos proyectos no han entrado a formar parte del kernel oficial y han quedado obsoletos, como por ejemplo DigSig. Por otra parte existen herramientas como bsign pero simplemente están ahí, no se ha seguido avanzando en el concepto


En definitiva, tengo la impresión de que si bien este modelo tan cooperativo era excepcional en entornos tipo servidor con pocos procesos, en entornos tipo workstation está completamente obsoleto.


Linux ha hecho increíbles avances en áreas de rendimiento y optimización de recursos a nivel kernel pero le falta, a mi parecer, avanzar en otras capas.