Instalação OpenLDAP multi-master no Oracle Linux 7

O cenário de testes é são duas maquinas virtuais usando Oracle Linux 7.7 (atualizadas em 02/02/2020), mas como a origem da distribuição é a mesma, se aplica ao CentOS e ao Red Hat

Nome IP OS
ol77-ldap1.prego.eti.br 192.168.0.53 Oracle Linux 7.7
ol77-ldap2.prego.eti.br 192.168.0.54 Oracle Linux 7.7

Inclua os nomes nos dois servidores, se você estiver usando um usuário com poderes de sudo:

$ sudo su -c "echo '192.168.0.53 ol77-ldap1.prego.eti.br' >> /etc/hosts"
$ sudo su -c "echo '192.168.0.54 ol77-ldap2.prego.eti.br' >> /etc/hosts"

Caso esteja como root, é só executar o echo direto, trocando os IPs e nomes conforme a sua configuração

 $ sudo yum install -y openldap-servers openldap-clients

Gere uma senha com o slappasswd (hash Salted SHA-512):

$ slappasswd -h "{SSHA512}" -o module-load=pw-sha2.la -o module-path=/usr/lib64/openldap/
New password:
Re-enter new password:
{SSHA512}BHSt64+Rd+Ujy3yYhFVxI/1ESYXM/hRppd3BjSpGk+hlZmTrQx7NCn+S0MV0zK9+nshkhSXg/0FHy7kTKJBKFVqvTulSIjB/

O pacote de instalação do LDAP do Oracle Linux 7 vem por padrão com um ldif para gerar uma base em hdb, a recomendação dos desenvolvedores do OpenLDAP é usar MDB, vamos alterar isso antes de iniciar o serviço, pois uma vez criado o banco não pode ter seu tipo alterado:

$ sudo mv /etc/openldap/slapd.d/cn\=config/olcDatabase={2}hdb.ldif /etc/openldap/slapd.d/cn\=config/olcDatabase={2}mdb.ldif

Vamos aproveitar e já alterar o dominio e incluir a senha do usuário Admin ou Master (padrão):

dn: olcDatabase={2}hdb <== altere para mdb
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig <== altere para Mdb
olcDatabase: {2}hdb <== altere para mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=prego,dc=eti,dc=br <== altere para o seu dominio
olcRootDN: cn=Admin,dc=prego,dc=eti,dc=br <== altere para o seu dominio e nome de usuario de preferência
olcRootPW: {SSHA512}BHSt64+Rd+Ujy3yYhFVxI/1ESYXM/hRppd3BjSpGk+hlZmTrQx7NCn+S0MV0zK9+nshkhSXg/0FHy7kTKJBKFVqvTulSIjB/  <== Inclua essa linha com a senha gerada no passo anterior
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
olcDbMaxSize: 31457280 <== Inclua essa linha com o tamanho do arquivo (30MB armazenam até 10000 entradas)
structuralObjectClass: olcHdbConfig <== altere para Mdb
entryUUID: de245f08-db80-1039-90a1-51312546408f
creatorsName: cn=config
createTimestamp: 20200204100007Z
entryCSN: 20200204100007.672968Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20200204100007Z

O serviço do servidor LDAP no Oracle linux chama slapd, para ativar o serviço e fazer com que ele seja iniciado automáticamente no reboot, utilize:

$ sudo systemctl start slapd
$ sudo systemctl enable slapd

Crie um arquivo incluisenharoot.ldif (o mesmo nos dois servidores) com o conteúdo abaixo:

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW:{SSHA512}BHSt64+Rd+Ujy3yYhFVxI/1ESYXM/hRppd3BjSpGk+hlZmTrQx7NCn+S0MV0zK9+nshkhSXg/0FHy7kTKJBKFVqvTulSIjB/

Obs.: Em caso de precisar reiniciar a senha root, altere o "add:" por "replace:" na terceira linha acima

$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f incluisenharoot.ldif

Após definir a senha root o próximo passo é a carga de definições de dados do LDAP, os schemas:

Schema Uso Depende de
core definições iniciais (sn, cn, etc) Nenhum schema (Já esta no LDAP)
cosine Atributos gerais (documentos, pessoas, etc.) core.schema 
nis Informações sobre usuários e grupos posix (UNIX/Linux) cosine.schema
inetorgperson Informações de nome preferido, foto e lingua da pessoa cosine.schema
sudo Regras de sudo centralizadas  
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

Em 3 de fevereiro de 2020 a versão do sudo era a 1.8.23:

