Whitepaper técnico — PodHeitor Active Directory / LDAP para Bacula

Whitepaper técnico — PodHeitor Active Directory / LDAP para Bacula

Whitepaper Técnico — Versão 0.1.0 — Maio de 2026

Autor: Heitor Faria · Website: https://podheitor.com · E-mail: heitor@opentechs.lat · Telefone / WhatsApp: +1 786 726-1749 | +55 61 98268-4220

Oferta especial. Traga sua proposta de renovação de qualquer plataforma comercial de backup empresarial — Veeam, Commvault, NetBackup ou outras. Realizaremos uma análise comparativa com proposta formal visando pelo menos 50% de economia com funcionalidades AD/LDAP superiores. Entre em contato pelo heitor@opentechs.lat para obter uma cotação por escrito.

Sumário

  1. Resumo executivo
  2. Introdução e contexto de mercado
  3. Visão geral da arquitetura
  4. Modos de backup em detalhes
  5. Modos de restauração em detalhes
  6. Matriz de funcionalidades
  7. Guia de instalação
  8. Referência de configuração
  9. Exemplos de FileSet
  10. Dimensionamento e planejamento de capacidade
  11. Metas de desempenho
  12. Matriz de compatibilidade
  13. Segurança
  14. Monitoramento
  15. Guia de resolução de problemas
  16. Casos de uso e cenários de implantação
  17. Comparação com outras abordagens
  18. Roadmap
  19. Informações de contato
  20. Legal / direitos autorais

1. Resumo executivo

A infraestrutura de identidade — Microsoft Active Directory, OpenLDAP, 389-DS e Samba AD DC — é o componente mais crítico de qualquer ambiente de TI empresarial. Cada conta de usuário, cada associação de grupo, cada Group Policy Object (GPO), cada lista de controle de acesso e cada principal Kerberos reside no diretório. Quando dados de identidade são perdidos ou corrompidos, toda a organização para: logins falham, aplicações não conseguem autenticar e o acesso privilegiado a outros sistemas protegidos por backup se torna impossível.

Apesar dessa criticidade, a maioria das organizações não possui um backup dedicado para seus serviços de diretório. As abordagens comuns variam de exportações periódicas de ldif via scripts ldapsearch até a dependência do backup de estado do sistema Windows — nenhuma das quais se integra de forma limpa com uma plataforma de backup open-source, nenhuma oferece capacidade incremental real e nenhuma cobre a superfície completa de dados de identidade, incluindo SYSVOL, GPO, schema e ACLs.

O PodHeitor Active Directory / LDAP Backup Plugin for Bacula preenche essa lacuna. É um cdylib metaplugin puro em Rust carregado diretamente pelo bacula-fd, fornecendo backup e restauração sem agente, apenas via rede, dos serviços de diretório: Microsoft Active Directory (Windows Server 2012 R2 até 2025 e Samba AD DC), OpenLDAP 2.4/2.5/2.6, 389 Directory Server / Red Hat DS / FreeIPA e qualquer servidor compatível com LDAPv3 no modo genérico.

O plugin oferece cinco modos de backup cobrindo todos os cenários operacionais — desde snapshots lógicos equivalentes a ldif (modo ldap) até streaming incremental AD DirSync (modo ad), proteção contínua de dados (cdp), replicação ao vivo entre diretórios (replicate) e backup integrado de SYSVOL/GPO (hybrid_sysvol). Seis modos de restauração oferecem precisão desde a correção de um único atributo até a recuperação autoritativa completa de floresta. Tudo é gerenciado por meio da configuração padrão de Job e FileSet do Bacula, sem daemons auxiliares, sem scripts shell e sem arquivos de estado externos.

O plugin é construído com hardening de Unicode brasileiro embutido desde o início — um requisito prático para o mercado latino-americano, onde entradas de diretório frequentemente contêm cedilha, til e outros caracteres acentuados que quebram implementações menos robustas. 734 testes unitários, 45 testes de integração com LDAP ao vivo contra 389-DS e Samba AD, e um conjunto de testes de failover destrutivo durante varredura confirmam confiabilidade de nível produtivo.


2. Introdução e contexto de mercado

2.1 Por que o backup de diretório é uniquamente crítico

Ao contrário de um banco de dados ou sistema de arquivos, um serviço de diretório não é autossuficiente. Ele é a espinha dorsal de autenticação e autorização de todos os outros sistemas no ambiente. Uma falha de diretório se propaga imediatamente: o e-mail para de ser entregue, conexões VPN falham, o single sign-on na nuvem quebra, sistemas ERP recusam logins e o operador não consegue autenticar no próprio sistema de backup. A recuperação de uma perda de diretório sem backup adequado é medida em dias, não horas — e pode exigir reconstruir toda a infraestrutura de identidade do zero.

Os dados de diretório possuem diversas propriedades que tornam o backup genérico em nível de arquivo insuficiente:

  • Dependência de schema. Entradas LDAP referenciam classes de objeto e tipos de atributo do schema que precisam ser restaurados na ordem correta. Uma cópia bruta de arquivo NTDS.dit não captura o schema de forma independente.
  • Fidelidade de ACL e descritor de segurança. Cada objeto do AD carrega um descritor de segurança NT. Estes não são atributos simples e exigem tratamento especial durante a restauração.
  • Coerência entre GPO e SYSVOL. Os Group Policy Objects abrangem tanto o diretório LDAP (objetos groupPolicyContainer) quanto o compartilhamento de arquivo SYSVOL. Um backup que captura apenas o lado LDAP produz um conjunto de GPO inconsistente na restauração.
  • Estado da topologia de replicação. Em um ambiente multi-DC, a restauração deve considerar vetores USN e metadados de replicação para evitar ressurreição de tombstones e cenários de USN rollback.
  • Capacidade incremental. Diretórios grandes (100 mil+ objetos) não podem ser totalmente copiados na janela de backup disponível. Capacidade incremental real — via RFC 4533 syncrepl para OpenLDAP/389-DS ou Microsoft DirSync para AD — é essencial.

2.2 Por que as abordagens existentes são insuficientes

Abordagem Cobertura Veredicto
ldapsearch / scripts de exportação ldif Apenas dados lógicos; sem schema, sem ACLs, sem SYSVOL Não é adequado para produção; sem integração com Bacula; sem incremental
Backup de estado do sistema Windows NTDS.dit completo; apenas Windows; requer agente Windows no DC Viola requisito sem agente; sem suporte a OpenLDAP/389-DS
AD Recycle Bin Apenas recuperação de objetos em nível de objeto; retenção de 60–180 dias Não é um backup; sem restauração a um ponto no tempo
Veeam Sem agente nativo AD/LDAP em nível de protocolo de diretório Apenas backup em nível de VM; sem restauração de objetos sem add-on
Commvault Active Directory iDataAgent Apenas Windows AD; requer agente em cada DC Sem OpenLDAP/389-DS; custo de licença elevado
Bacula Community (nativo, sem plugin) Apenas nível de arquivo — faz backup dos arquivos brutos NTDS.dit ou MDB do OpenLDAP Inseguro com o diretório em operação; sem restauração lógica
NetBackup BMR Recuperação bare-metal; sem consciência de diretório Apenas restauração completa do servidor; sem precisão de objeto ou atributo

2.3 A abordagem PodHeitor

