Configurar sincronización unidireccional OpenLDAP con Active Directory y TLS en Debian (sssd/samba-tool): paso a paso
Redes & Segurança · Por Kevin Marcondes · Publicado el · 11 min de lectura
En este tutorial configurarás la sincronización unidireccional de OpenLDAP hacia Active Directory con transporte seguro (TLS) en Debian, usando sssd para resoluciones de identidad y samba-tool para crear/actualizar cuentas. Cubre preparación de TLS, Kerberos, el script de sincronización, programación con systemd y validación final, además de troubleshooting para errores habituales.
Requisitos previos y escenario de red
Vamos a sincronizar usuarios de OpenLDAP hacia Active Directory, asegurando el transporte con TLS (LDAPS o StartTLS). Necesitas acceso administrativo al AD, una cuenta de servicio en OpenLDAP, una CA de confianza, nombres DNS resolubles y relojes sincronizados.
Usa dominios de ejemplo como ad.example.com para el AD y ldap.example.org para el OpenLDAP. Ten una OU de pruebas en el AD para validar primero. Las acciones del tutorial crean y modifican usuarios en el AD; úsalo en un entorno de homologación antes de producción.
Si TLS/PKI es nuevo para ti, revisa recursos sobre mTLS —por ejemplo el tutorial sobre mTLS entre Nginx y microservicios o la guía de PKI interna en Docker Compose. Para recomendaciones generales de seguridad en servidores, consulta el checklist de seguridad para VPS.
- Debian actualizado, shell con sudo.
- OpenLDAP accesible via LDAP/LDAPS, base: dc=example,dc=org.
- Active Directory accesible, base: DC=ad,DC=example,DC=com.
- Cuenta admin en el AD y cuenta bind en OpenLDAP.
- CA raíz/intermedia importada en Debian.
- DNS del AD resolviendo registros SRV y A/AAAA.
- Sincronización horaria (NTP).
| Servicio | Puerto | Uso |
|---|---|---|
| LDAP (StartTLS) | 389/TCP | Consultas/actualizaciones de directorio con StartTLS |
| LDAPS | 636/TCP | Consultas/actualizaciones de directorio mediante TLS directo |
| Kerberos | 88/TCP+UDP | Autenticación (GSSAPI) en el AD |
| DNS | 53/UDP+TCP | Descubrimiento de DCs y registros SRV del AD |
1) Preparar TLS: CAs, certificados y prueba de StartTLS/LDAPS
Instala la CA raíz/intermedia usada por OpenLDAP y por el AD (si existe una CA corporativa). ldapsearch debe validar los certificados. Usa LDAPS (636) cuando esté disponible; StartTLS (389) también es aceptable.
Si la CA no está instalada, las conexiones LDAP seguras fallarán. Prueba primero contra OpenLDAP y luego contra el AD. Para certificados públicos la lógica de confianza es la misma que en HTTPS; si necesitas generar certificados, consulta la guía de Let's Encrypt.
# 1) Instalar CA corporativa
sudo install -m 0644 /path/to/your-ca.crt /usr/local/share/ca-certificates/your-ca.crt
sudo update-ca-certificates
# 2) Testar OpenLDAP com StartTLS (389)
ldapsearch -H ldap://ldap.example.org -ZZ -x \
-b "dc=example,dc=org" -s base namingContexts
# 3) Testar OpenLDAP com LDAPS (636)
ldapsearch -H ldaps://ldap.example.org -x \
-b "dc=example,dc=org" -s base namingContexts
# 4) Testar AD com GSSAPI + LDAPS (exige Kerberos configurado)
ldapsearch -H ldaps://dc1.ad.example.com -Y GSSAPI \
-b "DC=ad,DC=example,DC=com" -s base defaultNamingContext
2) Instalar paquetes en Debian y ajustar DNS/Kerberos
Instala las herramientas esenciales: sssd, Samba (samba-tool), utilidades LDAP y Kerberos. Configura /etc/krb5.conf para tu realm del AD. Después, obtén un ticket Kerberos con kinit. No continúes sin un kinit exitoso.
Asegura que /etc/resolv.conf apunte al DNS del AD, ya que sssd usa descubrimiento SRV para localizar los controladores de dominio.
sudo apt update && sudo apt install -y \
sssd sssd-tools sssd-ldap samba samba-common-bin \
krb5-user ldap-utils openssl
# Exemplo mínimo de /etc/krb5.conf (ajuste domínios e DCs)
sudo tee /etc/krb5.conf > /dev/null <<'EOF'
[libdefaults]
default_realm = EXAMPLE.COM
dns_canonicalize_hostname = false
rdns = false
dns_lookup_kdc = true
[realms]
EXAMPLE.COM = {
kdc = dc1.ad.example.com
kdc = dc2.ad.example.com
admin_server = dc1.ad.example.com
}
[domain_realm]
.ad.example.com = EXAMPLE.COM
ad.example.com = EXAMPLE.COM
EOF
# Obter TGT (ticket)
kinit [email protected]
klist
3) Configurar sssd para resolver identidades de Active Directory vía TLS
sssd proporcionará NSS/PAM a partir del AD, útil para validar la creación de usuarios. No sincroniza directorios; solo resuelve identidades y autentica.
Define el dominio del AD, exige certificados válidos y habilita el cache. Mantén /etc/sssd/sssd.conf con permiso 600. Ajusta nsswitch para incluir sss en passwd y group.
- sssd no sincroniza directorios; solo consulta y hace cache.
- Usa ldap_tls_reqcert=demand para fallar ante certificados inválidos.
- Después de cambios, limpia el cache: sss_cache -E.
# Criar /etc/sssd/sssd.conf
sudo install -m 0600 /dev/null /etc/sssd/sssd.conf
sudo tee /etc/sssd/sssd.conf > /dev/null <<'EOF'
[sssd]
services = nss, pam
domains = ad.example.com
[domain/ad.example.com]
id_provider = ad
ad_domain = ad.example.com
krb5_realm = EXAMPLE.COM
cache_credentials = true
ldap_id_mapping = true
access_provider = ad
ad_gpo_access_control = permissive
# TLS
ldap_tls_reqcert = demand
ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt
# Descoberta DNS
dns_discovery_domain = ad.example.com
EOF
sudo systemctl enable --now sssd
# Incluir sss no NSS (ajuste conforme seu arquivo atual)
sudo sed -i 's/^passwd:.*/passwd:\t\tfiles systemd sss/' /etc/nsswitch.conf
sudo sed -i 's/^group:.*/group:\t\tfiles systemd sss/' /etc/nsswitch.conf
4) Probar binds y consultas en OpenLDAP y en AD con TLS
Valida el acceso a OpenLDAP con bind simple usando la cuenta de servicio. En el AD, prefiere GSSAPI con el ticket Kerberos obtenido por kinit. Nunca expongas contraseñas en la línea de comandos en producción.
Confirma filtros y bases correctas. Ajusta nombres y DNs según tu entorno.
# OpenLDAP: bind simples com conta de serviço
ldapsearch -H ldaps://ldap.example.org \
-D "cn=sync,ou=svc,dc=example,dc=org" -W \
-b "ou=People,dc=example,dc=org" '(objectClass=inetOrgPerson)' uid mail -LLL -o ldif-wrap=no
# AD: GSSAPI com Kerberos (sem senha em linha)
ldapsearch -H ldaps://dc1.ad.example.com -Y GSSAPI \
-b "DC=ad,DC=example,DC=com" '(sAMAccountName=*)' cn -LLL -o nettimeout=5
5) Mapear atributos y crear usuarios en AD con samba-tool
Haremos la sincronización OpenLDAP → AD. Mapeos comunes: uid → sAMAccountName, givenName/sn → nombres, mail → mail y uidNumber/gidNumber → RFC2307 en el AD.
Las contraseñas no se copian entre directorios directamente. El flujo más seguro es crear el usuario con una contraseña temporal y exigir el cambio en el primer inicio de sesión.
Este script crea/actualiza cuentas en el AD; apunta a una OU de pruebas antes de usar en producción. Autentícate en el AD con Kerberos (kinit) y usa samba-tool con -k yes.
- uid → sAMAccountName
- givenName/sn → nombre y apellido
- mail → mail
- uidNumber/gidNumber → RFC2307 (si se usa en el AD)
# Salve como /usr/local/sbin/ol2ad-sync.sh e torne executável
sudo install -m 0750 /dev/null /usr/local/sbin/ol2ad-sync.sh
sudo tee /usr/local/sbin/ol2ad-sync.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
OPENLDAP_URI="ldaps://ldap.example.org"
OPENLDAP_BINDDN="cn=sync,ou=svc,dc=example,dc=org"
OPENLDAP_BASE="ou=People,dc=example,dc=org"
FILTER='(objectClass=inetOrgPerson)'
AD_URI="ldaps://dc1.ad.example.com"
AD_BASE="DC=ad,DC=example,DC=com"
AD_UPN_SUFFIX="@ad.example.com"
# Requer 'kinit [email protected]' prévio
ldapsearch -H "$OPENLDAP_URI" -D "$OPENLDAP_BINDDN" -W -LLL -o ldif-wrap=no \
-b "$OPENLDAP_BASE" "$FILTER" uid givenName sn mail uidNumber gidNumber \
| awk 'BEGIN{ FS=": "; RS="" }{
uid=""; given=""; sn=""; mail=""; uidn=""; gidn="";
for(i=1;i<=NF;i++){
if($i ~ /^uid: /){ split($i,a,": "); uid=a[2] }
if($i ~ /^givenName: /){ split($i,a,": "); given=a[2] }
if($i ~ /^sn: /){ split($i,a,": "); sn=a[2] }
if($i ~ /^mail: /){ split($i,a,": "); mail=a[2] }
if($i ~ /^uidNumber: /){ split($i,a,": "); uidn=a[2] }
if($i ~ /^gidNumber: /){ split($i,a,": "); gidn=a[2] }
}
if(uid!=""){ printf "%s;%s;%s;%s;%s;%s\n", uid, given, sn, mail, uidn, gidn }
}' \
| while IFS=';' read -r U G S M UIDN GIDN; do
UPN="${U}${AD_UPN_SUFFIX}"
if samba-tool user show "$U" -k yes -H "$AD_URI" >/dev/null 2>&1; then
# Atualizar atributos simples
[ -n "$M" ] && samba-tool user setattribute "$U" mail "$M" -k yes -H "$AD_URI"
continue
fi
TMPPASS="$(openssl rand -base64 12)"
samba-tool user create "$U" "$TMPPASS" \
--given-name="$G" --surname="$S" \
--user-principal-name="$UPN" \
${UIDN:+--uid-number="$UIDN"} ${GIDN:+--gid-number="$GIDN"} \
--use-username-as-cn \
-k yes -H "$AD_URI"
# Forçar troca de senha no primeiro login
samba-tool user setpassword "$U" --must-change-at-next-login -k yes -H "$AD_URI"
done
EOF
sudo chmod 0750 /usr/local/sbin/ol2ad-sync.sh
6) Programar la sincronización periódica con systemd timer
Programa la ejecución del script con systemd. Define intervalos según tu necesidad. Usa una OU de destino controlada en el AD para minimizar el impacto.
El servicio se ejecuta sin entorno interactivo; asegúrate de que el host obtenga un TGT Kerberos automáticamente (por ejemplo con un keytab) o que el timer se active tras un kinit mediante automatización.
- Usa un keytab del AD si quieres ejecutar sin intervención.
- Monitorea logs de ejecución y fallos.
- Define OnCalendar/OnUnitActiveSec según el SLA.
# Unidade de serviço
sudo tee /etc/systemd/system/ol2ad-sync.service > /dev/null <<'EOF'
[Unit]
Description=OpenLDAP -> AD one-way sync
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ol2ad-sync.sh
User=root
Group=root
# Opcional: export KRB5CCNAME para un cache de credencial específico
Environment=KRB5CCNAME=/tmp/krb5cc_sync
[Install]
WantedBy=multi-user.target
EOF
# Timer horário (ajuste conforme necessário)
sudo tee /etc/systemd/system/ol2ad-sync.timer > /dev/null <<'EOF'
[Unit]
Description=Run OpenLDAP -> AD sync hourly
[Timer]
OnBootSec=5m
OnUnitActiveSec=1h
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now ol2ad-sync.timer
# Rodar manualmente para testar
sudo systemctl start ol2ad-sync.service
sudo systemctl status ol2ad-sync.service --no-pager
7) Cómo confirmar que funcionó y resolver problemas comunes
Valida identidades a través de sssd y confirma los objetos creados en el AD. Revisa que los atributos mapeados se hayan aplicado. Si algo falla, verifica TLS, Kerberos y filtros LDAP.
Para acceso administrativo remoto seguro al servidor, considera un bastion dedicado con 2FA: consulta la guía del bastión SSH.
Las contraseñas no se migran entre directorios sin mecanismos específicos; crea usuarios con contraseña temporal y fuerza el cambio en el primer inicio. Planifica grupos y OUs, limita permisos de la cuenta que ejecuta el script y registra auditoría. Un error en el script puede crear muchos objetos; haz dry-runs y apunta primero a una OU de pruebas.
- Verifica TGT: klist y expiración.
- Limpia cache de sssd tras cambios: sss_cache -E.
- Desajustes horarios rompen Kerberos; sincroniza NTP.
- Handshake TLS falla: revisa CA instalada y CN/SAN del certificado.
- samba-tool falla por permisos: revisa grupos/ACLs en el AD.
- Atributos RFC2307 ausentes: habilítalos en el AD o ajusta el script.
# Verificações
id usuario_teste
getent passwd usuario_teste
getent group "Domain Users"
# Ver no AD
samba-tool user show usuario_teste -k yes -H ldaps://dc1.ad.example.com | sed -n '1,120p'
# Confirmar no OpenLDAP
ldapsearch -H ldaps://ldap.example.org -D "cn=sync,ou=svc,dc=example,dc=org" -W \
-b "ou=People,dc=example,dc=org" "(uid=usuario_teste)" dn -LLL
8) Consideraciones finales sobre mapeos y extensión del flujo
Ajusta mapeos según tu árbol LDAP y políticas de UPN/sAMAccountName. Trata colisiones de uid/sAMAccountName con reglas claras. Para atributos adicionales, usa samba-tool setattribute de forma incremental.
Si necesitas sincronizar grupos o desactivar cuentas borradas en OpenLDAP, extiende el script para manejar esos casos. Empieza con reportes y dry-runs, luego aplica cambios con protecciones y logs detallados.
Preguntas frecuentes
¿sssd sincroniza OpenLDAP y Active Directory?
No. sssd ofrece identidades y autenticación al sistema (NSS/PAM) usando AD o LDAP como proveedores. No replica ni sincroniza objetos entre directorios. La sincronización requiere scripts o herramientas que lean de un lado y escriban en el otro.
¿Puedo sincronizar contraseñas de OpenLDAP al AD?
Directamente, no. Los hashes y políticas difieren y el AD restringe cómo se establecen contraseñas. Usa creación con contraseña temporal y 'must change at next logon' o flujos centralizados de cambio de contraseña. Evita exponer contraseñas en la línea de comandos.
¿Debo usar LDAPS (636) o StartTLS (389)?
Ambos cifran la comunicación. LDAPS es más simple operativamente cuando está disponible. StartTLS es útil si ya expones el puerto 389. En todos los casos, valida la cadena de certificados y exige verificación estricta en el cliente (ldap_tls_reqcert=demand).
¿Qué puertos debo abrir en el firewall?
LDAP 389/TCP (StartTLS), LDAPS 636/TCP, Kerberos 88/TCP+UDP y DNS 53/UDP+TCP para descubrimiento del AD. Si usas Global Catalog, 3268/3269. Abre solo las orígenes necesarias y monitoriza intentos de conexión.
¿Y si el AD no tiene habilitados los atributos RFC2307?
Puedes crear usuarios sin uidNumber/gidNumber y mapear solo sAMAccountName/UPN. Si necesitas IDs UNIX en el AD, habilita RFC2307 y rellena uidNumber/gidNumber con samba-tool setattribute según tu política.
¿Es posible hacer el flujo inverso (AD→OpenLDAP)?
Sí, pero es otro flujo. Lee desde el AD con GSSAPI y aplica cambios en OpenLDAP usando ldapadd/ldapmodify. Prueba filtros y colisiones de atributos. sssd sigue siendo solo un cliente para resolución, no una herramienta de sincronización.
¿Necesitas revisar TLS/PKI o reforzar el script de sincronización?
Si quieres validar mapeos, automatizar con keytabs o aplicar hardening, podemos evaluar los próximos pasos y ajustes necesarios.
Hablar sobre la integración OpenLDAP→ADVer también
- Tutorial: configurar mTLS entre Traefik y servicios en Docker Compose usando smallstep CA y certificados automáticos — paso a paso
- Tutorial: integrar Sentry en el pipeline de deploy con GitHub Actions para subir source maps automáticamente y generar issues (PHP y JavaScript) — paso a paso
- Configurar retención y compresión de logs de contenedores Docker con journald + logrotate + rsyslog en VPS con poco disco
- Tutorial: configurar GitHub Actions para tests de integración con PostgreSQL en contenedores efímeros y rollback automático de migrations — guía práctica