Centralizando sshPublicKey en Active Directory
Si contamos con varios usuarios que necesitan acceder remotamente a la CLI (Command Line Interface) de uno o mas servidores, existe una gran probabilidad de que terminemos implementando el servidor OpenSSH. El acceso más utilizando y más inseguro es mediante la combinación usuario y contraseña.
Para mejorar la seguridad y evitar ataques ddos al servicio ssh, se suele utilizar un certificado para comprobar la validez del usuario que establece la sesión. Por lo cual si por algún motivo un atacante se hace con las credenciales del usuario (por ejemplo mediante un keylogger) no podrá establecer una sesión remota a los servidores que el usuario tiene permitido. Por no contar con su llave privada del certificado.
A nivel administrativo, la manera tradicional todo usuario deberá contar con un certificado que deberá ser cargado en cada uno de los servidores a los que tiene autorizado acceder. El sustituir un certificado, implicaría realizar la sustitución de la llave publica anterior por la del nuevo certificado.
La baja de uno o mas usuarios implicaría eliminar las llaves publicas correspondientes en todos los servidores agregados.
Reemplacemos la manera tradicional con una gestión centralizada mucho mas sencilla. En donde almacenaremos la llave publica como un atributo (sshPublicKey) en el objeto del AD correspondiente al usuario.
Entendiendo LDAP
Active Directory esta basado en LDAP (Lightweight Directory Access Protocol), el cual esta diseñado en el estándar X.500 creado por las organizaciones ISO (International Organization for Standarization) e ITU (International Telecommunication Unión) en 1988. Para entender como funciona el esquema de AD, necesitamos los conceptos básicos de X.500.
El estándar X.500 especifica que las clases de objetos individuales en una organización deben estar definidas de manera única utilizando un proceso de identificación. Este proceso debe ser capaz de agregar a una cuenta una clase que al mismo tiempo puede heredar atributos de otras clases. También deberá ser capaz de definir y exportar clases personalizadas.
X.500 define un OID (Object Identifier) único dentro de cada esquema de objetos. El OID esta compuesto de dos partes:
- Identificación de la ruta única hacia la rama de una estructura de datos del tipo árbol donde se almacena el objeto en X.500.
- Identificación del objeto dentro de la rama del árbol.
La anotación OID utiliza enteros para identificar a cada rama y objeto. Por ejemplo:
1.3.6.1.4.1.3385.12.497
La única referencia al objeto 497 en la rama 1.3.6.1.4.1.3385.12. La rama 1.3.6.1.4.1.3385.12 esta contenida en la rama 1.3.6.1.4.1.3385, y así sucesivamente hasta llegar a la raíz.
Figure 1 - Ejemplo Árbol OID
Figure 1 - organizationalPersonal Schema class properties
Entendiendo Active Directory
Dentro de Active Directory podemos encontrar a las Unidades Organizacionales (OU). Una OU es como una carpeta, que almacenan información y están diseñadas para organizar todo los tipos de recursos disponibles en Active Directory. Como usuarios, computadoras, impresoras e incluso otras OU.
Fuente: Active Directory Bible
Cada uno de esos objetos tiene diferentes tipos de atributos identificados por su OID. Veamos por ejemplo el objeto User Accounts tiene los siguientes atributos:
Fuente: Active Directory Bible
Aquí es donde entra en juego nuestra arquitectura para centralizar sshPubKey, nuestro objetivo sera incorporar al objeto User Account un atributo adicional al que llamaremos sshPubKey, en el cual utilizaremos para almacenar los diferentes llaves publicas que estén asociado con el usuario. Está sera nuestra fuente de verdad para la validación de cada llave privada que sea utilizada para establecer una sesión por ssh por parte de un usuario. De esta manera no tenemos que estar gestionando de manera "manual" la llave publica en el directorio personal de cada usuario en los servidores.
Extendiendo un esquema con LDIF
La manera mas común de extender un esquema es mediante LDIF (LDAP Data Interfhange Format) especificado mediante el RFC 2849, donde se establece la manera de representar datos de un directorio en un archivo de texto con una codificación human-readable.
Se pueden exportar,agregar,modificar y eliminar datos de Active Directory en formato LDIF.
Ejemplo de archivo LDIF para agregar un objeto del tipo grupo a un Usuario.
dn: cn=mygroup,cn=users,dc=mycorp,dc=com
changetype: add
objectclass: group
description: My Group
member: cn=administrator,cn=users,dc=mycorp,dc=com
member: cn=guest,cn=users,dc=mycorp,dc=com
Extendiendo un esquema con LDIF en SAMBA AD
Cómo la implementación de Active Directory que se estará utilizando es mediante el software Samba, hay que tener en consideración que la modificación del esquema, puede ser bastante problemática y se tiene que analizar en profundidad las configuraciones que sean aplicadas con respecto a esquemas. Dada la implementación actual de Samba, solo permiten agregar y editar esquemas, pero no eliminarlos.
Samba provee a modo de referencia los siguientes ldif para la creación del atributo sshPubKey:
dn: CN=sshPublicKey,${SCHEMADN} changetype: add objectClass: top objectClass: attributeSchema attributeID: 1.3.6.1.4.1.24552.500.1.1.1.13 cn: sshPublicKey name: sshPublicKey lDAPDisplayName: sshPublicKey description: MANDATORY: OpenSSH Public key attributeSyntax: 2.5.5.10 oMSyntax: 4 isSingleValued: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} searchFlags: 8 schemaIDGUID:: cjDAZyEXzU+/akI0EGDW+g== dn: CN=ldapPublicKey,${SCHEMADN} changetype: add objectClass: top objectClass: classSchema governsID: 1.3.6.1.4.1.24552.500.1.1.2.0 cn: ldapPublicKey name: ldapPublicKey description: MANDATORY: OpenSSH LPK objectclass lDAPDisplayName: ldapPublicKey subClassOf: top objectClassCategory: 3 objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ldapPublicKey,${SCHEMADN} mayContain: sshPublicKey schemaIDGUID:: +8nFQ43rpkWTOgbCCcSkqA==
Ambiente de pruebas
Estaremos implementando la siguiente topología, en la que tenemos implementado un Active Directory en Samba y tenemos los servidores ya unidos al dominio. Con lo cual podemos acceder desde cualquier equipo de nuestra red con las credenciales correctas de un usuario que pertenezca al grupo de ad llamado Unix Admins.
De la manera tradicional, tendríamos que generar un certificado para el usuario(por ejemplo mediante la aplicación ssh-keygen) y como mencionábamos al inicio replicar la llave publica en los perfiles de cada usuario de todos los servidores a los que se necesite acceso.
Ahora veamos como podemos centralizar esta sshPubKey.
1) Aplicar LDIFF en el servidor
2) Mostrar el nuevo atributo
3) Cargar la llave publica
4) Verificar valor del atributo mediante ldapsearch
5) Editar sssd con las configuraciones necesarias en los servidores srv01
5) Reiniciar el servicio y verificar con sss_ssh_authorizedkeys
The End