Respaldo Active Directory y LDAP confiable. Domain Controllers Windows y directorios OpenLDAP — System State coordinado, Authoritative Restore, granular object recovery.
- System State Backup — base AD + SYSVOL + registry, coordinado vía VSS.
- Authoritative Restore — recupere objetos eliminados sin revertir el dominio completo.
- Granular object recovery — usuario, grupo o OU específica, sin levantar DC aislado.
- OpenLDAP, FreeIPA, Samba AD — mismo plugin, detección automática de schema.
- Forest multi-dominio — coordinación cross-domain, replicación consistente.
Producción en 30 días, al menos 50% más barato. Trial gratuito, RPMs y DEBs firmados, soporte directo con Heitor Faria. Reemplace su licencia Veeam, Commvault o Bacula Enterprise sin romper la ventana nocturna.
Solicitar trial gratuito de 30 días →
Tabla de contenidos
- Resumen ejecutivo
- Introducción y contexto de mercado
- Visión general de la arquitectura
- Modos de respaldo en detalle
- Modos de restauración en detalle
- Matriz de funcionalidades
- Guía de instalación
- Referencia de configuración
- Ejemplos de FileSet
- Dimensionamiento y planificación de capacidad
- Objetivos de rendimiento
- Matriz de compatibilidad
- Seguridad
- Monitoreo
- Guía de resolución de problemas
- Casos de uso y escenarios de implementación
- Comparación con otros enfoques
- Hoja de ruta
- Información de contacto
- Legal / derechos de autor
1. Resumen ejecutivo
La infraestructura de identidad — Microsoft Active Directory, OpenLDAP, 389-DS y Samba AD DC — es el componente más crítico en cualquier entorno de TI empresarial. Cada cuenta de usuario, cada membresía de grupo, cada Group Policy Object (GPO), cada lista de control de acceso y cada principal Kerberos reside en el directorio. Cuando los datos de identidad se pierden o se corrompen, toda la organización se detiene: los inicios de sesión fallan, las aplicaciones no pueden autenticarse y el acceso privilegiado a otros sistemas protegidos por respaldo se vuelve imposible.
A pesar de esta criticidad, la mayoría de las organizaciones carecen de un respaldo específico para sus servicios de directorio. Los enfoques comunes van desde exportaciones periódicas de ldif mediante scripts ldapsearch hasta depender del respaldo del estado del sistema Windows — ninguno de los cuales se integra de forma limpia con una plataforma de respaldo de código abierto, ninguno ofrece capacidad incremental real y ninguno cubre la superficie completa de datos de identidad, incluyendo SYSVOL, GPO, schema y ACLs.
El PodHeitor Active Directory / LDAP Backup Plugin for Bacula cierra esta brecha. Es un plugin FD framework de plugin PodHeitor puro en Rust cargado directamente por bacula-fd, que proporciona respaldo y restauración sin agente, solo por red, de los servicios de directorio: Microsoft Active Directory (Windows Server 2012 R2 hasta 2025 y Samba AD DC), OpenLDAP 2.4/2.5/2.6, 389 Directory Server / Red Hat DS / FreeIPA y cualquier servidor compatible con LDAPv3 en modo genérico.
El plugin incluye cinco modos de respaldo que cubren todos los escenarios operativos — desde instantáneas lógicas equivalentes a ldif (modo ldap) hasta streaming incremental AD DirSync (modo ad), protección continua de datos (cdp), replicación en vivo entre directorios (replicate) y respaldo integrado de SYSVOL/GPO (hybrid_sysvol). Seis modos de restauración ofrecen precisión desde la corrección de un único atributo hasta la recuperación autoritativa completa de bosque. Todo se gestiona mediante la configuración estándar de Job y FileSet de Bacula, sin daemons auxiliares, sin scripts shell y sin archivos de estado externos.
El plugin está construido con refuerzo de Unicode brasileño incorporado desde el principio — un requisito práctico para el mercado latinoamericano donde las entradas de directorio contienen frecuentemente cedilla, tilde y otros caracteres acentuados que rompen implementaciones menos robustas. 734 pruebas unitarias, 45 pruebas de integración con LDAP en vivo contra 389-DS y Samba AD, y un conjunto de pruebas de failover destructivo durante el barrido confirman la fiabilidad de nivel productivo.
2. Introducción y contexto de mercado
2.1 Por qué el respaldo de directorio es singularmente crítico
A diferencia de una base de datos o sistema de archivos, un servicio de directorio no es autosuficiente. Es la columna vertebral de autenticación y autorización de todos los demás sistemas del entorno. Un fallo de directorio se propaga inmediatamente: el correo electrónico deja de entregarse, las conexiones VPN fallan, el single sign-on en la nube se rompe, los sistemas ERP rechazan los inicios de sesión y el operador no puede autenticarse en el propio sistema de respaldo. La recuperación de una pérdida de directorio sin un respaldo adecuado se mide en días, no en horas — y puede requerir reconstruir toda la infraestructura de identidad desde cero.
Los datos de directorio tienen varias propiedades que hacen que el respaldo genérico a nivel de archivo sea insuficiente:
- Dependencia de schema. Las entradas LDAP hacen referencia a clases de objeto y tipos de atributo del schema que deben restaurarse en el orden correcto. Una copia de archivo sin procesar de NTDS.dit no captura el schema de forma independiente.
- Fidelidad de ACL y descriptor de seguridad. Cada objeto AD lleva un descriptor de seguridad NT. Estos no son atributos simples y requieren manejo especial durante la restauración.
- Coherencia entre GPO y SYSVOL. Los Group Policy Objects abarcan tanto el directorio LDAP (los objetos
groupPolicyContainer) como el recurso compartido de archivos SYSVOL. Un respaldo que solo captura el lado LDAP produce un conjunto de GPO inconsistente en la restauración. - Estado de la topología de replicación. En un entorno multi-DC, la restauración debe tener en cuenta los vectores USN y los metadatos de replicación para evitar la resurrección de tombstones y los escenarios de USN rollback.
- Capacidad incremental. Los directorios grandes (100 000+ objetos) no pueden respaldarse completamente en la ventana de respaldo disponible. La capacidad incremental real — mediante RFC 4533 syncrepl para OpenLDAP/389-DS o Microsoft DirSync para AD — es esencial.
2.2 Por qué los enfoques existentes son insuficientes
| Enfoque | Cobertura | Veredicto |
|---|---|---|
| ldapsearch / scripts de exportación ldif | Solo datos lógicos; sin schema, sin ACLs, sin SYSVOL | No apto para producción; sin integración con Bacula; sin incremental |
| Respaldo de estado del sistema Windows | NTDS.dit completo; solo Windows; requiere agente Windows en el DC | Viola el requisito sin agente; sin soporte para OpenLDAP/389-DS |
| AD Recycle Bin | Solo recuperación de objetos a nivel de objeto; retención de 60–180 días | No es un respaldo; sin restauración a un punto en el tiempo |
| Veeam | Sin agente nativo AD/LDAP a nivel de protocolo de directorio | Solo respaldo a nivel de VM; sin restauración de objetos sin complemento |
| Commvault Active Directory iDataAgent | Solo Windows AD; requiere agente en cada DC | Sin OpenLDAP/389-DS; costo de licencia elevado |
| PodHeitor Backup (nativo, sin plugin) | Solo nivel de archivo — respalda los archivos sin procesar NTDS.dit o MDB de OpenLDAP | Inseguro con el directorio activo; sin restauración lógica |
| NetBackup BMR | Recuperación bare-metal; sin conciencia de directorio | Solo restauración completa del servidor; sin precisión de objeto o atributo |
2.3 El enfoque PodHeitor
El plugin realiza el respaldo solo por red, sin agente: se conecta al directorio a través de LDAP/LDAPS desde el host del Bacula File Daemon, sin ningún agente instalado en el servidor de directorio. Esto es arquitectónicamente análogo a cómo un plugin de respaldo de base de datos se conecta a la base de datos a través de su protocolo nativo. El servidor de directorio es una caja negra; el plugin habla LDAPv3, RFC 4533 (syncrepl) y la extensión LDAP Microsoft DirSync — los mismos protocolos de red que el directorio expone a cualquier socio de replicación.
Este enfoque funciona igualmente bien para Windows Server AD (sin agente en el DC), Samba AD DC, OpenLDAP y 389-DS. Un único plugin cubre todo el panorama de directorios desde un único host Bacula File Daemon.
3. Visión general de la arquitectura
3.1 Formato en disco: híbrido MessagePack-LDIF
Cada entrada LDAP se almacena como un archivo de dos segmentos bajo la ruta virtual @adldap/<server>/<basedn>/entries/<objectGUID-or-uuid>.ent:
Section 1: 4-byte magic 'PHAE' + msgpack(EntryHeader)
Section 2: msgpack(Vec<Attribute>)
binary attrs (jpegPhoto, userCertificate, msExchMailbox*)
are blob-tagged for round-trip safety
Este formato es aproximadamente 3–4 veces más compacto que el ldif sin procesar para cargas útiles AD (MessagePack vs base64), es seguro para Unicode y admite ordenamiento determinista para operaciones de diff. Una vista ldif secundaria se genera bajo demanda para los modos dry_run y diff.
3.2 Portador de estado RestoreObject
Al final del respaldo, el plugin emite un RestoreObject llamado adldap-state.msgpack en el catálogo de Bacula. Este contiene la cookie syncrepl (RFC 4533) o cookie DirSync (AD), el mayor USN/CSN visto, un hash SHA-256 del schema y el manifiesto completo de entradas. El siguiente job incremental recupera la cookie automáticamente del catálogo — no se requiere ningún archivo de estado en disco, por lo que el plugin sobrevive a la pérdida y reinstalación del host sin perder la línea base incremental.
4. Modos de respaldo en detalle
4.1 Modo ldap — RFC 4533 syncrepl (OpenLDAP / 389-DS)
Cómo funciona
El modo ldap se conecta a cualquier servidor LDAPv3 y realiza una búsqueda paginada (RFC 2696) para respaldos Full, y RFC 4533 syncrepl (refreshOnly o refreshAndPersist) para respaldos Incrementales y Diferenciales. Cada entrada se serializa al formato MessagePack-LDIF y se transmite como un archivo virtual de Bacula.
La cookie syncrepl se lleva en el RestoreObject después de cada job. El siguiente job Incremental presenta la cookie al servidor y recibe solo las entradas modificadas desde ese punto — incluyendo modificaciones, adiciones y eliminaciones (el servidor marca las eliminaciones con syncState=delete).
Full backup: paged search → emit all entries → save cookie in RestoreObject
Incremental: syncrepl refreshOnly (cookie) → emit changed/deleted entries
CDP: syncrepl refreshAndPersist → stream changes in real-time
Compatibilidad con Samba AD
La implementación syncrepl de Samba AD omite el control SyncStateValue por entrada del RFC 4533 que incluye 389-DS. El plugin detecta esto en tiempo de análisis y sintetiza la identidad de la entrada desde objectGUID (preferido) o entryUUID (alternativa), enrutando la entrada como state=add. Esto es semánticamente correcto para la entrega refresh-only de instantánea completa de Samba. Las respuestas de 389-DS permanecen en la ruta estricta.
Cuándo usar
- OpenLDAP 2.4/2.5/2.6 — objetivo primario soportado
- 389 Directory Server / Red Hat DS / núcleo de directorio FreeIPA
- Samba AD DC en modo syncrepl
- Cualquier servidor LDAPv3 sin soporte para Microsoft DirSync
- Entornos donde se requiere un respaldo lógico y portable equivalente a ldif
4.2 Modo ad — Microsoft DirSync
Cómo funciona
El modo ad utiliza el control extendido LDAP Microsoft DirSync (OID 1.2.840.113556.1.4.841) para transmitir cambios de directorio desde Active Directory. DirSync es el mismo mecanismo utilizado por los socios de replicación del AD y es el único método soportado por Microsoft para la enumeración incremental de directorio. Captura todos los cambios de objetos incluyendo modificaciones del descriptor de seguridad, objetos tombstoned (entradas eliminadas) y atributos operacionales.
Para respaldos Full, el plugin emite una solicitud DirSync sin cookie previa, lo que hace que AD devuelva todo el árbol de directorio. Para respaldos Incrementales, se presenta la cookie anterior (almacenada en el RestoreObject) y AD devuelve solo los cambios desde esa marca de agua.
Las cookies DirSync codifican rangos USN (Update Sequence Number). Debido a que la replicación DRS garantiza que cada DC en el bosque almacene los mismos cambios con vectores de marca de agua consistentes, una cookie emitida por DC1 puede transferirse con seguridad a DC2 durante el failover — el plugin maneja esto de forma transparente (ver Sección 4.5).
Permisos AD necesarios
El usuario de bind debe tener:
SeSyncAgentPrivilege(«Replicating Directory Changes») — obligatorio para DirSync.- Replicating Directory Changes All — requerido para acceso a tombstone y Recycle Bin.
- Replicating Directory Changes In Filtered Set — para entornos RODC.
- Acceso de lectura a
<dc>SYSVOL<domain>Policies— requerido solo para el modohybrid_sysvol.
Una cuenta con privilegio mínimo «Operador de Respaldo – PodHeitor» puede delegarse mediante dsacls.exe — la guía del operador proporciona la receta exacta.
Cuándo usar
- Microsoft Active Directory (Windows Server 2012 R2 hasta 2025)
- Samba AD DC en modo DirSync (raíz del dominio
basedn=requerida — ver nota del operador) - Cualquier escenario que requiera acceso a tombstone e integración con AD Recycle Bin
- Entornos multi-DC donde se necesita portabilidad de cookie USN
4.3 Modo hybrid_sysvol — LDAP DirSync + SYSVOL/GPO
Cómo funciona
El modo hybrid_sysvol realiza un barrido LDAP DirSync completo del directorio (idéntico al modo ad) y simultáneamente adjunta una instantánea del recurso compartido SYSVOL a nivel SMB-CIFS usando libsmbclient-rs (bindings Rust para libsmbclient.so). Los archivos SYSVOL se almacenan en @adldap/<server>/sysvol/... con preservación completa de NT ACL mediante descriptores de seguridad NT codificados en msgpack.
Las fases LDAP y SYSVOL se ejecutan como un par de única pasada dentro de un job. El failover LDAP mid-stream a un DC diferente se rechaza intencionalmente: si la fase LDAP rota al DC2 mientras la fase SYSVOL sigue apuntando al sysvol_uri= del DC1, el respaldo resultante contendría objetos de directorio del DC2 y archivos GPO del DC1, que podrían estar en diferentes estados de replicación. El plugin rechaza este escenario de split-brain y falla con Fatal, requiriendo que la siguiente ejecución programada comience de nuevo.
Cuándo usar
- Cualquier entorno Active Directory donde se requiera la capacidad de restauración de GPO
- Escenarios de cumplimiento que requieren el estado de identidad completo incluyendo scripts de inicio de sesión, paquetes de instalación de software y plantillas de seguridad en
Policies - Planificación de DR donde una instantánea consistente LDAP+SYSVOL es el punto de restauración autoritativo
4.4 Modo replicate — replicación en vivo entre directorios
Cómo funciona
El modo replicate abre una sesión syncrepl (o DirSync) contra el directorio de origen y simultáneamente abre una sesión de escritura LDAP contra un directorio de destino configurado por replicate_target_uri=. Cada cambio observado en el origen se aplica al destino de inmediato. El stream de respaldo de Bacula sigue recibiendo una copia para auditabilidad del catálogo y restauración a un punto en el tiempo.
La replicación entre proveedores (AD → OpenLDAP o viceversa) se soporta mediante un archivo de mapeo de schema configurable (default-schema-mapping.toml). El mapeo predeterminado traduce sAMAccountName → uid, userPrincipalName → mail y objectGUID → entryUUID (UUIDv4 determinista). La detección de bucles se maneja mediante objectGUID (AD) o entryUUID (RFC 4530) para evitar tormentas de replicación en topologías bidireccionales.
Cuándo usar
- Espejo de identidad en modo cold-standby en un datacenter de DR, sin necesidad de AD Trust ni replicación multi-master
- Proyectos de migración de identidad entre proveedores (transición AD → OpenLDAP)
- Copia de auditoría en tiempo real de un directorio de producción hacia un servidor LDAP de solo lectura
4.5 Modo cdp — protección continua de datos
Cómo funciona
El modo cdp usa syncrepl refreshAndPersist para mantener una conexión persistente con el servidor de directorio y transmitir cambios en tiempo real. El job de Bacula permanece abierto y emite chunks de respaldo cada cdp_max_seconds (predeterminado 60 segundos), acotando el RPO a ese intervalo. El submodo cdp_dirsync proporciona la misma semántica para Active Directory usando el modelo de sondeo persistente DirSync.
Cuando ocurre un fallo de transporte, el plugin agota la lista de URI de failover (avanzando en errores TCP, fallos TLS y condiciones de servidor LDAP no disponible) con retroceso exponencial gobernado por cdp_reconnect_max_attempts, cdp_reconnect_initial_backoff_ms y cdp_reconnect_max_backoff_ms. La cookie syncrepl o DirSync más reciente se conserva entre reconexiones mediante DcSelector::carry_cookie, de modo que el plugin reanuda desde donde quedó en lugar de releer todo el directorio.
Failover multi-DC
Todos los modos de respaldo que aceptan ldapuri= (o target_ldapuri= para la restauración) soportan una lista separada por comas de URIs LDAP. El plugin trata esto como una secuencia de failover solo hacia adelante. El selector avanza solo en errores a nivel de transporte (TCP rechazado/restablecido/tiempo de espera, fallo DNS, fallo de handshake TLS, servidor LDAP no disponible). No avanza en fallos de autenticación, fallos de autorización ni errores de configuración — estos fallan inmediatamente ya que las mismas credenciales fallarán en todos los DCs.
| Modo | Failover en conexión | Failover mid-stream | Cookie transferida entre DCs |
|---|---|---|---|
ldap (refresh-only) |
Sí | No | Sí (sidecar del operador) |
ad (DirSync) |
Sí | Sí | Sí (USN replicado) |
cdp (refresh+persist) |
Sí | Sí | Sí (cluster-CSN) |
cdp_dirsync |
Sí | Sí | Sí (USN replicado) |
hybrid_sysvol |
Sí | No (por diseño) | n/a (par LDAP+SYSVOL) |
replicate |
Sí | Sí | Sí (gestionado por el selector) |
| restore (cualquier submodo) | Sí | No (por diseño) | n/a |
5. Modos de restauración en detalle
El motor de restauración acepta un parámetro mode= que selecciona entre seis estrategias de restauración. Todos los modos comparten la misma infraestructura de streaming de entradas; la diferencia está en lo que escriben en el directorio de destino.
5.1 Modo object
Restaura una única entrada identificada por DN o objectGUID. La entrada se vuelve a agregar (o modifica si ya está presente, según la política replace=) con todos los atributos del respaldo. Este es el modo predeterminado para la restauración selectiva — «Eliminé accidentalmente una cuenta de usuario.»
5.2 Modo subtree
Restaura una unidad organizacional completa y todos sus descendientes. El motor reordena las entradas con los padres primero y puede crear OUs padre faltantes si create_parents=true. El parámetro where_basedn= redirige la restauración a una OU de staging (por ejemplo, ou=Restaurado,dc=lab,dc=local) para que el árbol activo no se vea perturbado durante la verificación.
5.3 Modo attribute
Restaura N atributos especificados en M entradas sin tocar otros atributos. Usa semántica LDAP Modify Replace — los atributos especificados se reemplazan con los valores del respaldo; todos los demás atributos permanecen tal como están en el directorio activo. Ideal para «restablecer displayName al valor del respaldo en toda una OU» sin una restauración completa del subárbol.
5.4 Modo authoritative
Realiza una restauración completa y eleva la versión USN del AD en los objetos restaurados para que otros DCs repliquen DESDE el DC restaurado en lugar de sobrescribirlo. Este es el equivalente de la restauración autoritativa del AD y está bloqueado por un parámetro obligatorio i_understand=yes — aplicar este modo sin el control desencadena un Fatal inmediato sin escribir ninguna entrada LDAP. La guía del operador explica el radio de impacto y los pasos necesarios de aislamiento de DC.
5.5 Modo dry_run
Calcula el ldif que SE APLICARÍA y lo escribe en el RestoreLog de Bacula. No se abre ningún canal de escritura LDAP contra el destino. Úselo para verificación previa antes de ejecutar una restauración destructiva.
5.6 Modo diff
Compara la instantánea del respaldo con el directorio activo y produce un informe JSON de adiciones, eliminaciones y modificaciones: {adds: [], dels: [], mods: []}. Completamente de solo lectura. Útil para auditoría de cumplimiento, detección de cambios y análisis forense post-incidente.
6. Matriz de funcionalidades
| Funcionalidad | ldap | ad | hybrid_sysvol | replicate | cdp |
|---|---|---|---|---|---|
| Respaldo Full | Sí | Sí | Sí | Sí | Sí |
| Respaldo Incremental (RFC 4533) | Sí | No | No | Sí | Sí |
| Respaldo Incremental (DirSync) | No | Sí | Sí | No | Sí (cdp_dirsync) |
| Failover multi-DC | Sí | Sí | Sí | Sí | Sí |
| Cookie transferida entre DCs | Sí | Sí | n/a | Sí | Sí |
| Respaldo SYSVOL / GPO | No | No | Sí | No | No |
| Preservación NT ACL | Parcial | Sí | Sí | Sí | Sí |
| Replicación entre proveedores | No | No | No | Sí | No |
| Cifrado en reposo (AES-256-GCM) | Sí | Sí | Sí | Sí | Sí |
| Cifrado en reposo (ChaCha20-Poly1305) | Sí | Sí | Sí | Sí | Sí |
| Backend KMS HashiCorp Vault | Sí | Sí | Sí | Sí | Sí |
| Métricas Prometheus | Sí | Sí | Sí | Sí | Sí |
| Registro estructurado JSON-Lines | Sí | Sí | Sí | Sí | Sí |
| Refuerzo Unicode brasileño (NFC/NFD) | Sí | Sí | Sí | Sí | Sí |
| Catalogación estable por objectGUID | No | Sí | Sí | Sí | Sí |
| Respaldo paralelo por rama (pool por OU) | Sí | Sí | No | No | No |
| Soporte AD Recycle Bin | No | Sí | Sí | No | Sí (cdp_dirsync) |
| Autenticación Kerberos / GSSAPI | No | Sí | Sí | Sí | Sí |
| StartTLS / LDAPS | Sí | Sí | Sí | Sí | Sí |
| Paquete RPM | Sí | Sí | Sí | Sí | Sí |
| Paquete DEB | Sí | Sí | Sí | Sí | Sí |
| RestoreObject cookie carry | Sí | Sí | n/a | Sí | Sí |
| RPO sub-minuto (CDP) | No | No | No | No | Sí |
| Compresión zstd | Sí | Sí | Sí | Sí | Sí |
| Compresión lz4 | Sí | Sí | Sí | Sí | Sí |
7. Guía de instalación
7.1 Requisitos previos
- PodHeitor Backup o posterior instalado;
bacula-fdejecutándose en un host Linux x86_64 - Conectividad de red desde el host
bacula-fdhacia el servidor de directorio en el puerto LDAP (389) o LDAPS (636) - Para
mode=ad/ Kerberos: cliente Kerberos configurado (/etc/krb5.confapuntando al realm AD); keytab en/etc/podheitor/bacula.keytab - Para
mode=hybrid_sysvol:samba-client-libs(o equivalente) que proporcionelibsmbclient.so - SO: RHEL/OL/Rocky 9+ o Ubuntu 22.04+/Debian 12+
- glibc 2.34+
7.2 Instalación RPM (EL9 / OL9 / RHEL9 / Rocky 9)
# 1. Install the RPM
dnf install podheitor-adldap-0.1.0-1.el9.x86_64.rpm
# 2. Verify plugin is in place
ls -la /opt/bacula/plugins/podheitor-adldap-fd.so
# 3. Restart bacula-fd to load the plugin
systemctl restart bacula-fd
# 4. Confirm plugin loaded
journalctl -u bacula-fd --since "1 minute ago" | grep podheitor
7.3 Instalación DEB (Ubuntu 22.04 / Debian 12)
# 1. Install the DEB
apt install ./podheitor-adldap_0.1.0-1_amd64.deb
# 2. Verify plugin is in place
ls -la /opt/bacula/plugins/podheitor-adldap-fd.so
# 3. Restart bacula-fd
systemctl restart bacula-fd
# 4. Confirm plugin loaded
journalctl -u bacula-fd --since "1 minute ago" | grep podheitor
7.4 Configuración de credenciales — bind simple
# Create a password file for LDAP simple bind
cat > /etc/podheitor/openldap.pass << 'EOF'
secret_password_here
EOF
chown bacula:bacula /etc/podheitor/openldap.pass
chmod 600 /etc/podheitor/openldap.pass
7.5 Configuración de credenciales — keytab Kerberos (AD)
# Create a keytab for the AD backup service account
# On the Windows DC (or via samba-tool):
# ktpass /out bacula.keytab /mapuser bacula-backup@LAB.LOCAL
# /princ bacula-backup@LAB.LOCAL /pass * /crypto AES256-SHA1
# Deploy to the bacula-fd host
install -o bacula -g bacula -m 600 bacula.keytab /etc/podheitor/bacula.keytab
# Verify Kerberos works
kinit -k -t /etc/podheitor/bacula.keytab bacula-backup@LAB.LOCAL
klist
7.6 Verificación de la instalación — smoke test OpenLDAP
FileSet { Name = "Smoke-ADLDAP"; Include {
Options { signature=MD5 }
Plugin = "podheitor-adldap: mode=ldap ldapuri=ldap://192.168.15.154
binddn=cn=Manager,dc=lab,dc=podheitor,dc=local
bindpass_file=/etc/podheitor/openldap.pass
basedn=dc=lab,dc=podheitor,dc=local"
} }
Ejecute un job Full mediante bconsole: *run job=Smoke-ADLDAP level=Full yes. Resultado esperado: estado del job T con bytes escritos distintos de cero y canal interno START → END visible en el registro del job.
8. Referencia de configuración
8.1 Parámetros de respaldo
| Parámetro | Predeterminado | Descripción |
|---|---|---|
mode |
(requerido) | ldap / ad / replicate / cdp / hybrid_sysvol |
ldapuri |
(requerido) | URI(s) LDAP, separados por coma para failover multi-DC |
binddn |
DN de bind simple (omitir si kerberos=yes) |
|
bindpass_file |
Ruta al archivo que contiene la contraseña de bind (modo 0600) | |
kerberos |
no |
Usar autenticación GSSAPI/Kerberos |
keytab |
Ruta del archivo keytab (requerido si kerberos=yes) |
|
starttls |
auto |
Actualizar a TLS en ldap:// si el servidor anuncia StartTLS |
tls_cacert |
Paquete de CA personalizado para LDAPS o StartTLS | |
basedn |
(requerido) | DN base de búsqueda LDAP |
filter |
(objectClass=*) |
Filtro de búsqueda LDAP para delimitar el alcance del respaldo |
attribs_include |
*,+ |
Atributos a incluir (+ = atributos operacionales) |
attribs_exclude |
Atributos a omitir (por ejemplo, userPassword) |
|
page_size |
1000 |
Tamaño de página de la búsqueda paginada RFC 2696 |
parallel_branches |
1 |
Tamaño del pool de hilos paralelos por OU; 0 = automático (conteo de CPU) |
include_recycle_bin |
no |
Solo AD — incluir objetos tombstoned/eliminados mediante LDAP_SERVER_SHOW_DELETED |
dirsync_flags |
0x801 |
Indicadores del control DirSync (OBJECT_SECURITY|INCREMENTAL_VALUES|ANCESTORS_FIRST_ORDER) |
sysvol_uri |
URI SMB para el recurso compartido SYSVOL; requerido para mode=hybrid_sysvol |
|
sysvol_pass_file |
Archivo de contraseña SMB para acceso a SYSVOL | |
compress |
zstd |
none / zstd / lz4 |
compress_level |
3 |
Nivel de compresión zstd (1–22) |
encryption |
none |
none / aes-gcm / chacha20-poly1305 |
kms |
Backend KMS: file:/path/key, vault:transit/keys/name, sops:/path |
|
replicate_target_uri |
URI LDAP de destino para mode=replicate |
|
replicate_target_binddn |
DN de bind de destino para mode=replicate |
|
replicate_schema_map |
(predeterminado) | Ruta a default-schema-mapping.toml para replicación entre proveedores |
cdp_max_seconds |
60 |
Intervalo de chunk CDP en segundos (acota el RPO) |
cdp_reconnect_max_attempts |
6 |
Máximo de recorridos completos de la lista de URI antes de Fatal |
cdp_reconnect_initial_backoff_ms |
500 |
Retroceso inicial de reconexión en milisegundos |
cdp_reconnect_max_backoff_ms |
30000 |
Tope máximo de retroceso de reconexión en milisegundos |
metrics_path |
/var/lib/podheitor/adldap.prom |
Ruta de salida del textfile Prometheus |
no_normalize_dn |
no |
Deshabilitar normalización NFC en DNs (escape hatch) |
allow_anonymous |
no |
Defensa en profundidad: rechazar bind anónimo |
verify_after_backup |
yes |
Releer manifiesto y recomputar resúmenes después del respaldo |
8.2 Parámetros de restauración
| Parámetro | Predeterminado | Descripción |
|---|---|---|
mode |
object |
object / subtree / attribute / authoritative / dry_run / diff |
target_ldapuri |
(URI del respaldo) | URI del directorio de destino; admite failover separado por coma |
target_binddn |
DN de bind de destino (predeterminado: DN de bind del origen) | |
target_bindpass_file |
Archivo de contraseña de bind de destino | |
target_kerberos |
no |
Usar Kerberos para la conexión de destino |
where_basedn |
Redirigir la restauración a un DN base diferente (OU de staging) | |
replace |
never |
never / if-newer / always |
attributes |
* |
Atributos separados por coma para restaurar (para mode=attribute) |
entries |
* |
DNs u objectGUIDs a restaurar (predeterminado: todos) |
create_parents |
no |
Crear OUs padre faltantes durante la restauración del subárbol |
i_understand |
Debe ser yes para habilitar mode=authoritative |
|
password_reset |
keep |
keep / random / force=<pwd> para contraseñas de cuentas de usuario |
dry_run_output |
Ruta para escribir la vista previa ldif para mode=dry_run |
|
diff_output |
Ruta para escribir el informe JSON de diff para mode=diff |
|
decrypt_kms |
Ruta del backend KMS para descifrar un respaldo cifrado |
9. Ejemplos de FileSet
9.1 Respaldo Full OpenLDAP
FileSet {
Name = "OpenLDAP-Full"
Include {
Options { signature=MD5 }
Plugin = "podheitor-adldap: mode=ldap
ldapuri=ldap://ldap.example.com
binddn=cn=Manager,dc=example,dc=com
bindpass_file=/etc/podheitor/openldap.pass
basedn=dc=example,dc=com
compress=zstd"
}
}
9.2 Respaldo Full Active Directory con Kerberos
FileSet {
Name = "AD-Full-Kerberos"
Include {
Options { signature=MD5 }
Plugin = "podheitor-adldap: mode=ad
ldapuri=ldaps://dc01.corp.local:636,ldaps://dc02.corp.local:636
kerberos=yes keytab=/etc/podheitor/bacula.keytab
basedn=DC=corp,DC=local
include_recycle_bin=yes
parallel_branches=4
compress=zstd encryption=aes-gcm
kms=file:/etc/podheitor/adldap.key"
}
}
9.3 Respaldo Incremental Active Directory (DirSync)
FileSet {
Name = "AD-Incremental"
Include {
Plugin = "podheitor-adldap: mode=ad
ldapuri=ldaps://dc01.corp.local,ldaps://dc02.corp.local
kerberos=yes keytab=/etc/podheitor/bacula.keytab
basedn=DC=corp,DC=local
cookie_file=/var/lib/bacula/adldap.cookie"
}
}
9.4 Respaldo Full híbrido SYSVOL + LDAP
FileSet {
Name = "AD-Hybrid-SYSVOL"
Include {
Plugin = "podheitor-adldap: mode=hybrid_sysvol
ldapuri=ldaps://dc01.corp.local
kerberos=yes keytab=/etc/podheitor/bacula.keytab
basedn=DC=corp,DC=local
sysvol_uri=smb://dc01.corp.local/SYSVOL/corp.local
compress=zstd"
}
}
9.5 CDP — protección continua OpenLDAP
FileSet {
Name = "OpenLDAP-CDP"
Include {
Plugin = "podheitor-adldap: mode=cdp
ldapuri=ldap://ldap1.example.com,ldap://ldap2.example.com
binddn=cn=Manager,dc=example,dc=com
bindpass_file=/etc/podheitor/openldap.pass
basedn=dc=example,dc=com
cdp_max_seconds=30
cdp_reconnect_max_attempts=8"
}
}
9.6 Replicación entre proveedores — AD a OpenLDAP
FileSet {
Name = "AD-to-OpenLDAP-Replicate"
Include {
Plugin = "podheitor-adldap: mode=replicate
ldapuri=ldaps://dc01.corp.local
kerberos=yes keytab=/etc/podheitor/bacula.keytab
basedn=DC=corp,DC=local
replicate_target_uri=ldap://standby-ldap.example.com
replicate_target_binddn=cn=admin,dc=example,dc=com
replicate_target_pass_file=/etc/podheitor/standby.pass"
}
}
9.7 Restauración — objeto único por objectGUID
Job {
Name = "AD-Restore-Object"
Type = Restore
Client = adldap-fd
FileSet = "AD-Full-Kerberos"
Storage = File
Pool = Default
Messages = Standard
Plugin = "podheitor-adldap: mode=object
target_ldapuri=ldaps://dc01.corp.local
target_kerberos=yes
entries=550e8400-e29b-41d4-a716-446655440000
replace=always"
}
9.8 Restauración — vista previa dry run antes de la restauración autoritativa
Plugin = "podheitor-adldap: mode=dry_run
target_ldapuri=ldaps://dc01.corp.local
target_kerberos=yes
dry_run_output=/tmp/preview-restore.ldif"
10. Dimensionamiento y planificación de capacidad
10.1 Requisitos de memoria
| Escenario | Línea base bacula-fd | RAM adicional del plugin |
|---|---|---|
| respaldo full ldap / ad, single-threaded | 512 MB | +64 MB |
| respaldo full ad, parallel_branches=4 | 512 MB | +256 MB (4×64 MB) |
| Modo CDP (conexión persistente) | 512 MB | +96 MB |
| hybrid_sysvol (LDAP + SMB) | 512 MB | +128 MB |
| Objetivo de respaldo con 100 000 entradas (tope RSS) | ≤250 MB RSS total del bacula-fd | |
10.2 Estimaciones de volumen de respaldo
| Modo | Almacenamiento aproximado por 100 000 objetos |
|---|---|
| ldap / ad full (sin compresión) | 200–500 MB (varía con la densidad de atributos) |
| ldap / ad full (zstd nivel 3) | 60–150 MB |
| Incremental (1% modificado) | 2–10 MB |
| SYSVOL / GPO (hybrid_sysvol) | 10–200 MB (varía con el número de GPO y el tamaño de política) |
| RestoreObject (cookie + manifiesto) | ≤50 MB (comprimido con zstd; peor caso 1M de entradas) |
10.3 Objetivos de rendimiento (metas de laboratorio v0.1.0)
| Escenario | Objetivo |
|---|---|
| 100 000 entradas OpenLDAP, respaldo full | ≤8 minutos (4 vCPU, 4 GB RAM) |
| 100 000 entradas OpenLDAP, incremental syncrepl (1% modificado) | ≤1 minuto |
| 50 000 objetos AD, DirSync full | ≤5 minutos |
| Incremental AD DirSync (100 cambios) | ≤15 segundos |
| RPO CDP (cdp_max_seconds=60) | ≤90 segundos de extremo a extremo |
10.4 Espacio en disco — instalación del plugin
| Archivo | Tamaño |
|---|---|
podheitor-adldap-fd.so |
~2–3 MB (Rust con todas las funcionalidades vinculadas estáticamente) |
| Huella total de la instalación | ~2–3 MB |
No se requiere ningún binario sidecar externo. libsmbclient.so es una dependencia de paquete del sistema solo para el modo hybrid_sysvol.
11. Informe de rendimiento
Todas las mediciones se realizan en el entorno de laboratorio PodHeitor en máquinas virtuales Rocky Linux 9.4 (2–4 vCPU, 2–4 GB RAM) conectadas a servidores Samba AD DC y 389-DS en una LAN 192.168.15.0/24. PodHeitor Backup se usa en todas las pruebas.
11.1 Estado del conjunto de pruebas — v0.1.0
| Categoría | Pruebas | Estado |
|---|---|---|
| Pruebas unitarias (adldap-core) | 734 | Todas aprobadas |
| Pruebas unitarias (shim ABI plugin-adldap) | 14 | Todas aprobadas |
| Pruebas de integración con LDAP en vivo (389-DS + Samba AD) | 45 | Todas aprobadas |
| Prueba destructiva de failover mid-sweep (opt-in) | 1 | Aprobada (#[ignore]) |
| Escenarios de restauración sobre daño en vivo (delete, modify+delete, modrdn, borrado total) | 4 | Todas aprobadas |
| Restauración autoritativa E2E (Samba AD) | 2 | Todas aprobadas |
| Total | 800+ | Todas aprobadas |
11.2 Resultados de la prueba de failover multi-DC
| Prueba | Resultado |
|---|---|
| Failover en el momento de conexión (DC1 inactivo al inicio) | Aprobada — se conecta al DC2 de forma transparente |
Failover mid-stream (cdp_dirsync): DC1 detenido en medio del sondeo |
Aprobada — cookie transferida entre DCs |
| Failover mid-sweep con 50 entradas sembradas | Aprobada — cookie_len=N (N>0) confirmado en el registro |
| Continuidad incremental post-reconexión | Aprobada — sin entradas duplicadas tras la reconexión |
11.3 Resultados de escenario de restauración (389-DS)
| Escenario | Descripción | Resultado |
|---|---|---|
| escenario1 | Objeto eliminado; restauración mediante mode=object |
Aprobado — atributos originales incluyendo mail round-trip |
| escenario2 | Atributo mutado tras el respaldo y luego entrada eliminada; la restauración recupera el valor original | Aprobado |
| escenario3 | Entrada renombrada mediante modrdn; la restauración recrea el DN original | Aprobado — DN original recreado, copia renombrada persiste (no destructivo) |
| escenario4 | OU completa (5 hijos) eliminada de abajo hacia arriba; restauración mediante mode=subtree |
Aprobado — todas las 5 hojas round-trip |
11.4 Resultados de restauración autoritativa (Samba AD)
| Prueba | Resultado |
|---|---|
autoritativa sin i_understand=yes → Fatal |
Aprobada — frame Error + Fatal; cero escrituras LDAP |
| autoritativa con control: 2 entradas respaldadas, eliminadas, reproducidas | Aprobada — terminal=Ok, applied≥2, ambos DNs presentes, uSNChanged estrictamente > pre-restauración |
12. Matriz de compatibilidad
12.1 Sistema operativo
| SO | Arquitectura | Estado |
|---|---|---|
| RHEL 9 | x86_64 | Soportado |
| Oracle Linux 9 | x86_64 | Soportado |
| Rocky Linux 9 | x86_64 | Soportado (plataforma de laboratorio) |
| AlmaLinux 9 | x86_64 | Soportado |
| Ubuntu 22.04 LTS | x86_64 | Soportado |
| Debian 12 | x86_64 | Soportado |
| RHEL 8 / CentOS 8 | x86_64 | No probado (glibc < 2.34) |
| Ubuntu 20.04 | x86_64 | No probado (glibc < 2.34) |
| ARM64 / aarch64 | cualquiera | Aún no disponible |
12.2 Versiones de servidor de directorio
| Servidor de directorio | Versión | Modo | Estado |
|---|---|---|---|
| Microsoft Active Directory | Windows Server 2012 R2 – 2025 | ad, hybrid_sysvol, cdp_dirsync | Soportado |
| Samba AD DC | Cualquier versión Samba actual | ad, ldap, hybrid_sysvol | Soportado (probado en laboratorio) |
| OpenLDAP (slapd) | 2.4, 2.5, 2.6 | ldap, cdp, replicate | Soportado |
| 389 Directory Server | Actual | ldap, cdp, replicate | Soportado (probado en laboratorio) |
| Red Hat DS / FreeIPA | Actual | ldap, cdp | Soportado (vía 389-DS) |
| ApacheDS | Actual | ldap (genérico) | Mejor esfuerzo |
| OpenDJ | Actual | ldap (genérico) | Mejor esfuerzo |
12.3 Versiones de Bacula
| Versión de Bacula | Estado |
|---|---|
| Community 15.0.3 | Soportado (validado) |
| Community 15.0.x (futuro) | Compatibilidad esperada |
| Community 14.x | No soportado |
| Bacula Enterprise | No requerido; el plugin está orientado a PodHeitor Backup |
12.4 Controles LDAP utilizados
| OID | Nombre | Utilizado por |
|---|---|---|
| 1.2.840.113556.1.4.319 | Resultados paginados (RFC 2696) | Respaldo Full |
| 1.3.6.1.4.1.4203.1.9.1.1 | syncrepl (RFC 4533) | Incremental LDAP |
| 1.2.840.113556.1.4.841 | DirSync | Incremental AD |
| 1.2.840.113556.1.4.417 | LDAP_SERVER_SHOW_DELETED | Tombstone, Recycle Bin |
| 1.2.840.113556.1.4.2065 | DirSync extendido (V2) | AD ≥ 2008 R2 |
| 1.2.840.113556.1.4.529 | LDAP_SERVER_EXTENDED_DN | Restauración AD |
| 1.3.6.1.4.1.1466.20037 | StartTLS | Actualizaciones TLS |
| 1.3.6.1.4.1.4203.1.11.1 | Password Modify (RFC 3062) | Restauración con restablecimiento de contraseña |
13. Seguridad
13.1 Manejo de credenciales
Las contraseñas de bind nunca se almacenan en la configuración de FileSet o Job de Bacula. Todas las contraseñas se leen desde archivos dedicados con modo 0600 de propiedad del usuario bacula. La contraseña se pasa en memoria a la biblioteca cliente LDAP; nunca se escribe en disco durante el job, nunca aparece en los argumentos del proceso visibles mediante ps y se redacta en toda la salida de registro (registro JSON-Lines con redacción obligatoria para bindpass, target_bindpass, contenido del keytab y claves resueltas por el KMS).
Los archivos keytab Kerberos deben tener modo 0600; el plugin rechaza usar un keytab con permisos más permisivos.
13.2 Cifrado en reposo
El plugin proporciona su propia capa de cifrado en reposo independiente del cifrado a nivel de stream de Bacula. Se soportan dos algoritmos:
- AES-256-GCM — el predeterminado recomendado para entornos con aceleración de hardware AES.
- ChaCha20-Poly1305 — preferido para entornos sin hardware AES (por ejemplo, plataformas embebidas o ARM).
Se proporcionan tres backends KMS:
file:/path/key— clave almacenada en un archivo (más sencillo; el archivo de clave debe ser 0600).vault:transit/keys/name— motor Transit de HashiCorp Vault; las claves nunca salen del Vault.sops:/path— archivo de clave cifrado Mozilla SOPS.
Un intento de restauración con una configuración KMS ausente o incorrecta falla rápidamente con un error explícito antes de que se intente cualquier escritura en el directorio.
13.3 Seguridad de red
El plugin soporta LDAPS (TLS directo en el puerto 636) y StartTLS (actualización en el puerto 389). No abre puertos de escucha adicionales en el host bacula-fd. Para el modo hybrid_sysvol, la conexión SMB al recurso compartido SYSVOL utiliza el ticket Kerberos obtenido del keytab — no se requieren credenciales SMB separadas si Kerberos está configurado.
El bind anónimo se rechaza de forma predeterminada (allow_anonymous=no). Esta es una medida de defensa en profundidad; cualquier operador que habilite explícitamente el bind anónimo debe auditar cuidadosamente sus ACLs de directorio.
13.4 Control de seguridad de restauración autoritativa
La restauración mode=authoritative está bloqueada estructuralmente: el bucle de aplicación no tiene acceso al selector y no puede proceder sin que el parámetro i_understand=yes esté configurado explícitamente. Esto no es una verificación en tiempo de ejecución — está impuesto por el sistema de tipos de Rust. Un job de restauración sin el control emite un frame Error y un estado terminal Fatal sin realizar una sola escritura LDAP, y el cumplimiento del control está cubierto por una prueba en vivo contra Samba AD en el conjunto de pruebas.
14. Monitoreo
14.1 Métricas de textfile Prometheus
Al final del job (y periódicamente durante el modo CDP), el plugin escribe métricas de textfile Prometheus en /var/lib/podheitor/adldap.prom (ruta configurable mediante metrics_path=). Estas pueden ser recolectadas por el recolector de textfile del Node Exporter.
14.2 Métricas expuestas
| Métrica | Tipo | Descripción |
|---|---|---|
podheitor_adldap_entries_backed_up |
Counter | Total de entradas LDAP serializadas a Bacula |
podheitor_adldap_bytes_written |
Counter | Total de bytes escritos al Bacula Storage Daemon |
podheitor_adldap_job_duration_seconds |
Histogram | Duración de respaldo por job |
podheitor_adldap_errors_total |
Counter | Total de eventos de error por código de error |
podheitor_adldap_replicate_lag_seconds |
Gauge | Modo CDP/replicate: antigüedad del cambio más recientemente aplicado |
podheitor_adldap_failover_events_total |
Counter | Conteo de eventos de failover multi-DC por modo y par de DC |
podheitor_adldap_cookie_age_seconds |
Gauge | Antigüedad de la cookie syncrepl/DirSync actual |
podheitor_adldap_compression_ratio |
Gauge | Relación de compresión más reciente (comprimido / sin procesar) |
14.3 Configuración de recolección de textfile Node Exporter
scrape_configs:
- job_name: 'podheitor-adldap'
static_configs:
- targets: ['bacula-fd-host:9100']
metrics_path: /metrics
scrape_interval: 60s
El Node Exporter debe iniciarse con --collector.textfile.directory=/var/lib/podheitor/ (o la ruta configurada mediante metrics_path=).
14.4 Registro estructurado JSON-Lines
Toda la salida de registro del plugin se emite como JSON Lines en stderr (capturado por bacula-fd) y se copia en /var/log/bacula/podheitor-adldap-<jobid>.log. Niveles: TRACE / DEBUG / INFO / WARN / ERROR. Eventos de diagnóstico clave emitidos en nivel WARN:
{"lvl":"warn","msg":"cdp_dirsync: connect failure on ldaps://dc1.corp.local (LDAP_SERVER_DOWN); failing over to ldaps://dc2.corp.local at cookie_len=128"}
{"lvl":"warn","msg":"cdp: all DCs exhausted on connect (attempt 3/6); last error: ...; backing off 4000ms then restarting walk"}
{"lvl":"warn","msg":"schema_hash mismatch: promoting Incremental to Full"}
Busque en el registro del job FD los términos failing over, exhausted o schema_hash mismatch para identificar eventos operacionalmente significativos para los informes de SLO.
15. Guía de resolución de problemas
15.1 Errores comunes
Plugin no encontrado al iniciar
Error: cannot open shared object file: No such file or directory
Causa. podheitor-adldap-fd.so no está en el directorio de plugins configurado.
Solución. Verifique que /opt/bacula/plugins/podheitor-adldap-fd.so existe y que la directiva PluginDirectory en bacula-fd.conf apunta a /opt/bacula/plugins.
Conexión LDAP rechazada
podheitor-adldap: LDAP_SERVER_DOWN connecting to ldaps://dc01.corp.local:636
Causa. El servidor de directorio no está disponible, TLS falló o el URI es incorrecto.
Solución:
# Test connectivity from the bacula-fd host
ldapsearch -H ldaps://dc01.corp.local:636 -x -b "" -s base
# Check TLS certificate validity
openssl s_client -connect dc01.corp.local:636 -CAfile /etc/podheitor/ca.crt < /dev/null
Fallo de autenticación Kerberos
podheitor-adldap: GSSAPI bind failed: clock skew too great
Causa. El reloj del host bacula-fd tiene más de 5 minutos de diferencia respecto al controlador de dominio.
Solución:
systemctl enable --now chronyd
chronyc makestep # force immediate sync
DirSync con permiso denegado
podheitor-adldap: DirSync control rejected: insufficientAccessRights (50)
Causa. El usuario de bind no posee SeSyncAgentPrivilege en el dominio.
Solución. Delegue los derechos necesarios mediante dsacls.exe o el asistente de delegación de Active Directory Users and Computers. Consulte la Guía del Operador para el comando dsacls exacto.
Samba AD: basedn DirSync rechazado
podheitor-adldap: DirSync unwillingToPerform (53): basedn must be domain root
Causa. Samba AD rechaza solicitudes DirSync con raíz por debajo del contexto de nomenclatura del dominio.
Solución. Configure basedn=dc=lab,dc=local (raíz del dominio) y use filter= para delimitar los resultados:
Plugin = "podheitor-adldap: mode=ad ...
basedn=dc=lab,dc=local
filter=(&(objectClass=user)(memberOf=cn=eng,ou=groups,dc=lab,dc=local))"
Discrepancia de hash del schema — respaldo full promovido
podheitor-adldap: schema_hash mismatch (stored=abc123, current=def456); promoting to Full
Causa. El schema del directorio cambió entre el último respaldo Full y este Incremental (por ejemplo, se aplicó una extensión de schema de AD).
Solución. Este es el comportamiento esperado. El plugin se autopromueve correctamente a Full y guarda el nuevo hash del schema. No se requiere ninguna acción del operador a menos que el cambio de schema haya sido involuntario.
Restauración autoritativa rechazada — control ausente
podheitor-adldap: mode=authoritative requires i_understand=yes; refusing to write
Causa. El parámetro i_understand=yes no fue configurado en el job de restauración.
Solución. Agregue i_understand=yes a la Plugin string de restauración. Lea la sección de la Guía del Operador sobre el radio de impacto de la restauración autoritativa antes de continuar.
15.2 Ubicaciones de registros
| Registro | Ruta |
|---|---|
| Registro principal bacula-fd | /opt/bacula/log/bacula-fd.log |
| Registro por job del plugin | /var/log/bacula/podheitor-adldap-<jobid>.log |
| Textfile Prometheus | /var/lib/podheitor/adldap.prom |
| Mensajes del Bacula Director | según la configuración en el recurso Messages de bacula-dir.conf |
15.3 Habilitando el registro de depuración
Agregue debug=9 a la Plugin string para la máxima verbosidad:
Plugin = "podheitor-adldap: mode=ldap ... debug=9"
Esto registra cada frame canal interno, cada solicitud/respuesta LDAP (incluyendo DN y código de resultado) y todas las transiciones de estado.
16. Casos de uso y escenarios de implementación
16.1 AD empresarial — cobertura completa de DR
Escenario. Una empresa de 2 000 personas opera Windows Server 2022 AD con dos controladores de dominio. Necesitan respaldos full nocturnos incluyendo GPOs, respaldos incrementales diarios y runbooks de DR probados.
Solución.
- Semanal: respaldo full
mode=hybrid_sysvol— captura objetos del directorio + SYSVOL/GPO - Diario: respaldo incremental
mode=ad— solo delta DirSync (minutos, no horas) - Retención: 30 días en el pool de Bacula
- Prueba de DR:
mode=dry_runtrimestral contra un dominio de laboratorio para verificar el procedimiento de restauración
Beneficio operativo. La capacidad de restauración de GPO es un diferenciador clave frente al AD Recycle Bin (que no incluye SYSVOL). Cuando un GPO se elimina accidentalmente o se configura incorrectamente, el conjunto completo de archivos GPO puede restaurarse desde el catálogo de Bacula sin necesidad de reconstruir desde cero.
16.2 Auditoría de cumplimiento de identidad en múltiples bosques
Escenario. Una institución financiera debe demostrar a los auditores que los atributos de cuentas de usuario y las membresías de grupos no se han modificado sin un ticket de cambio. Necesitan un informe de diff automatizado diario.
Solución.
- Job de respaldo diario con
mode=ad - Tras completar el respaldo, un job secundario de restauración se ejecuta con
mode=diff, produciendo un informe JSON de todos los cambios desde el respaldo anterior - El informe de diff se ingiere en el SIEM para correlación con tickets de cambio
- Cualquier entrada que aparezca en
delsomodssin un ticket de cambio correspondiente activa una alerta de seguridad
16.3 CDP OpenLDAP para directorio de cuentas de servicio
Escenario. Una plataforma de microservicios utiliza OpenLDAP para la autenticación de cuentas de servicio. Cualquier pérdida de datos LDAP provoca el fallo simultáneo de autenticación en decenas de servicios. El RPO debe ser inferior a 2 minutos.
Solución.
- Modo:
cdpconcdp_max_seconds=60contra un clúster OpenLDAP de dos réplicas (ldapuri=ldap://ldap1,ldap://ldap2) - RPO CDP: ≤90 segundos de extremo a extremo
- Failover mid-stream probado: si ldap1 falla durante una sesión de streaming, el plugin realiza el failover a ldap2 y continúa sin interrupción del job
16.4 Migración de dominio FreeIPA a Samba AD
Escenario. Una empresa está migrando de un dominio FreeIPA (backend 389-DS) a Samba AD DC. Necesitan una migración controlada y auditada con la capacidad de revertir.
Solución.
- Fase 1: Respaldo Full de FreeIPA mediante
mode=ldap— instantánea canónica de todas las cuentas de usuario, grupos y políticas - Fase 2:
mode=replicateconreplicate_target_uri=ldap://samba-dcy el mapeo de schema predeterminado — espeja en vivo los cambios de FreeIPA en Samba AD durante la ventana de migración - Fase 3: Tras la migración, ejecutar
mode=diffpara confirmar que el directorio Samba AD coincide con la última instantánea de FreeIPA - Reversión: si la migración falla, restaurar el directorio FreeIPA desde el respaldo Bacula de la Fase 1 mediante
mode=subtree
16.5 Recuperación autoritativa de bosque tras ransomware
Escenario. Todos los controladores de dominio fueron cifrados por ransomware. La empresa debe reconstruir el directorio desde el respaldo sin contaminación de replicación.
Solución.
- Provisionar un DC nuevo — aislado de la red, sin socios de replicación
- Ejecutar
mode=dry_runcontra el DC nuevo para previsualizar la restauración sin escribir nada - Tras revisar el ldif de vista previa, ejecutar
mode=authoritativeconi_understand=yes— restaura todos los objetos con USN elevado para que ningún socio de replicación pueda sobrescribir el estado restaurado - Reconectar el DC a la red; verificar que la replicación DRS converge desde el estado restaurado
- Ejecutar
mode=diffdespués de 1 hora para confirmar que no hubo replicación inesperada del estado cifrado
17. Comparación con otros enfoques
17.1 Diferenciadores PodHeitor vs. plugin Bacula Enterprise LDAP/MSAD
| Funcionalidad | PodHeitor AD/LDAP | Bacula Enterprise LDAP/MSAD |
|---|---|---|
| Respaldo SYSVOL / GPO | Sí (hybrid_sysvol) | No — solo LDAP |
| Replicación en vivo entre directorios | Sí (modo replicate) | No |
| CDP (protección continua de datos) | Sí (cdp / cdp_dirsync) | No |
| Incremental verdadero mediante DirSync + RFC 4533 | Sí (cookies USN / CSN) | Full + diff solo |
| Restauración a nivel de atributo | Sí (mode=attribute) | Solo nivel de objeto |
| Vista previa de restauración dry-run | Sí (mode=dry_run) | No |
| Restauración diff (informe de cambios de solo lectura) | Sí (mode=diff) | No |
| Restauración autoritativa | Sí (con control) | Parcial (solo MSAD) |
| Cifrado en reposo | Sí (AES-256-GCM / ChaCha20) | Solo nivel de stream Bacula |
| Refuerzo Unicode brasileño | Sí (NFC/NFD, CI gate completo) | Mejor esfuerzo |
| RestoreObject cookie (sin archivo de estado) | Sí | Archivo en disco |
| Catalogación estable por objectGUID / objectSID | Sí | Solo estable por DN |
| Respaldo paralelo por OU | Sí (parallel_branches=N) | Single-threaded |
| plugin nativo en Rust (sin shim C/C++) | Sí | Shim C++ |
| Métricas estructuradas Prometheus | Sí | Solo registros de texto |
| Failover multi-DC con cookie carry | Sí (todos los modos) | Limitado |
17.2 Comparación más amplia de plataformas
| Funcionalidad | PodHeitor Backup + PodHeitor | Bacula Enterprise | Veeam | Commvault |
|---|---|---|---|---|
| Respaldo nativo AD (DirSync) | Sí | Parcial | No (solo VM) | Parcial (agente Windows) |
| Respaldo nativo OpenLDAP / 389-DS | Sí | Limitado | No | No |
| Respaldo SYSVOL / GPO | Sí | No | No | No |
| CDP / RPO casi cero | Sí | No | No | Limitado |
| Replicación LDAP entre proveedores | Sí | No | No | No |
| Restauración a nivel de atributo | Sí | No | No | No |
| Restauración a nivel de objeto | Sí | Parcial | Requiere complemento | Sí (solo Windows AD) |
| Restauración autoritativa | Sí | Parcial | No | No |
| Cifrado en reposo (nivel de plugin) | Sí | Nivel de stream | Sí | Sí |
| Métricas Prometheus | Sí | No | No | No |
| Plataforma base de código abierto | Sí (Bacula CE) | No | No | No |
| Paquetes RPM + DEB | Sí | Sí | Sí | Sí |
| Sin agente (clientless, sin agente en el DC) | Sí | Parcial | No | No |
17.3 Comparación de costos
Oferta especial. Traiga su propuesta de renovación de Veeam, Commvault, NetBackup o cualquier otra plataforma de respaldo empresarial. Produciremos una propuesta comparativa formal orientada a lograr al menos 50% de ahorro, con funcionalidades AD/LDAP superiores. Contáctenos en heitor@opentechs.lat.
| Solución | Costo anual típico | Soporte AD / LDAP |
|---|---|---|
| PodHeitor Backup + plugin PodHeitor | Significativamente menor | Nativo completo (este plugin) |
| Bacula Enterprise | Frecuentemente > US$ 10 000/año | Parcial (LDAP/MSAD, sin SYSVOL) |
| Veeam Data Platform | Frecuentemente > US$ 5 000/año | Solo nivel de VM (sin restauración de objetos sin complemento) |
| Commvault | Frecuentemente > US$ 15 000/año | Solo Windows AD (agente obligatorio) |
| NetBackup | Frecuentemente > US$ 20 000/año | Limitado (sin LDAP nativo) |
Los precios varían según el tamaño del entorno y los contratos negociados. Contáctenos en heitor@opentechs.lat para una comparación específica con su propuesta de renovación actual.
18. Hoja de ruta
El plugin se lanza en v0.1.0 con el conjunto completo de funcionalidades MVP en los 5 modos de respaldo y 6 modos de restauración, validados por 800+ pruebas. Las direcciones de desarrollo planificadas incluyen:
- Fase 9 — empaquetado y documentación. Paquetes DEB y RPM firmados y publicados en el repositorio PodHeitor. Guía del Operador completa, DR Runbook y Guía de Resolución de Problemas.
- Agente AD nativo para Windows. Una compilación del plugin para Windows que se cargue en un
bacula-fdnativo Windows permitiría el acceso directo al NTDS.dit local mediante VSS — eliminando la necesidad de un host Linux separado conbacula-fdpara el respaldo de AD. Actualmente fuera del alcance de v0.1.0. - Soporte para múltiples arquitecturas. Paquetes ARM64 / aarch64 para entornos cloud-native y Raspberry Pi.
- Panel de administración Bacularis. Interfaz de configuración del plugin en la interfaz web de Bacularis para la entrada de parámetros sin editar la configuración sin procesar del FileSet. Confirmado fuera del alcance de v0.1.0.
- Soporte explícito para ApacheDS / OpenDJ. Actualmente mejor esfuerzo mediante el modo genérico
ldap; la certificación completa está planificada para una versión menor futura. - Azure AD DS / AWS Managed Microsoft AD. Los servicios AD gestionados en la nube tienen endpoints LDAP y soportan parcialmente DirSync — la certificación explícita y la documentación de soluciones alternativas están planificadas.
- Alertas Prometheus extendidas. Reglas de alerta predefinidas para obsolescencia de cookie, deriva de schema y latencia de replicación.
No se comprometen fechas de lanzamiento específicas. La dirección de funcionalidades se guía por los comentarios de los clientes y los hallazgos del laboratorio.
Licenciamiento
PodHeitor AD/LDAP Backup Plugin es software propietario, distribuido por suscripción. Para condiciones comerciales, demostración técnica o diagnóstico gratuito de 30 minutos, habla con el equipo por los canales abajo.
¿Listo para evaluar?
- 💬 WhatsApp: +1 (786) 726-1749
- ✉️ Email: heitor@opentechs.lat
- 🩺 Diagnóstico gratuito — 30 min con Heitor Faria
19. Información de contacto
| Autor | Heitor Faria |
| Sitio web | https://podheitor.com |
| Correo electrónico | heitor@opentechs.lat |
| Teléfono / WhatsApp | +1 786 726-1749 |
| Teléfono / WhatsApp (BR) | +55 61 98268-4220 |
| Página del producto | https://podheitor.com/active-directory-ldap-plugin |
| Soporte | heitor@opentechs.lat |
20. Legal / derechos de autor
© 2026 Heitor Faria — todos los derechos reservados.
El PodHeitor Active Directory / LDAP Backup Plugin for Bacula es software propietario. La copia, distribución, modificación o ingeniería inversa no autorizadas están estrictamente prohibidas. Se requiere una licencia comercial para su uso en producción.
Bacula® es marca registrada de Kern Sibbald y la comunidad Bacula. Microsoft Active Directory® es marca registrada de Microsoft Corporation. Todas las demás marcas comerciales — incluyendo OpenLDAP, 389-DS, FreeIPA, Samba, Kerberos, HashiCorp Vault, Veeam, Commvault y NetBackup — son propiedad de sus respectivos titulares.
Este documento se proporciona con fines informativos. Los valores de rendimiento son objetivos de mediciones controladas en laboratorio y pueden variar en entornos de producción según el hardware, las condiciones de red, la configuración del servidor de directorio y el tamaño del directorio.
Contacto para licenciamiento: heitor@opentechs.lat | https://podheitor.com | +1 786 726-1749 | +55 61 98268-4220
PodHeitor Active Directory / LDAP Backup Plugin for Bacula — v0.1.0 — © 2026 Heitor Faria — todos los derechos reservados — https://podheitor.com
Disponível em:
Português (Portugués, Brasil)
English (Inglés)
Español