O plugin realiza backup apenas via rede, sem agente: conecta-se ao diretório via LDAP/LDAPS a partir do host do Bacula File Daemon, sem nenhum agente instalado no servidor de diretório. Isso é arquiteturalmente análogo a como um plugin de backup de banco de dados se conecta ao banco via seu protocolo nativo. O servidor de diretório é uma caixa preta; o plugin fala LDAPv3, RFC 4533 (syncrepl) e a extensão LDAP Microsoft DirSync — os mesmos protocolos de rede que o diretório expõe a qualquer parceiro de replicação.

Essa abordagem funciona igualmente bem para Windows Server AD (sem agente no DC), Samba AD DC, OpenLDAP e 389-DS. Um único plugin cobre todo o cenário de diretórios a partir de um único host Bacula File Daemon.


3. Visão geral da arquitetura

3.1 Metaplugin cdylib puro em Rust

Ao contrário de plugins PodHeitor anteriores que usam um pequeno shim em C/C++ para carregar um sidecar Rust, o plugin AD/LDAP é um cdylib puro em Rust (ADR-001). O único objeto compartilhado podheitor-adldap-fd.so é carregado diretamente pelo bacula-fd em tempo de execução e expõe a ABI do plugin Bacula File Daemon (loadPlugin / unloadPlugin e a tabela de callbacks de eventos) compilada nativamente em Rust. Não há fork, não há bpipe, não há processo sidecar.

Componente Arquivo Função
Plugin Bacula FD (cdylib) /opt/bacula/plugins/podheitor-adldap-fd.so Carregado pelo bacula-fd; implementa a ABI do plugin Bacula e o canal PTCOMM em processo
Engine principal (vinculado estaticamente) Dentro de podheitor-adldap-fd.so Toda a lógica LDAP, engines de backup/restauração, criptografia, métricas — sem binário externo

Vantagens do design cdylib puro:

  • Artefato único. Um arquivo para instalar, um arquivo para atualizar.
  • Cópia zero para grandes blobs ldif. O PTCOMM Path-A usa um canal MPSC em processo — dados de entrada LDAP nunca cruzam uma fronteira de processo.
  • Análise de rede com segurança de memória. O protocolo de rede LDAP é analisado inteiramente em Rust seguro; sem possibilidade de buffer overflows em C no caminho de entrada LDAP.
  • Isolamento de pânicos. Toda fronteira C-ABI é envolvida em catch_unwind; um pânico na lógica de backup propaga um erro de job para o Bacula em vez de travar o bacula-fd.

3.2 PTCOMM Path-A (em processo)

PTCOMM é o protocolo de enquadramento binário PodHeitor usado em todos os plugins PodHeitor para logging uniforme, multiplexação de métricas e sinalização do ciclo de vida do job. No plugin AD/LDAP, o Path-A é utilizado: frames fluem por um canal MPSC entre o shim ABI do Bacula e o engine de backup/restauração no mesmo espaço de endereço do processo.

PTCOMM status characters:
  P = ping/handshake    O = ok/ack        J = jobinfo
  C = config/params     S = start         D = data
  E = end               R = restoreobject M = metric
  L = log               T = terminal      X = error

O ciclo de vida PTCOMM por job:

1. Handshake:  fd → plugin  "P000010nADLDAP_v1"
               plugin → fd  "O000003nACK"
2. JobInfo:    fd → plugin  "J<len>n<msgpack(JobInfo)>"
3. Params:     fd → plugin  "C<len>n<msgpack(BackupParams|RestoreParams)>"
               plugin → fd  "O000002nOK"
4. Start:      fd → plugin  "S000005nSTART"
5. Data:       plugin → fd  "D<len>n<chunk>"   (repeats)
               plugin → fd  "M<len>n<msgpack(metric)>"
               plugin → fd  "L<len>n<json log>"
6. End:        plugin → fd  "E000003nEND"
7. RestoreObj: plugin → fd  "R<len>n<msgpack(RestoreObject)>"
8. Status:     plugin → fd  "T<len>n<msgpack(JobStatus)>"

3.3 Diagrama de arquitetura

  ┌──────────────────────────────────────────────────────────────────────┐
  │  Bacula File Daemon (bacula-fd) — Linux x86_64                        │
  │                                                                      │
  │  ┌─────────────────────────────────────────────────────────────────┐ │
  │  │  podheitor-adldap-fd.so  (pure-Rust cdylib)                     │ │
  │  │                                                                 │ │
  │  │  ┌──────────────────────────────────────────────────────────┐   │ │
  │  │  │  ABI shim (plugin-adldap crate)                           │   │ │
  │  │  │  loadPlugin / unloadPlugin / handlePluginEvent            │   │ │
  │  │  │  catch_unwind at every C boundary                         │   │ │
  │  │  └───────────────────────┬──────────────────────────────────┘   │ │
  │  │                          │ PTCOMM Path-A (in-process MPSC)       │ │
  │  │  ┌───────────────────────▼──────────────────────────────────┐   │ │
  │  │  │  adldap-core engine                                       │   │ │
  │  │  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │   │ │
  │  │  │  │ ldap mode│ │  ad mode │ │ cdp mode │ │hybrid_sysvol│ │   │ │
  │  │  │  │(syncrepl)│ │(DirSync) │ │(CDP/CDP- │ │(LDAP+SYSVOL)│ │   │ │
  │  │  │  │          │ │          │ │ DirSync) │ │             │ │   │ │
  │  │  │  └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬──────┘ │   │ │
  │  │  │       │             │             │              │         │   │ │
  │  │  │  ┌────▼─────────────▼─────────────▼──────────────▼─────┐  │   │ │
  │  │  │  │  ldap3 crate (async LDAPv3 client)                   │  │   │ │
  │  │  │  │  RFC 4533 syncrepl · MS DirSync · RFC 2696 paged    │  │   │ │
  │  │  │  │  GSSAPI/Kerberos · StartTLS · LDAPS                 │  │   │ │
  │  │  │  └─────────────────────────────────────────────────────┘  │   │ │
  │  │  │                                                            │   │ │
  │  │  │  ┌───────────┐  ┌──────────┐  ┌──────────┐               │   │ │
  │  │  │  │  Restore  │  │  Crypto  │  │ Metrics  │               │   │ │
  │  │  │  │  engine   │  │AES-256-  │  │Prometheus│               │   │ │
  │  │  │  │ 6 modes   │  │GCM/CCP20 │  │textfile  │               │   │ │
  │  │  │  └───────────┘  └──────────┘  └──────────┘               │   │ │
  │  │  └─────────────────────────────────────────────────────────────┘   │ │
  │  └─────────────────────────────────────────────────────────────────┘ │
  └──────────────────────────────────────────────────────────────────────┘
       │                          │
       │ LDAP/LDAPS               │ SMB/CIFS (hybrid_sysvol only)
       ▼                          ▼
  ┌───────────────┐     ┌──────────────────────┐
  │ AD / OpenLDAP │     │ SYSVOL share          │
  │ 389-DS / Samba│     │ dcSYSVOLdomain   │
  │ (any LDAPv3)  │     │ Policies + scripts  │
  └───────────────┘     └──────────────────────┘
       │
       │ Bacula protocol (TCP)
       ▼
  ┌───────────────────┐
  │ Bacula Storage    │
  │ Daemon + Catalog  │
  └───────────────────┘

3.4 Formato em disco: híbrido MessagePack-LDIF

Cada entrada LDAP é armazenada como um arquivo de dois segmentos sob o caminho 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