$ sudo cp /usr/share/doc/sudo-1.8.23/schema.OpenLDAP /etc/openldap/schema/sudo.schema
$ cat > ./conv_sudo.conf << EOL
include /etc/openldap/schema/sudo.schema
EOL
$ mkdir ldif
$ slaptest -f conv_sudo.conf -F ldif/
$ sudo cp ldif/cn\=config/cn\=schema/cn\=\{0\}sudo.ldif /etc/openldap/schema/sudo.ldif

No arquivo sudo.ldif altere as linhas abaixo:

dn: cn={0}sudo

para

dn: cn=sudo,cn=schema,cn=config

e

cn: {0}sudo

para:

cn: sudo

e remova as linhas abaixo do fim do arquivo:

structuralObjectClass: olcSchemaConfig
entryUUID: 77f4eaf8-db36-1039-9215-0d960f602724
creatorsName: cn=config
createTimestamp: 20200204010733Z
entryCSN: 20200204010733.345744Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20200204010733Z

O arquivo deve ficar assim:

dn:  cn=sudo,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: sudo
olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s
 ) who may  run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5Substrin
 gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s
 ) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5Substring
 sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Com
 mand(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4
 .1.1466.115.121.1.26 )
olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(
 s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3
 .6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Opti
 ons(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466
 .115.121.1.26 )
olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'U
 ser(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.
 1466.115.121.1.26 )
olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC '
 Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.
 1.1466.115.121.1.26 )
olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'S
 tart of time interval for which the entry is valid' EQUALITY generalizedTim
 eMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.12
 1.1.24 )
olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'En
 d of time interval for which the entry is valid' EQUALITY generalizedTimeMa
 tch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1
 .24 )
olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an i
 nteger to order the sudoRole entries' EQUALITY integerMatch ORDERING intege
 rOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer
 Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand
  $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ su
 doNotBefore $ sudoNotAfter $ description ) )

Finalize incluindo-o no LDAP:

$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/sudo.ldif

Veja abaixo um ldif para criar a base do domínio prego.eti.br, troque de acordo com seu sistema/ambiente.
Ainda no ldif abaixo, note que o tipo de base usada é o mdb (recomendação dos desenvolvedores do OpenLDAP) e o tamanho 31457280 (30MB) e é equivalente a 10000 entradas. O tamanho da base MDB não pode ser aumentada após a criação, dimensione de acordo com o esperado, acompanhe regulamermente o crescimento e reconstrua a base se necessário.

dn: olcDatabase=mdb,cn=config
changetype: add
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=prego,dc=eti,dc=br
olcRootDN: cn=admin,dc=prego,dc=eti,dc=br
olcRootPW: {SSHA512}BHSt64+Rd+Ujy3yYhFVxI/1ESYXM/hRppd3BjSpGk+hlZmTrQx7NCn+S0MV0zK9+nshkhSXg/0FHy7kTKJBKFVqvTulSIjB/
olcDbDirectory:	/var/lib/ldap
olcDbIndex: objectClass,uid,uidNumber,gidNumber eq
olcDbMaxSize: 31457280
olcAccess: to attrs=userPassword
  by self write
  by anonymous auth
  by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
olcAccess: to attrs=shadowLastChange by self write
  by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by dn.subtree="ou=sistema,dc=prego,dc=eti,dc=br" read
  by * none
olcAccess: to dn.subtree="ou=sistema,dc=prego,dc=eti,dc=br" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
olcAccess: to dn.subtree="dc=prego,dc=eti,dc=br" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by users read 
  by * none
 

Adicione o domínio:

$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f prego.eti.br.ldif

Para a sincronia entre os servidores funcionar bem, o horário é primordial, ative o serviço de atualização de horário dos servidores:

 $ sudo systemctl start ntpdate
 $ sudo systemctl enable ntpdate

Para conferir se o serviço esta ativo e atualizando, use:

$ sudo systemctl -l status ntpdate
ntpdate.service - Set time via NTP Loaded: loaded (/usr/lib/systemd/system/ntpdate.service; enabled; vendor preset: disabled) Active: active (exited) since Seg 2020-02-03 18:21:44 -03; 3min 12s ago Main PID: 6107 (code=exited, status=0/SUCCESS) Fev 03 16:34:24 ol77-ldap2.prego.eti.br systemd[1]: Starting Set time via NTP... Fev 03 18:21:44 ol77-ldap2.prego.eti.br systemd[1]: Started Set time via NTP.