Por qué Directory administrator
Directory administrator es la herramienta que desarrollé para administrar usuarios y grupos UNIX en servidores de directorio. Es la más popular para su propósito, y ha tenido más de 15000 descargas, contando solo el código fuente.
En este documento, exploraremos la necesidad de Directory administrator, paso a paso, sus orígenes y detalles técnicos. Comencemos por entender un poco cómo fue la autenticación en el mundo UNIX en sus principios.
Si conoces UNIX y su historia, o lo viviste personalmente (en cuyo caso me ganas como por 30 años y 10 terminales tontas) anda directo a la descripción larga de Directory administrator.
Operación multiusuario con UNIX: los comienzos
UNIX y sus clones poseen la capacidad de operar múltiples usuarios simultáneamente (control de acceso discrecional - discretionary access control), y, como control de acceso, ha requerido contraseñas para permitir el acceso a estos usuarios. Adicionalmente, cada usuario es miembro de uno o más grupos, que determinan los privilegios de acceso a los objetos disponibles para el sistema operativo (en UNIX, por tradición, todos los objetos son archivos).
El uso de contraseñas planteó varios problemas originalmente:
- dónde guardar la información de los usuarios y grupos
- cómo guardarla de forma segura
La solución inicial consistió en guardar las contraseñas y la información de los grupos en dos archivos planos: /etc/passwd y /etc/group. Las contraseñas se guardaban encriptadas en el archivo /etc/passwd, es decir, con una función de hashing (DES o Crypt) que no permite que, a partir del hash, se recupere la contraseña, excepto con un ataque de fuerza bruta. Cada usuario tenía un UID asignado: un entero que servía de clave primaria para la verificación del acceso; este entero es el dato que se guarda junto con un archivo en el sistema de archivos.
Con el avance de capacidad de procesamiento, el hashing original se volvió muy vulnerable a ataques de fuerza bruta y se extendió la solución mediante el uso de hashes MD5 y la separación de la contraseña en un archivo separado, /etc/shadow legible sólo para root (el superusuario). Los procesos que pretendían usar la información en /etc/shadow debían iniciarse con privilegios de acceso de superusuario.
Sin embargo, siendo la solución técnicamente apropiada para los problemas de la época, no se pensó que el modelo de la computación cambiaría de minis y mainframes al uso de las LANs. Veamos qué sucedió con el advenimiento de las PCs.
Operación multiusuario en LANs: problemas nuevos
El advenimiento de las LANs trajo su propio juego de problemas. ¿Cómo acceder archivos en un servidor distinto a otro? ¿Cómo evitar al usuario recordar una contraseña distinta para cada servidor?
Sun Microsystems inventó Network Information Service (NIS) y Network File System (NFS), como soluciones al problema de autentificación/autorización y transferencia de archivos. NIS transparenta la autentificación y NFS transparenta el acceso a archivos.
NFS
Rrecordemos que el UID del usuario tiene que ser consistente entre los servidores que comparten y usan archivos. Un escenario: rudd-o trae su laptop y la conecta a la red local, montando un volumen compartido con NFS desde el servidor. Puesto que rudd-o es dueño de su laptop, puede esperarse que tenga UID 0 (el superusuario), y NFS le otorgará acceso de superusuario a los archivos en el volumen compartido. Esto es aún más peligroso de lo que parece, pues rudd-o podría instalar un programa en el volumen compartido y hacerlo set-uid (al ejecutarse, adquirir los privilegios del dueño). Ahora, con solo ejecutar el programa desde el servidor de archivos, rudd-o tendría privilegios de superusuaro en el servidor de archivos.
En esencia, NFS confía en el cliente. Mecanismos adicionales se inventaron para evitar elevación de privilegios (no_root_squash, nosuid), pero aún así se requiere que los UIDs de los usuarios sean consistentes entre el cliente y el servidor.
NIS
NIS soluciona ese problema, ¿no?. No. NIS provee una forma de forzar la consistencia de los objetos de seguridad en la red, pero el transporte de las contraseñas se realiza a través de la red en texto sin cifrar, lo cual hace que la solución sea peor que el problema original.
Problemas adicionales de NIS incluyen:
- falta de herramientas administrativas fáciles de aprender (se usan los comandos estándar de UNIX para administración de usuarios)
- escalabilidad limitada según el tamaño de la base informática donde se aplique la solución
Una solución a los problemas
Definamos los problemas que aparecieron con las LANs:
- los usuarios no pueden utilizar su misma contraseña en distintos servidores sin cambiarlas todas al unísono
- los administradores deben mantener cuentas de usuario/grupo duplicadas en cada servidor
- los administradores deben procurar manualmente la consistencia de los objetos de seguridad existentes en los nodos de la red
- la consistencia, seguridad y escalabilidad de las soluciones existentes no están a la par de las demandas en la práctica
Una solución al problema debe atacar los puntos anteriormente descritos; en esencia, lo que se busca es una forma de homogeneizar los objetos de seguridad en una red, para que un objeto que representa un usuario/grupo en un nodo represente el mismo usuario en otro nodo.
Adicionalmente, de la solución se requiere implícitamente:
- escalabilidad
- tolerancia a fallos
- facilidad de uso y aprendizaje
- seguridad
- base en estándares Internet
- interoperabilidad
La solución requiere de los siguientes componentes:
- un almacenamiento de objetos de seguridad (object store) tolerante a fallos
- una infraestructura genérica para utilizar objetos de seguridad locales y remotos
- un juego de herramientas administrativas por lotes
- una herramienta administrativa de interfaz humana (en este caso, gráfica)
Almacenamiento de objetos
Tratemos el asunto del almacenamiento de objetos:
LDAP (Lightweight Directory Access Protocol) es un servicio de directorios; dicho más claro, es una base de datos que guarda objetos en un árbol (como los directorios en un volumen de disco duro). LDAP nació como un subjuego simple de X.500 (una cuestión complicadísima que ni yo entiendo). OpenLDAP es el servidor de directorios libremente disponible más popular.
LDAP provee la infraestructura necesaria para guardar objetos, entonces, ¿por qué no usarlo para guardar información de UNIX? Luke Howard definió en RFC 2307 la estructura para guardar información UNIX en el directorio, que subsiguientemente se convirtió en un estándar de facto. Además, estos mismos objetos pueden contener información de muchos otros tipos, como información corporativa de una persona e información de contacto.
Además, OpenLDAP y otros servidores LDAP poseen la habilidad de servir mediante conexiones cifradas (SSL/TLS) y además permiten definir políticas de restricción de acceso a la información de los objetos de seguridad. También existen múltiples niveles de acceso, que permiten delegar la administración de grupos de usuarios a particulares.
Hoy día, muchas aplicaciones tienen la capacidad de usar la información en un directorio LDAP (por ejemplo, Microsoft Outlook y Ximian Evolution están en capacidad de usar el directorio como una libreta de direcciones compartida).
Infraestructura de seguridad
Sun pensó que, al desarrollar NIS, sería un error deshacer la infraestructura en sitio para utilizar archivos de autenticación. En su lugar, decidió modularizar el acceso a los objetos de seguridad y la autenticación, y llamó a cada subsistema NSS (Name Service Switch) y PAM (Pluggable Authentication Modules). Esto permite escribir módulos particulares que extienden la funcionalidad del sistema operativo.
GNU/Linux adoptó la misma infraestructura. En poco tiempo, PAM se hizo muy popular, de suerte que hoy existen varios métodos maduros de autenticación, entre los cuales existen módulos para LDAP: pam_ldap y nss_ldap.
pam_ldap y nss_ldap hacen su trabajo en tándem. pam_ldap verifica las contraseñas y credenciales suministradas por el usuario contra el servidor LDAP, y nss_ldap asigna la información de seguridad (UID y demás) de los usuarios al momento de iniciar sesión, o bajo demanda. El nivel de madurez es tal, que casi todos los sistemas operativos UNIX tienen herramientas administrativas que permiten designar un directorio como fuente de los objetos de seguridad, configurando todo el sistema automáticamente.
Herramientas de administración por lotes
Hoy hay un juego de comandos estándar en UNIX que permiten administrar usuarios y grupos. Estos comandos agilitan el procesamiento por lotes (en tradición UNIX de componentes pequeños y específicos) y proveen una interfaz a los objetos de seguridad. Muchas utilidades del sistema dependen de ellas, y son tan importantes que están definidas en el estándar POSIX y en el estándar Single UNIX Specification.
Múltiples esfuerzos coordinados por varios grupos de desarrolladores lograron desarrollar interfaces de proceso por lotes en reemplazo de las ya existentes (adduser, deluser, addgroup, delgroup) que trabajan usando el directorio LDAP y clonan la interfaz de esos comandos.
El esfuerzo más avanzado es el de Red Hat, que con su Red Hat Linux 8 define una librería general estándar de administración de usuarios y grupos, haciendo que el desarrollo de herramientas administrativas sea sencilla y el resultado de este desarrollo sea una herramienta que funcione automáticamente contra cualquier back-end.
Podría ser que Mac OS X haya superado a Red Hat en este aspecto, ya que hoy día, es la única implementación de UNIX que utiliza por defecto un servidor LDAP local como almacenamiento de objetos de seguridad. Sin embargo, el administrador de usuarios de Mac OS X deja mucho que desear.
Directory administrator
Podría decirse que integrando los componentes anteriormente descritos alcanzamos el Nirvana de la autenticación y la autorización distribuida. Es decir, se lograron los objetivos a cabalidad.
Esto sería un error. El usuario y el administrador de hoy día espera una interfaz a su sistema operativo sencilla de aprender y usar, que no transparente los detalles técnicos, y que permita la delegación de la administración. Esto en parte por la evolución de los sistemas operativos a interfaces gráficas, y la competencia de otros sistemas operativos (Microsoft Windows NT).
El problema es que para el tiempo en que todos los componentes estaban maduros, no existía una interfaz gráfica para administrar usuarios y grupos UNIX, mucho menos una libremente disponible.
Entonces comencé a desarrollar Directory administrator como software libre, y a todas luces ha sido un éxito. En el afán de la transparencia, el motivante principal para desarrollar la herramienta fue una labor de integración en la compañía TIOSA, que quería implementar esta infraestructura, pero motivos ajenos al proyecto mantienen esta labor de integración a medias.
Sin embargo, Directory administrator está, a juzgar por múltiples e-mail que he recibido, en producción en varias partes, y he recibido algunas solicitudes de cambio y mejora del extranjero (nunca pensé que recibiría ingresos como parte del desarrollo), así como parches, ideas y reportes de errores. Me ahorré un contingente de pruebas y gané desarrollo gratis al distribuirlo como software GPL.
Un par de estadísticas e indicadores: tengo 28 bugs arreglados registrados en el bug tracking system, Directory administrator viene en Mandrake Linux, Conectiva, Debian, la página del proyecto en Freshmeat.net tiene 29,853 accesos, ha experimentado más de 21000 descargas (sólo en código fuente, sin contar los paquetes compilados).
Para qué se puede usar Directory administrator
Directory administrator tiene la capacidad de crear, remover y modificar usuarios y grupos existentes en el directorio LDAP.
Es de interés para un trabajador una compañía poder consultar con su cliente de correo la información de contacto de uno de sus colegas (en la práctica, él escribe parte de nombre de su colega en el campo De:, y la aplicación automáticamente lo busca en el directorio y completa la dirección de correo).
Puesto que el directorio ya posee la habilidad de almacenar distintos tipos de información con respecto a un solo objeto, cupo incluir en Directory administrator el soporte para la información más frecuentemente referida con respecto a cada objeto.
Aspectos técnicos
Directory administrator es una aplicación GNOME. Al desarrollar, por mi experiencia en programación, pensé en varios lenguajes, y me decidí por el más distribuido. El juego de herramientas de desarrollo GNOME me permitió crear interfaces gráficas muy atractivas y fáciles de usar, y el grueso de aplicaciones GNOME está desarrollado en C. La elección de C fue natural, aunque podría generar problemas de crecimiento a futuro.
Directory administrator hace uso de las bibliotecas LDAP del sistema para comunicarse con el servidor LDAP.
Influencias de diseño
Desde el principio tuve claro que tendría que construir una aplicación fácil de usar y aprender. Esto porque mi audiencia objetivo era el usuario no técnico, sino más bien administrativo - el usuario final corporativo. Esto influenció el diseño en los siguientes aspectos:
- se minimizó el uso de términos técnicos, que transparenten la infraestructura por detrás al usuario
- se construyó una interfaz sin elementos extraños, usando sólo controles estándar de la biblioteca de elementos de interfaz de usuario
- se intentó automatizar cualquier proceso que pudiera automatizarse, y se proveyeron controles para modificar los valores predefinidos, de una forma clara y concisa
- se usaron metáforas fáciles de interiorizar (listas de iconos, barra de herramientas con pocos botones, hojas de propiedades, arrastrar y colocar)
- se maximizó la navegación por teclado (aunque limitaciones de la plataforma no permiten una navegación completa por teclado)
Qué falta por hacer
Queda aún:
- internacionalizar el software
- escribir la documentación de usuario
- mejorar la aplicación para su uso en directorios gigantescos: he tenido un par de solicitudes, una de las cuales estoy atendiendo en este minuto (para Mesa Inc.), para mejorar el uso de la aplicación con directorios de más de diez mil objetos. En este momento, trabajar con una sola vista de iconos y diez mil objetos es un poquito problemático.
Estoy investigando reescribir la aplicación en Python, un lenguaje orientado a objetos con soporte multiplataforma, excepciones, colección de basura y código interpretado/compilado para VM. Python es un lenguaje maduro, muy usado y extensible, pero su mayor virtud es la rapidez con la que se desarrolla. En este momento, la infraestructura ya está desarrollada, en, estimo yo, aproximadamente 1/10 del tiempo de haberla hecho en C.