Esse formato é aproximadamente 3–4x mais compacto que ldif bruto para payloads AD (MessagePack vs base64), é seguro para Unicode e suporta ordenação determinística para operações de diff. Uma visão ldif secundária é gerada sob demanda para os modos dry_run e diff.

3.5 Portador de estado RestoreObject

Ao final do backup, o plugin emite um RestoreObject chamado adldap-state.msgpack no catálogo do Bacula. Este carrega o cookie syncrepl (RFC 4533) ou cookie DirSync (AD), o maior USN/CSN visto, um hash SHA-256 do schema e o manifesto completo de entradas. O próximo job incremental resgata o cookie automaticamente do catálogo — nenhum arquivo de estado em disco é necessário, portanto o plugin sobrevive à perda e reinstalação do host sem perder a linha de base incremental.


4. Modos de backup em detalhes

4.1 Modo ldap — RFC 4533 syncrepl (OpenLDAP / 389-DS)

Como funciona

O modo ldap conecta-se a qualquer servidor LDAPv3 e realiza uma busca paginada (RFC 2696) para backups Full, e RFC 4533 syncrepl (refreshOnly ou refreshAndPersist) para backups Incrementais e Diferenciais. Cada entrada é serializada no formato MessagePack-LDIF e transmitida como um arquivo virtual do Bacula.

