ACTUALIZACIÓN 30/01/2022: Aunque el método explicado en este artículo para unir a dominio de Active Directory una máquina GNU/Linux sigue siendo válido, te puedes encontrar problemas si necesitas servir archivos por protocolo SMB utilizando Samba. Si este es tu caso te recomiendo revisar el artículo "De SSSD a Winbind: compartiendo archivos por SMB desde GNU/Linux".
ACTUALIZACIÓN 05/04/2020: Agregado un workaround para que funcione la actualización dinámica de DNS, con referencia al artículo original de Microsoft.
Justo como dice el título, y ojo que no hablo de utilizar LDAP para autenticar usuario de Linux con nuestro Active Directory, sino realizar una integración de autenticación adecuada mediante Kerberos. Pero antes de empezar, un poco de historia...
Un poco de historia...
Siempre ha habido necesidades de interoperabilidad entre Windows y Linux, y este no ha sido siempre un camino agradable, en especial para los administradores de sistemas y los desarrolladores que tuvieron que lidiar con estos menesteres en los 90' y en el 2000 (aunque surgieran mitos como Internet Explorer para UNIX. Sin embargo, el escenario es radicalmente distinto ahora, donde los silos tecnológicos se comienzan a disolver con la llegada del Cloud Computing para prestar toda la atención al servicio y no a la tecnología.
Microsoft ha experimentado una apertura inimaginable años atrás donde no sólo Linux es un ciudadano de primera clase en Azure, sino que además existe una certificación concreta en dicha materia. Además, Microsoft empieza a desarrollar software también para Linux, como SQL Server, Visual Studio Code, Storage Explorer o el renovado Skype para Linux.
En medio de todo esto, los administradores de sistemas llevamos ya años enfrentándonos a un reto común, hacer todo lo posible por integrar Windows con sistemas UNIX.
Es lo más común del mundo encontrarnos con implementaciones de infraestructura en Azure donde hay que lidiar por igual con Windows Server y con Linux... Hoy más que nunca sería realmente útil poder unir estas máquinas Linux a nuestro dominio de ADDS y trabajar con una única identidad en nuestros sistemas.
Entrando en materia, un caso de uso con Let's Encrypt
Algo que llevo haciendo desde hace varios meses es integrar Let's Encrypt como entidad certificadora en mi infraestructura. Todas las operaciones con Let's Encrypt se llevan a cabo de forma automatizada mediante una API llamada ACME. El soporte de herramientas para operar con esta API en Windows es espartano y third-party, mientras que Let's Encrypt tiene un cliente oficial llamado Certbot que sólo corre sobre sistemas POSIX (afortunadamente Windows reactiva su POSIX con Bash on Ubuntu Windows, aun en beta).
Así pues, lo mejor para mantener mis certificados al día es establecer una máquina Linux en mi infraestructura que mediante Certbot gestione su corto ciclo de vida (72 días) y los sirva mediante SMB.
Para que todos los servidores Windows puedan consumir y renovar automáticamente las instalaciones de los certificados, se me antoja que esta máquina debe estar dentro del dominio.
Opciones para unir nuestra máquina Linux a Active Directory
Dicho sea que descarto la autenticación LDAP simple y que quiero una integración donde esta máquina de la que estoy hablando, MAD-CERTBOT, tena su Machine Account en el directorio. Las opciones más comunes son:
- Winbind. Con más de 10 años de historia, es un componente de la suite SAMBA que otorga servicios de autenticación a través del Name Service Switch, consultando a un controlador de dominio. A día de hoy es que el que más capacidades de integración soporta, y sería la opción por defecto si no fuera por los caídas esotéricas que sufre y que son muy muy complicadas de depurar. En su haber soporta:
- Confianza entre bosques.
- MS-RPC para hablar con controladores de dominio NT 4.
- Autenticación NTLM en caso de que Kerberos falle.
- System Security Services Daemon (SSSD). Un nuevo proyecto prometedor que se ha convertido en el estándar de-facto en RHEL. No soporta todas las características de Winbind ni tiene todo su recorrido, pero ha demostrado ser bastante más sencillo de configurar y -por ahora- más estable y rápido. Dimitri Pal explica en el blog oficial de RHEL cómo funciona versus las alternativas tradicionales.
- Soluciones comerciales, como Centrify. Que no puedo entrar a valorar porque se salen de mi presupuesto.
Implementado SSSD
Dado que he estado trabajando con Ubuntu Server 16.04.1 LTS, he seguido esta completa guía de configuración que voy a comentar aquí con algunas situaciones que me he encontrado.
¿Qué necesitamos?
Una serie de elementos básicos:
- Un dominio de Active Directory en funcionamiento. En mi caso he utilizado ADDS de Windows Server 2016, en nivel funcional 2012 R2.
- Al igual que ocurre en Windows, la máquina Linux debe estar usando los servidores DNS autoritativos para la zona del dominio.
- La hora del sistema está sincronizada con la de los controladores de dominio. Esto es vital para Kerberos.
- Instalar los siguientes elementos en nuestra máquina: cliente de Kerberos, Samba, SSSD y NTP.
Como podéis ver, Samba sigue haciendo falta, ya que las operaciones con Active Directory las sigue llevando a cabo él, aunque sustituyamos Winbind por SSSD.
En Ubuntu:
$ sudo apt install krb5-user samba sssd ntp
A partir de ahí ya podemos empezar a configurar cada uno de los elementos, ¡va a ser fácil y rápido!
Kerberos
Editamos el archivo de configuración /etc/krb5.conf
y especificamos:
[libdefaults]
default_realm = CALNUS.COM
ticket_lifetime = 24h #
renew_lifetime = 7d
Sólo con esto el sistema debería ser capaz de encontrar los servidores KDC, es decir, nuestros controladores de dominio.
Importante: Configura NTP para que sincronice la hora de tu controlador de dominio primario, agregando a /etc/ntp.conf
la siguiente línea:
server dc1.calnus.com
Configuración de Samba
Tan sencillo como crear un nuevo archivo /etc/samba/smb.conf
y agregar lo siguiente:
[global]
workgroup = CALNUS
client signing = yes
client use spnego = yes
kerberos method = secrets and keytab
realm = CALNUS.COM
security = ads
Que no te lleve a confusión el workgroup, ya que es necesario aunque estemos configurando un dominio. En esta caso hay que poner el nombre NETBIOS del dominio.
Opcionalmente, agregamos al archivo las carpetas que queramos compartir:
[cert]
path = /var/cert
comment = Calnus certificates
browseable = yes
read only = yes
writable = no
create mask = 660
directory mask = 660
admin users = @"CALNUS\Domain Admins",svcAccount
Fácil ¿verdad?
SSSD
En el archivo /etc/sssd/sssd.conf
he usado la misma configuración del artículo:
[sssd]
services = nss, pam
config_file_version = 2
domains = CALNUS.COM
[domain/CALNUS.COM]
id_provider = ad
access_provider = ad
# Use this if users are being logged in at /.
# This example specifies /home/DOMAIN-FQDN/user as $HOME. Use with pam_mkhomedir.so
override_homedir = /home/%d/%u
# Uncomment if the client machine hostname doesn't match the computer object on the DC.
# ad_hostname = mad-certbot.calnus.com
# Uncomment if DNS SRV resolution is not working
# ad_server = dc1.calnus.com
# Uncomment if the AD domain is named differently than the Samba domain
# ad_domain = CALNUS.COM
# Enumeration is discouraged for performance reasons.
# enumerate = true
Ahora es necesario establecer los permisos y propietario del archivo. Si no están correctos, SSSD se negará a arrancar:
sudo chown root:root /etc/sssd/sssd.conf
sudo chmod 600 /etc/sssd/sssd.conf
Name Service Switch
El Name Service Switch de GNU/Linux se configura en /etc/nsswitch.conf
. Este sistema nos permitirá especificar, para cada una de las bases de datos definidas en la Librería de C estándar de GNU, que sistemas son los responsables de las mismas y el orden de preferencia a la hora de buscar usuarios.
La instalación de SSSD ya modifica este archivo por defecto, pero conviene verificar que está todo correcto. Debe tener un aspecto parecido a este para los servicios passwd
, group
, shadow
y services
:
passwd: compat sss
group: compat sss
...
netgroup: nis sss
sudoers: files sss
Como podemos ver, por ejemplo en passwd
estamos especificando que primero deberían buscarse los usuarios en compat
y si no se encuentran en sss
. compat
es el sistema por defecto de bases de datos de usuarios en UNIX, que se hospeda en el archivo /etc/passwd
.
/etc/hosts
Es muy recomendable que agregues a este archivo el FQDN de la máquina Linux que vas a unir al dominio. Por ejemplo:
192.168.1.10 mad-certbot mad-certbot.calnus.com
Unirse a Active Directory
Llegados este punto, ya tenemos todo listo para unirnos a Active Directory. Cuidado porque hay un bug en el mencionado artículo si nos guiamos por él para poner a punto el sistema, por lo que os pongo los pasos en el orden correcto.
En primer lugar, hay que reiniciar los servicios NTP y Samba:
$ sudo systemctl restart ntp
$ sudo systemctl restart smbd nmbd
¡Ahora deberíamos estar en condiciones de solicitar un ticket Kerberos a nuestro controlador de dominio! Veamos si funciona:
$ sudo kinit Administrator
Password for Administrator@CALNUS.COM:
No news, good news. Si no hay errores probablemente hemos obtenido el ticket correctamente. Lo podemos verificar así:
$ sudo klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: Administrator@CALNUS.COM
Valid starting Expires Service principal
12/11/2016 21:10:00 12/12/2016 07:10:00 krbtgt/CALNUS.COM@CALNUS.COM
renew until 12/12/2016 21:09:58
¡Esto pinta muy bien! ¡Ha llegado el momento de unirnos al dominio!
$ sudo net ads join -k
Using short domain name -- CALNUS
Joined 'MAD-CERTBOT' to dns domain 'calnus.com'
No DNS domain configured for mad-certbot. Unable to perform DNS Update.
DNS update failed: NT_STATUS_INVALID_PARAMETER
Vaya, éxito parcial. Este mensaje nos comunica que nos hemos unido al dominio, pero que no se pudo llevar a cabo una actualización dinámica del DNS. Esto no supone un problema porque es una operación que podemos llevar a cabo manualmente nosotros mismos en el DNS del Active Directory.
En la documentación que he podido encontrar, siempre hacen referencia a que se debe comprobar el archivo /etc/hosts
y que las entradas estén correctamente, pero en mi caso no he dado aún a día de hoy por qué falla. Si alguien encuentra la causa, ¡dejadme un comentario en el artículo! Como he dicho, no influye en el éxito de la operación.
Si nos hemos podido unir adecuadamente, podremos abrir Active Directory Users and Computers y bajo Computers deberíamos encontrar la Machine Account de nuestro Linux.
Como estamos oficialmente unidos al dominio, reiniciamos SSSD para que aplique la configuración y podamos empezar a autenticar usuarios:
$ sudo systemctl restart sssd
La segunda verificación que podemos hacer para ver que todo está corriendo sin problemas es hacer una consulta directamente a nuestro AD desde Linux:
$ getent passwd Administrator
administrator:*:6347736775:6347736776:Administrator:/home/CALNUS.COM/administrator:
Como no tengo ningún usuario Administrator en mi máquina Linux, doy la prueba por buena. ¡Ya estamos integrados con Active Directory!
Nuestros usuarios de dominio ya pueden iniciar sesión en nuestra máquina, manteniendo también el inicio de sesión local.
Creando un $HOME para los usuarios de dominio con pam_mkhomedir
Todo el mundo necesita una casa. Para que nuestros usuarios de AD sean ciudadanos de primera en nuestra máquina Linux, necesitaremos activar un módulo del PAM que se encargará de generarla dinámicamente al inciar sesión.
Esto es ta fácil como ir a /etc/pam.d/common-session
y agregar la siguiente línea justo después del pam_unix.so.
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
Ten en cuenta que esto sólo funcionará correctamente si activamos el override_homedir
en el sssd.conf
, cosa que ya dejamos a tal propósito en el paso anterior.
Logging
Los logs de SSSD se encuentran ubicados en /var/log/sssd/
, por lo que en caso de problemas podéis consultar en dicho directorio. Afortunadamente, a servidor aún no le ha llegado la hora de hacerlo.
Actualizaciones dinámicas de DNS
A pesar de seguir estos pasos nos podemos encontrar con que nuestra máquina GNU/Linux no se registra correctamente en el DNS de Microsoft. En este genial articulo de un blog oficial de Microsoft nos detallan por qué ocurre esto, que básicamente es poque SSSD envía a AD únicamente el hostname de nuestra máquina, cuando la actualización de DNS necesita el FQDN completo.
El workaround para esto es cambiar nuestro hostname para que sea un FQDN, que en la mayoría de distribuciones de GNU/Linux podemos conseguir con el siguiente comando:
hostnamectl set-hostname mimaquina.calnus.com
Happy Linuxing!