O cookie syncrepl é carregado no RestoreObject após cada job. O próximo job Incremental apresenta o cookie ao servidor e recebe apenas as entradas alteradas desde aquele ponto — incluindo modificações, adições e exclusões (o servidor marca exclusões com 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

Compatibilidade com Samba AD

A implementação syncrepl do Samba AD omite o controle SyncStateValue por entrada do RFC 4533 que o 389-DS inclui. O plugin detecta isso em tempo de análise e sintetiza a identidade da entrada a partir de objectGUID (preferido) ou entryUUID (fallback), roteando a entrada como state=add. Isso é semanticamente correto para a entrega refresh-only de snapshot completo do Samba. As respostas do 389-DS permanecem no caminho estrito.

Quando usar

  • OpenLDAP 2.4/2.5/2.6 — alvo primário suportado
  • 389 Directory Server / Red Hat DS / núcleo de diretório FreeIPA
  • Samba AD DC no modo syncrepl
  • Qualquer servidor LDAPv3 sem suporte a Microsoft DirSync
  • Ambientes onde um backup lógico e portável equivalente a ldif é necessário

4.2 Modo ad — Microsoft DirSync

Como funciona

O modo ad usa o controle estendido LDAP Microsoft DirSync (OID 1.2.840.113556.1.4.841) para transmitir alterações de diretório do Active Directory. O DirSync é o mesmo mecanismo usado pelos parceiros de replicação do AD e é o único método suportado pela Microsoft para enumeração incremental de diretório. Ele captura todas as alterações de objetos incluindo modificações de descritor de segurança, objetos tombstoned (entradas excluídas) e atributos operacionais.

Para backups Full, o plugin emite uma solicitação DirSync sem cookie anterior, fazendo com que o AD retorne toda a árvore de diretório. Para backups Incrementais, o cookie anterior (armazenado no RestoreObject) é apresentado e o AD retorna apenas as alterações desde aquela marca d’água.

Os cookies DirSync codificam intervalos USN (Update Sequence Number). Como a replicação DRS garante que cada DC na floresta armazene as mesmas alterações com vetores de marca d’água consistentes, um cookie emitido pelo DC1 pode ser transferido com segurança para o DC2 durante o failover — o plugin lida com isso de forma transparente (veja a Seção 4.5).

Permissões AD necessárias

O usuário de bind deve ter:

  • SeSyncAgentPrivilege (“Replicando Alterações de Diretório”) — obrigatório para DirSync.
  • Replicating Directory Changes All — necessário para acesso a tombstone e Recycle Bin.
  • Replicating Directory Changes In Filtered Set — para ambientes RODC.
  • Acesso de leitura a <dc>SYSVOL<domain>Policies — necessário apenas para o modo hybrid_sysvol.

Uma conta com privilégio mínimo “Operador de Backup – PodHeitor” pode ser delegada via dsacls.exe — o guia do operador fornece a receita exata.

Quando usar

  • Microsoft Active Directory (Windows Server 2012 R2 até 2025)
  • Samba AD DC no modo DirSync (raiz do domínio basedn= obrigatória — veja nota do operador)
  • Qualquer cenário que exija acesso a tombstone e integração com AD Recycle Bin
  • Ambientes multi-DC onde a portabilidade do cookie USN é necessária

4.3 Modo hybrid_sysvol — LDAP DirSync + SYSVOL/GPO

Como funciona

O modo hybrid_sysvol realiza uma varredura LDAP DirSync completa do diretório (idêntica ao modo ad) e simultaneamente anexa um snapshot do compartilhamento SYSVOL em nível SMB-CIFS usando libsmbclient-rs (bindings Rust para libsmbclient.so). Os arquivos SYSVOL são armazenados em @adldap/<server>/sysvol/... com preservação completa de NT ACL via descritores de segurança NT codificados em msgpack.

As fases LDAP e SYSVOL são executadas como um par de única passagem dentro de um job. O failover LDAP mid-stream para um DC diferente é intencionalmente recusado: se a fase LDAP rotacionar para o DC2 enquanto a fase SYSVOL ainda aponta para o sysvol_uri= do DC1, o backup resultante conterá objetos de diretório do DC2 e arquivos GPO do DC1, que podem estar em estados de replicação diferentes. O plugin recusa esse cenário de split-brain e falha com Fatal, exigindo que a próxima execução agendada comece do zero.

Quando usar

  • Qualquer ambiente Active Directory onde a capacidade de restauração de GPO é necessária
  • Cenários de conformidade que exigem estado de identidade completo incluindo scripts de login, pacotes de instalação de software e modelos de segurança em Policies
  • Planejamento de DR onde um snapshot consistente LDAP+SYSVOL é o ponto de restauração autoritativo

4.4 Modo replicate — replicação ao vivo entre diretórios

Como funciona

O modo replicate abre uma sessão syncrepl (ou DirSync) contra o diretório de origem e simultaneamente abre uma sessão de escrita LDAP contra um diretório de destino configurado por replicate_target_uri=. Cada alteração observada na origem é aplicada ao destino imediatamente. O stream de backup do Bacula ainda recebe uma cópia para auditabilidade de catálogo e restauração a um ponto no tempo.

A replicação entre fornecedores (AD → OpenLDAP ou vice-versa) é suportada via um arquivo de mapeamento de schema configurável (default-schema-mapping.toml). O mapeamento padrão traduz sAMAccountNameuid, userPrincipalNamemail e objectGUIDentryUUID (UUIDv4 determinístico). A detecção de loop é tratada via objectGUID (AD) ou entryUUID (RFC 4530) para evitar tempestades de replicação em topologias bidirecionais.

Quando usar

  • Espelho de identidade em modo cold-standby em um datacenter de DR, sem necessidade de AD Trust ou replicação multi-master
  • Projetos de migração de identidade entre fornecedores (transição AD → OpenLDAP)
  • Cópia de auditoria em tempo real de um diretório de produção para um servidor LDAP somente leitura

4.5 Modo cdp — proteção contínua de dados

Como funciona

O modo cdp usa syncrepl refreshAndPersist para manter uma conexão persistente com o servidor de diretório e transmitir alterações em tempo real. O job do Bacula permanece aberto e emite chunks de backup a cada cdp_max_seconds (padrão 60 segundos), limitando o RPO a esse intervalo. O sub-modo cdp_dirsync fornece a mesma semântica para o Active Directory usando o modelo de polling persistente DirSync.

Quando ocorre uma falha de transporte, o plugin esgota a lista de URI de failover (avançando em erros TCP, falhas TLS e condições de servidor LDAP indisponível) com backoff exponencial governado por cdp_reconnect_max_attempts, cdp_reconnect_initial_backoff_ms e cdp_reconnect_max_backoff_ms. O cookie syncrepl ou DirSync mais recente é preservado entre as reconexões via DcSelector::carry_cookie, para que o plugin retome de onde parou em vez de reler todo o diretório.

Failover multi-DC

Todos os modos de backup que aceitam ldapuri= (ou target_ldapuri= para restauração) suportam uma lista separada por vírgula de URIs LDAP. O plugin trata isso como uma sequência de failover somente para frente. O seletor avança apenas em erros de nível de transporte (TCP recusado/reiniciado/timeout, falha DNS, falha de handshake TLS, servidor LDAP indisponível). Não avança em falhas de autenticação, falhas de autorização ou erros de configuração — estes falham imediatamente pois as mesmas credenciais falharão em todo DC.

Modo Failover na conexão Failover mid-stream Cookie transferido entre DCs
ldap (refresh-only) Sim Não Sim (sidecar do operador)
ad (DirSync) Sim Sim Sim (USN replicado)
cdp (refresh+persist) Sim Sim Sim (cluster-CSN)
cdp_dirsync Sim Sim Sim (USN replicado)
hybrid_sysvol Sim Não (por design) n/a (par LDAP+SYSVOL)
replicate Sim Sim Sim (gerenciado pelo seletor)
restore (qualquer submodo) Sim Não (por design) n/a

5. Modos de restauração em detalhes

O engine de restauração aceita um parâmetro mode= selecionando entre seis estratégias de restauração. Todos os modos compartilham a mesma infraestrutura de streaming de entradas; a diferença está no que escrevem no diretório de destino.

5.1 Modo object

Restaura uma única entrada identificada por DN ou objectGUID. A entrada é re-adicionada (ou modificada se já estiver presente, com base na política replace=) com todos os atributos do backup. Este é o modo padrão para restauração seletiva — “Excluí acidentalmente uma conta de usuário.”

5.2 Modo subtree

Restaura uma unidade organizacional inteira e todos os seus descendentes. O engine reordena as entradas com os pais primeiro e pode criar OUs pai ausentes se create_parents=true. O parâmetro where_basedn= redireciona a restauração para uma OU de staging (por exemplo, ou=Restaurado,dc=lab,dc=local) para que a árvore ao vivo não seja perturbada durante a verificação.

5.3 Modo attribute

Restaura N atributos especificados em M entradas sem tocar em outros atributos. Usa semântica LDAP Modify Replace — os atributos especificados são substituídos pelos valores do backup; todos os outros atributos permanecem como estão no diretório ao vivo. Ideal para “redefinir displayName para o valor do backup em uma OU inteira” sem uma restauração completa de subárvore.

5.4 Modo authoritative

Realiza uma restauração completa e eleva a versão USN do AD nos objetos restaurados para que outros DCs repliquem A PARTIR do DC restaurado em vez de sobrescrevê-lo. É o equivalente da restauração autoritativa do AD e é bloqueado por um parâmetro obrigatório i_understand=yes — aplicar esse modo sem o gate aciona um Fatal imediato sem gravar nenhuma entrada LDAP. O guia do operador explica o raio de impacto e os passos necessários de isolamento de DC.

5.5 Modo dry_run

Computa o ldif que SERIA aplicado e o escreve no RestoreLog do Bacula. Nenhum canal de escrita LDAP é aberto contra o destino. Use para verificação antes de executar uma restauração destrutiva.

5.6 Modo diff

Compara o snapshot de backup com o diretório ao vivo e produz um relatório JSON de adições, exclusões e modificações: {adds: [], dels: [], mods: []}. Totalmente somente leitura. Útil para auditoria de conformidade, detecção de alterações e perícia pós-incidente.


6. Matriz de funcionalidades

Funcionalidade ldap ad hybrid_sysvol replicate cdp
Backup Full Sim Sim Sim Sim Sim
Backup Incremental (RFC 4533) Sim Não Não Sim Sim
Backup Incremental (DirSync) Não Sim Sim Não Sim (cdp_dirsync)
Failover multi-DC Sim Sim Sim Sim Sim
Cookie transferido entre DCs Sim Sim n/a Sim Sim
Backup SYSVOL / GPO Não Não Sim Não Não
Preservação NT ACL Parcial Sim Sim Sim Sim
Replicação entre fornecedores Não Não Não Sim Não
Criptografia em repouso (AES-256-GCM) Sim Sim Sim Sim Sim
Criptografia em repouso (ChaCha20-Poly1305) Sim Sim Sim Sim Sim
Backend KMS HashiCorp Vault Sim Sim Sim Sim Sim
Métricas Prometheus Sim Sim Sim Sim Sim
Logging estruturado JSON-Lines Sim Sim Sim Sim Sim
Hardening Unicode brasileiro (NFC/NFD) Sim Sim Sim Sim Sim
Catalogação estável por objectGUID Não Sim Sim Sim Sim
Backup paralelo por branch (pool por OU) Sim Sim Não Não Não
Suporte ao AD Recycle Bin Não Sim Sim Não Sim (cdp_dirsync)
Autenticação Kerberos / GSSAPI Não Sim Sim Sim Sim
StartTLS / LDAPS Sim Sim Sim Sim Sim
Pacote RPM Sim Sim Sim Sim Sim
Pacote DEB Sim Sim Sim Sim Sim
RestoreObject cookie carry Sim Sim n/a Sim Sim
RPO sub-minuto (CDP) Não Não Não Não Sim
Compressão zstd Sim Sim Sim Sim Sim
Compressão lz4 Sim Sim Sim Sim Sim

7. Guia de instalação

7.1 Pré-requisitos

  • Bacula Community 15.0.3 ou posterior instalado; bacula-fd em execução em um host Linux x86_64
  • Conectividade de rede do host bacula-fd para o servidor de diretório na porta LDAP (389) ou LDAPS (636)
  • Para mode=ad / Kerberos: cliente Kerberos configurado (/etc/krb5.conf apontando para o realm AD); keytab em /etc/podheitor/bacula.keytab
  • Para mode=hybrid_sysvol: samba-client-libs (ou equivalente) fornecendo libsmbclient.so
  • SO: RHEL/OL/Rocky 9+ ou Ubuntu 22.04+/Debian 12+
  • glibc 2.34+

7.2 Instalação 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 Instalação 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 Configuração de credenciais — bind simples

# 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 Configuração de credenciais — 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 Verificação da instalação — 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"
} }

Execute um job Full via bconsole: *run job=Smoke-ADLDAP level=Full yes. Esperado: status do job T com bytes gravados não nulos e PTCOMM STARTEND visível no log do job.


8. Referência de configuração

8.1 Parâmetros de backup

Parâmetro Padrão Descrição
mode (obrigatório) ldap / ad / replicate / cdp / hybrid_sysvol
ldapuri (obrigatório) URI(s) LDAP, separados por vírgula para failover multi-DC
binddn DN de bind simples (omitir se kerberos=yes)
bindpass_file Caminho para arquivo contendo a senha de bind (modo 0600)
kerberos no Usar autenticação GSSAPI/Kerberos
keytab Caminho do arquivo keytab (obrigatório se kerberos=yes)
starttls auto Atualizar para TLS em ldap:// se o servidor anunciar StartTLS
tls_cacert Pacote de CA personalizado para LDAPS ou StartTLS
basedn (obrigatório) DN base de busca LDAP
filter (objectClass=*) Filtro de busca LDAP para delimitar o escopo do backup
attribs_include *,+ Atributos a incluir (+ = atributos operacionais)
attribs_exclude Atributos a ignorar (por exemplo, userPassword)
page_size 1000 Tamanho de página da busca paginada RFC 2696
parallel_branches 1 Tamanho do pool de threads paralelas por OU; 0 = automático (contagem de CPU)
include_recycle_bin no Somente AD — incluir objetos tombstoned/excluídos via LDAP_SERVER_SHOW_DELETED
dirsync_flags 0x801 Flags do controle DirSync (OBJECT_SECURITY|INCREMENTAL_VALUES|ANCESTORS_FIRST_ORDER)
sysvol_uri URI SMB para compartilhamento SYSVOL; obrigatório para mode=hybrid_sysvol
sysvol_pass_file Arquivo de senha SMB para acesso ao SYSVOL
compress zstd none / zstd / lz4
compress_level 3 Nível de compressão 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 (padrão) Caminho para default-schema-mapping.toml para replicação entre fornecedores
cdp_max_seconds 60 Intervalo de chunk CDP em segundos (limita o RPO)
cdp_reconnect_max_attempts 6 Máximo de varreduras completas da lista de URI antes de Fatal
cdp_reconnect_initial_backoff_ms 500 Backoff inicial de reconexão em milissegundos
cdp_reconnect_max_backoff_ms 30000 Cap máximo de backoff de reconexão em milissegundos
metrics_path /var/lib/podheitor/adldap.prom Caminho de saída do textfile Prometheus
no_normalize_dn no Desabilitar normalização NFC em DNs (escape hatch)
allow_anonymous no Defesa em profundidade: recusar bind anônimo
verify_after_backup yes Reler manifesto e recomputar digests após o backup

8.2 Parâmetros de restauração

Parâmetro Padrão Descrição
mode object object / subtree / attribute / authoritative / dry_run / diff
target_ldapuri (URI do backup) URI do diretório de destino; suporta failover separado por vírgula
target_binddn DN de bind de destino (padrão: DN de bind da origem)
target_bindpass_file Arquivo de senha de bind de destino
target_kerberos no Usar Kerberos para conexão de destino
where_basedn Redirecionar restauração para um DN base diferente (OU de staging)
replace never never / if-newer / always
attributes * Atributos separados por vírgula para restaurar (para mode=attribute)
entries * DNs ou objectGUIDs a restaurar (padrão: todos)
create_parents no Criar OUs pai ausentes durante restauração de subárvore
i_understand Deve ser yes para habilitar mode=authoritative
password_reset keep keep / random / force=<pwd> para senhas de contas de usuário
dry_run_output Caminho para gravar a prévia ldif para mode=dry_run
diff_output Caminho para gravar o relatório JSON de diff para mode=diff
decrypt_kms Caminho do backend KMS para descriptografar um backup criptografado

9. Exemplos de FileSet

9.1 Backup 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 Backup Full Active Directory com 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 Backup 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 Backup 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 — proteção contínua 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 Replicação entre fornecedores — AD para 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 Restauração — 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 Restauração — prévia dry run antes da restauração autoritativa

Plugin = "podheitor-adldap: mode=dry_run 
          target_ldapuri=ldaps://dc01.corp.local 
          target_kerberos=yes 
          dry_run_output=/tmp/preview-restore.ldif"

10. Dimensionamento e planejamento de capacidade

10.1 Requisitos de memória

Cenário Linha de base bacula-fd RAM adicional do plugin
backup full ldap / ad, single-threaded 512 MB +64 MB
backup full ad, parallel_branches=4 512 MB +256 MB (4×64 MB)
Modo CDP (conexão persistente) 512 MB +96 MB
hybrid_sysvol (LDAP + SMB) 512 MB +128 MB
Alvo de backup com 100 mil entradas (cap RSS) ≤250 MB RSS total do bacula-fd

10.2 Estimativas de volume de backup

Modo Armazenamento aproximado por 100 mil objetos
ldap / ad full (sem compressão) 200–500 MB (varia com a densidade de atributos)
ldap / ad full (zstd nível 3) 60–150 MB
Incremental (1% alterado) 2–10 MB
SYSVOL / GPO (hybrid_sysvol) 10–200 MB (varia com contagem de GPO e tamanho de política)
RestoreObject (cookie + manifesto) ≤50 MB (comprimido com zstd; pior caso 1M de entradas)

10.3 Metas de desempenho (metas de laboratório v0.1.0)

Cenário Meta
100 mil entradas OpenLDAP, backup full ≤8 minutos (4 vCPU, 4 GB RAM)
100 mil entradas OpenLDAP, incremental syncrepl (1% alterado) ≤1 minuto
50 mil objetos AD, DirSync full ≤5 minutos
Incremental AD DirSync (100 alterações) ≤15 segundos
RPO CDP (cdp_max_seconds=60) ≤90 segundos de ponta a ponta

10.4 Espaço em disco — instalação do plugin

Arquivo Tamanho
podheitor-adldap-fd.so ~2–3 MB (Rust com todas as funcionalidades vinculadas estaticamente)
Footprint total da instalação ~2–3 MB

Nenhum binário sidecar externo é necessário. libsmbclient.so é uma dependência de pacote do sistema apenas para o modo hybrid_sysvol.


11. Relatório de desempenho

Todas as medições são realizadas no ambiente de laboratório PodHeitor em VMs Rocky Linux 9.4 (2–4 vCPU, 2–4 GB RAM) conectadas a servidores Samba AD DC e 389-DS em uma LAN 192.168.15.0/24. Bacula Community 15.0.3 é usado em todos os testes.

11.1 Status da suíte de testes — v0.1.0

Categoria Testes Status
Testes unitários (adldap-core) 734 Todos aprovados
Testes unitários (shim ABI plugin-adldap) 14 Todos aprovados
Testes de integração com LDAP ao vivo (389-DS + Samba AD) 45 Todos aprovados
Teste destrutivo de failover mid-sweep (opt-in) 1 Aprovado (#[ignore])
Cenários de restauração sobre dano ao vivo (delete, modify+delete, modrdn, wipe completo) 4 Todos aprovados
Restauração autoritativa E2E (Samba AD) 2 Todos aprovados
Total 800+ Todos aprovados

11.2 Resultados do teste de failover multi-DC

Teste Resultado
Failover no momento de conexão (DC1 inativo no início) Aprovado — conecta ao DC2 de forma transparente
Failover mid-stream (cdp_dirsync): DC1 parado no meio do polling Aprovado — cookie transferido entre DCs
Failover mid-sweep com 50 entradas preenchidas Aprovado — cookie_len=N (N>0) confirmado no log
Continuidade incremental pós-reconexão Aprovado — sem entradas duplicadas após reconexão

11.3 Resultados de cenário de restauração (389-DS)

Cenário Descrição Resultado
cenário1 Objeto excluído; restauração via mode=object Aprovado — atributos originais incluindo mail round-trip
cenário2 Atributo mutado após backup, depois entrada excluída; restauração traz valor original Aprovado
cenário3 Entrada renomeada via modrdn; restauração recria DN original Aprovado — DN original recriado, cópia renomeada persiste (não destrutivo)
cenário4 OU inteira (5 filhos) excluída de baixo para cima; restauração via mode=subtree Aprovado — todas as 5 folhas round-trip

11.4 Resultados de restauração autoritativa (Samba AD)

Teste Resultado
autoritativa sem i_understand=yes → Fatal Aprovado — frame Error + Fatal; zero escritas LDAP
autoritativa com gate: 2 entradas copiadas, excluídas, replicadas Aprovado — terminal=Ok, applied≥2, ambos DNs presentes, uSNChanged estritamente > pré-restauração

12. Matriz de compatibilidade

12.1 Sistema operacional

SO Arquitetura Status
RHEL 9 x86_64 Suportado
Oracle Linux 9 x86_64 Suportado
Rocky Linux 9 x86_64 Suportado (plataforma de laboratório)
AlmaLinux 9 x86_64 Suportado
Ubuntu 22.04 LTS x86_64 Suportado
Debian 12 x86_64 Suportado
RHEL 8 / CentOS 8 x86_64 Não testado (glibc < 2.34)
Ubuntu 20.04 x86_64 Não testado (glibc < 2.34)
ARM64 / aarch64 qualquer Ainda não disponível

12.2 Versões de servidor de diretório

Servidor de diretório Versão Modo Status
Microsoft Active Directory Windows Server 2012 R2 – 2025 ad, hybrid_sysvol, cdp_dirsync Suportado
Samba AD DC Qualquer versão Samba atual ad, ldap, hybrid_sysvol Suportado (testado em laboratório)
OpenLDAP (slapd) 2.4, 2.5, 2.6 ldap, cdp, replicate Suportado
389 Directory Server Atual ldap, cdp, replicate Suportado (testado em laboratório)
Red Hat DS / FreeIPA Atual ldap, cdp Suportado (via 389-DS)
ApacheDS Atual ldap (genérico) Melhor esforço
OpenDJ Atual ldap (genérico) Melhor esforço

12.3 Versões do Bacula

Versão do Bacula Status
Community 15.0.3 Suportado (validado)
Community 15.0.x (futuro) Compatibilidade esperada
Community 14.x Não suportado
Bacula Enterprise Não necessário; o plugin é direcionado ao Bacula Community

12.4 Controles LDAP utilizados

OID Nome Utilizado por
1.2.840.113556.1.4.319 Resultados paginados (RFC 2696) Backup 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 estendido (V2) AD ≥ 2008 R2
1.2.840.113556.1.4.529 LDAP_SERVER_EXTENDED_DN Restauração AD
1.3.6.1.4.1.1466.20037 StartTLS Atualizações TLS
1.3.6.1.4.1.4203.1.11.1 Password Modify (RFC 3062) Restauração com redefinição de senha

13. Segurança

13.1 Tratamento de credenciais

Senhas de bind nunca são armazenadas na configuração de FileSet ou Job do Bacula. Todas as senhas são lidas de arquivos dedicados com modo 0600 de propriedade do usuário bacula. A senha é passada em memória para a biblioteca cliente LDAP; nunca é gravada em disco durante o job, nunca aparece nos argumentos de processo visíveis via ps e é redatada de toda a saída de log (logging JSON-Lines com redação obrigatória para bindpass, target_bindpass, conteúdo do keytab e chaves resolvidas pelo KMS).

Arquivos keytab Kerberos devem ter modo 0600; o plugin recusa usar um keytab com permissões mais permissivas.

13.2 Criptografia em repouso

O plugin fornece sua própria camada de criptografia em repouso independente da criptografia em nível de stream do Bacula. Dois algoritmos são suportados:

  • AES-256-GCM — o padrão recomendado para ambientes com aceleração de hardware AES.
  • ChaCha20-Poly1305 — preferido para ambientes sem hardware AES (por exemplo, plataformas embarcadas ou ARM).

Três backends KMS são fornecidos:

  • file:/path/key — chave armazenada em um arquivo (mais simples; arquivo de chave deve ser 0600).
  • vault:transit/keys/name — engine Transit do HashiCorp Vault; chaves nunca saem do Vault.
  • sops:/path — arquivo de chave criptografado Mozilla SOPS.

Uma tentativa de restauração com configuração KMS ausente ou incorreta falha rapidamente com um erro explícito antes que qualquer escrita no diretório seja tentada.

13.3 Segurança de rede

O plugin suporta LDAPS (TLS direto na porta 636) e StartTLS (atualização na porta 389). Não abre portas de escuta adicionais no host bacula-fd. Para o modo hybrid_sysvol, a conexão SMB ao compartilhamento SYSVOL usa o ticket Kerberos obtido do keytab — nenhuma credencial SMB separada é necessária se o Kerberos estiver configurado.

O bind anônimo é recusado por padrão (allow_anonymous=no). Esta é uma medida de defesa em profundidade; qualquer operador que habilite explicitamente o bind anônimo deve auditar cuidadosamente suas ACLs de diretório.

13.4 Gate de segurança de restauração autoritativa

A restauração mode=authoritative é estruturalmente bloqueada: o loop de aplicação não tem acesso ao seletor e não pode prosseguir sem que o parâmetro i_understand=yes esteja definido explicitamente. Este não é uma verificação em tempo de execução — é imposto pelo sistema de tipos Rust. Um job de restauração sem o gate emite um frame Error e um status terminal Fatal sem realizar uma única escrita LDAP, e o cumprimento do gate é coberto por um teste ao vivo contra Samba AD na suíte de testes.


14. Monitoramento

14.1 Métricas de textfile Prometheus

Ao final do job (e periodicamente durante o modo CDP), o plugin grava métricas de textfile Prometheus em /var/lib/podheitor/adldap.prom (caminho configurável via metrics_path=). Estas podem ser coletadas pelo coletor de textfile do Node Exporter.

14.2 Métricas expostas

Métrica Tipo Descrição
podheitor_adldap_entries_backed_up Counter Total de entradas LDAP serializadas para o Bacula
podheitor_adldap_bytes_written Counter Total de bytes gravados no Bacula Storage Daemon
podheitor_adldap_job_duration_seconds Histogram Duração de backup por job
podheitor_adldap_errors_total Counter Total de eventos de erro por código de erro
podheitor_adldap_replicate_lag_seconds Gauge Modo CDP/replicate: idade da alteração mais recente aplicada
podheitor_adldap_failover_events_total Counter Contagem de eventos de failover multi-DC por modo e par de DC
podheitor_adldap_cookie_age_seconds Gauge Idade do cookie syncrepl/DirSync atual
podheitor_adldap_compression_ratio Gauge Razão de compressão mais recente (comprimido / bruto)

14.3 Configuração de coleta de textfile Node Exporter

scrape_configs:
  - job_name: 'podheitor-adldap'
    static_configs:
      - targets: ['bacula-fd-host:9100']
    metrics_path: /metrics
    scrape_interval: 60s

O Node Exporter deve ser iniciado com --collector.textfile.directory=/var/lib/podheitor/ (ou o caminho configurado via metrics_path=).

14.4 Logging estruturado JSON-Lines

Toda a saída de log do plugin é emitida como JSON Lines para stderr (capturado pelo bacula-fd) e copiada para /var/log/bacula/podheitor-adldap-&lt;jobid&gt;.log. Níveis: TRACE / DEBUG / INFO / WARN / ERROR. Eventos de diagnóstico importantes emitidos no nível 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"}

Pesquise no log do job FD por failing over, exhausted ou schema_hash mismatch para identificar eventos operacionalmente significativos para relatórios de SLO.


15. Guia de resolução de problemas

15.1 Erros comuns

Plugin não encontrado na inicialização

Error: cannot open shared object file: No such file or directory

Causa. podheitor-adldap-fd.so não está no diretório de plugins configurado.
Solução. Verifique se /opt/bacula/plugins/podheitor-adldap-fd.so existe e se a diretiva PluginDirectory no bacula-fd.conf aponta para /opt/bacula/plugins.

Conexão LDAP recusada

podheitor-adldap: LDAP_SERVER_DOWN connecting to ldaps://dc01.corp.local:636

Causa. O servidor de diretório está inacessível, TLS falhou ou o URI está incorreto.
Solução:

# 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 &lt; /dev/null

Falha de autenticação Kerberos

podheitor-adldap: GSSAPI bind failed: clock skew too great

Causa. O relógio do host bacula-fd está mais de 5 minutos fora de sincronia com o controlador de domínio.
Solução:

systemctl enable --now chronyd
chronyc makestep   # force immediate sync

DirSync com permissão negada

podheitor-adldap: DirSync control rejected: insufficientAccessRights (50)

Causa. O usuário de bind não possui SeSyncAgentPrivilege no domínio.
Solução. Delegue os direitos necessários via dsacls.exe ou pelo assistente de delegação do Active Directory Users and Computers. Consulte o Guia do Operador para o comando dsacls exato.

Samba AD: basedn DirSync rejeitado

podheitor-adldap: DirSync unwillingToPerform (53): basedn must be domain root

Causa. O Samba AD rejeita solicitações DirSync com raiz abaixo do contexto de nomenclatura de domínio.
Solução. Defina basedn=dc=lab,dc=local (raiz do domínio) e use filter= para delimitar os resultados:

Plugin = "podheitor-adldap: mode=ad ... 
          basedn=dc=lab,dc=local 
          filter=(&amp;(objectClass=user)(memberOf=cn=eng,ou=groups,dc=lab,dc=local))"

Incompatibilidade de hash do schema — backup full promovido

podheitor-adldap: schema_hash mismatch (stored=abc123, current=def456); promoting to Full

Causa. O schema do diretório foi alterado entre o último backup Full e este Incremental (por exemplo, uma extensão de schema AD foi aplicada).
Solução. Esse é o comportamento esperado. O plugin corretamente se autopromove para Full e salva o novo hash do schema. Nenhuma ação do operador é necessária a menos que a mudança de schema tenha sido não intencional.

Restauração autoritativa rejeitada — gate ausente

podheitor-adldap: mode=authoritative requires i_understand=yes; refusing to write

Causa. O parâmetro i_understand=yes não foi definido no job de restauração.
Solução. Adicione i_understand=yes à Plugin string de restauração. Leia a seção do Guia do Operador sobre o raio de impacto da restauração autoritativa antes de prosseguir.

15.2 Localizações de logs

Log Caminho
Log principal bacula-fd /opt/bacula/log/bacula-fd.log
Log por job do plugin /var/log/bacula/podheitor-adldap-&lt;jobid&gt;.log
Textfile Prometheus /var/lib/podheitor/adldap.prom
Mensagens do Bacula Director conforme configurado no recurso Messages do bacula-dir.conf

15.3 Habilitando logging de depuração

Adicione debug=9 à Plugin string para verbosidade máxima:

Plugin = "podheitor-adldap: mode=ldap ... debug=9"

Isso registra cada frame PTCOMM, cada solicitação/resposta LDAP (incluindo DN e código de resultado) e todas as transições de estado.


16. Casos de uso e cenários de implantação

16.1 AD empresarial — cobertura completa de DR

Cenário. Uma empresa de 2.000 funcionários opera Windows Server 2022 AD com dois controladores de domínio. Eles precisam de backups full noturnos incluindo GPOs, backups incrementais diários e runbooks de DR testados.

Solução.

  • Semanal: backup full mode=hybrid_sysvol — captura objetos do diretório + SYSVOL/GPO
  • Diário: backup incremental mode=ad — apenas delta DirSync (minutos, não horas)
  • Retenção: 30 dias no pool do Bacula
  • Teste de DR: mode=dry_run trimestral contra um domínio de laboratório para verificar o procedimento de restauração

Benefício operacional. A capacidade de restauração de GPO é um diferencial importante em relação ao AD Recycle Bin (que não inclui SYSVOL). Quando um GPO é acidentalmente excluído ou mal configurado, todo o conjunto de arquivos GPO pode ser restaurado do catálogo do Bacula sem reconstrução do zero.

16.2 Auditoria de conformidade de identidade em múltiplas florestas

Cenário. Uma instituição financeira precisa provar a auditores que atributos de contas de usuário e associações de grupos não foram alterados sem um chamado de mudança. Eles precisam de um relatório de diff automatizado diário.

Solução.

  • Job de backup diário com mode=ad
  • Após o backup, um job secundário de restauração é executado com mode=diff, produzindo um relatório JSON de todas as alterações desde o backup anterior
  • O relatório de diff é ingerido no SIEM para correlação com chamados de mudança
  • Qualquer entrada aparecendo em dels ou mods sem um chamado de mudança correspondente dispara um alerta de segurança

16.3 CDP OpenLDAP para diretório de contas de serviço

Cenário. Uma plataforma de microsserviços usa OpenLDAP para autenticação de contas de serviço. Qualquer perda de dados LDAP causa falha de autenticação simultânea em dezenas de serviços. O RPO deve ser inferior a 2 minutos.

Solução.

  • Modo: cdp com cdp_max_seconds=60 contra um cluster OpenLDAP de duas réplicas (ldapuri=ldap://ldap1,ldap://ldap2)
  • RPO CDP: ≤90 segundos de ponta a ponta
  • Failover mid-stream testado: se ldap1 falhar durante uma sessão de streaming, o plugin faz failover para ldap2 e continua sem interrupção do job

16.4 Migração de domínio FreeIPA para Samba AD

Cenário. Uma empresa está migrando de um domínio FreeIPA (backend 389-DS) para Samba AD DC. Eles precisam de uma migração controlada e auditada com a capacidade de rollback.

Solução.

  • Fase 1: Backup Full do FreeIPA via mode=ldap — snapshot canônico de todas as contas de usuário, grupos e políticas
  • Fase 2: mode=replicate com replicate_target_uri=ldap://samba-dc e o mapeamento de schema padrão — espelha ao vivo as alterações do FreeIPA no Samba AD durante a janela de migração
  • Fase 3: Após a migração, executar mode=diff para confirmar que o diretório Samba AD corresponde ao último snapshot do FreeIPA
  • Rollback: se a migração falhar, restaurar o diretório FreeIPA do backup Bacula da Fase 1 via mode=subtree

16.5 Recuperação autoritativa de floresta após ransomware

Cenário. Todos os controladores de domínio foram criptografados por ransomware. A empresa precisa reconstruir o diretório a partir do backup sem contaminação de replicação.

Solução.

  1. Provisionar um DC novo — isolado da rede, sem parceiros de replicação
  2. Executar mode=dry_run contra o DC novo para visualizar a restauração sem gravar nada
  3. Após revisar o ldif de prévia, executar mode=authoritative com i_understand=yes — restaura todos os objetos com USN elevado para que nenhum parceiro de replicação possa sobrescrever o estado restaurado
  4. Reconectar o DC à rede; verificar se a replicação DRS converge a partir do estado restaurado
  5. Executar mode=diff após 1 hora para confirmar que não houve replicação inesperada do estado criptografado

17. Comparação com outras abordagens

17.1 Diferenciais PodHeitor vs. plugin Bacula Enterprise LDAP/MSAD

Funcionalidade PodHeitor AD/LDAP Bacula Enterprise LDAP/MSAD
Backup SYSVOL / GPO Sim (hybrid_sysvol) Não — somente LDAP
Replicação ao vivo entre diretórios Sim (modo replicate) Não
CDP (proteção contínua de dados) Sim (cdp / cdp_dirsync) Não
Incremental verdadeiro via DirSync + RFC 4533 Sim (cookies USN / CSN) Full + diff apenas
Restauração em nível de atributo Sim (mode=attribute) Somente nível de objeto
Prévia de restauração dry-run Sim (mode=dry_run) Não
Restauração diff (relatório de alterações somente leitura) Sim (mode=diff) Não
Restauração autoritativa Sim (com gate) Parcial (somente MSAD)
Criptografia em repouso Sim (AES-256-GCM / ChaCha20) Somente nível de stream Bacula
Hardening Unicode brasileiro Sim (NFC/NFD, CI gate completo) Melhor esforço
RestoreObject cookie (sem arquivo de estado) Sim Arquivo em disco
Catalogação estável por objectGUID / objectSID Sim Somente estável por DN
Backup paralelo por OU Sim (parallel_branches=N) Single-threaded
cdylib puro em Rust (sem shim C/C++) Sim Shim C++
Métricas estruturadas Prometheus Sim Somente logs de texto
Failover multi-DC com cookie carry Sim (todos os modos) Limitado

17.2 Comparação mais ampla de plataformas

Funcionalidade Bacula Community + PodHeitor Bacula Enterprise Veeam Commvault
Backup nativo AD (DirSync) Sim Parcial Não (somente VM) Parcial (agente Windows)
Backup nativo OpenLDAP / 389-DS Sim Limitado Não Não
Backup SYSVOL / GPO Sim Não Não Não
CDP / RPO quase zero Sim Não Não Limitado
Replicação LDAP entre fornecedores Sim Não Não Não
Restauração em nível de atributo Sim Não Não Não
Restauração em nível de objeto Sim Parcial Requer add-on Sim (somente Windows AD)
Restauração autoritativa Sim Parcial Não Não
Criptografia em repouso (nível de plugin) Sim Nível de stream Sim Sim
Métricas Prometheus Sim Não Não Não
Plataforma base open-source Sim (Bacula CE) Não Não Não
Pacotes RPM + DEB Sim Sim Sim Sim
Sem agente (clientless, sem agente no DC) Sim Parcial Não Não

17.3 Comparação de custos

Oferta especial. Traga sua proposta de renovação do Veeam, Commvault, NetBackup ou qualquer outra plataforma de backup empresarial. Produziremos uma proposta comparativa formal visando pelo menos 50% de economia, com funcionalidades AD/LDAP superiores. Entre em contato pelo heitor@opentechs.lat.

Solução Custo anual típico Suporte a AD / LDAP
Bacula Community + plugin PodHeitor Significativamente menor Nativo completo (este plugin)
Bacula Enterprise Frequentemente > US$ 10.000/ano Parcial (LDAP/MSAD, sem SYSVOL)
Veeam Data Platform Frequentemente > US$ 5.000/ano Somente nível de VM (sem restauração de objetos sem add-on)
Commvault Frequentemente > US$ 15.000/ano Somente Windows AD (agente obrigatório)
NetBackup Frequentemente > US$ 20.000/ano Limitado (sem LDAP nativo)

Os preços variam conforme o tamanho do ambiente e contratos negociados. Entre em contato pelo heitor@opentechs.lat para uma comparação específica com sua proposta de renovação atual.


18. Roadmap

O plugin é lançado na v0.1.0 com o conjunto completo de funcionalidades MVP em todos os 5 modos de backup e 6 modos de restauração, validados por 800+ testes. As direções de desenvolvimento planejadas incluem:

  • Fase 9 — empacotamento e documentação. Pacotes DEB e RPM assinados e publicados no repositório PodHeitor. Guia do Operador completo, DR Runbook e Guia de Resolução de Problemas.
  • Agente AD nativo para Windows. Uma compilação do plugin para Windows carregando em um bacula-fd nativo Windows possibilitaria acesso direto ao NTDS.dit local via VSS — eliminando a necessidade de um host Linux separado com bacula-fd para backup AD. Atualmente fora do escopo da v0.1.0.
  • Suporte a múltiplas arquiteturas. Pacotes ARM64 / aarch64 para ambientes cloud-native e Raspberry Pi.
  • Painel de administração Bacularis. UI de configuração do plugin na interface web Bacularis para entrada de parâmetros sem editar a configuração bruta de FileSet. Confirmado fora do escopo da v0.1.0.
  • Suporte explícito a ApacheDS / OpenDJ. Atualmente melhor esforço via modo genérico ldap; certificação completa planejada para uma versão menor futura.
  • Azure AD DS / AWS Managed Microsoft AD. Serviços AD gerenciados na nuvem têm endpoints LDAP e suportam parcialmente DirSync — certificação explícita e documentação de soluções alternativas planejadas.
  • Alertas Prometheus estendidos. Regras de alerta pré-construídas para obsolescência de cookie, drift de schema e lag de replicação.

Nenhuma data de lançamento específica está comprometida. A direção das funcionalidades é guiada pelo feedback de clientes e descobertas do laboratório.


19. Informações de contato

Autor Heitor Faria
Website https://podheitor.com
E-mail heitor@opentechs.lat
Telefone / WhatsApp +1 786 726-1749
Telefone / WhatsApp (BR) +55 61 98268-4220
Página do produto https://podheitor.com/active-directory-ldap-plugin
Suporte heitor@opentechs.lat

20. Legal / direitos autorais

© 2026 Heitor Faria — todos os direitos reservados.

O PodHeitor Active Directory / LDAP Backup Plugin for Bacula é um software proprietário. Cópia, distribuição, modificação ou engenharia reversa não autorizadas são estritamente proibidas. Uma licença comercial é necessária para uso em produção.

Bacula® é marca registrada de Kern Sibbald e da comunidade Bacula. Microsoft Active Directory® é marca registrada da Microsoft Corporation. Todas as outras marcas comerciais — incluindo OpenLDAP, 389-DS, FreeIPA, Samba, Kerberos, HashiCorp Vault, Veeam, Commvault e NetBackup — são propriedade de seus respectivos titulares.

Este documento é fornecido para fins informativos. Os números de desempenho são metas de medições controladas em laboratório e podem variar em ambientes de produção dependendo do hardware, condições de rede, configuração do servidor de diretório e tamanho do diretório.

Contato para licenciamento: 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 os direitos reservados — https://podheitor.com

Disponível em: pt-brPortuguêsenEnglish (Inglês)esEspañol (Espanhol)

Deixe um comentário