Table des matières

Annuaire de connexion

Présentation d'installation d'une architecture OpenLDAP sur debian 10.

Packages

Installation des outils:

apt-get purge -y slapd ldap-utils
DEBIAN_FRONTEND=noninteractive apt-get install -yqq slapd ldap-utils

Configuration de base

Dans la suite de la configuration, nous utiliserons le répertoire /opt/ldap pour sauver des fichiers de configuration.

Réglage OpenLDAP

Créer et modifier le fichier /var/lib/ldap/DB_CONFIG comme suit:

service slapd stop
cd /var/lib/ldap
rm -rf *
echo "#DB_CONFIG" > DB_CONFIG
echo "set_cachesize           0 150000000 1" >> DB_CONFIG
echo "set_lg_regionmax        262144" >> DB_CONFIG
echo "set_lg_bsize            2097152" >> DB_CONFIG
echo "set_flags               DB_LOG_AUTOREMOVE" >> DB_CONFIG
service slapd start

Initialisation

Définir l'identifiant racine et le mot de passe du compte “root”

rootpass=$(slappasswd -s ROOT_PASSWORD_SECRET | base64)
echo "dn: olcDatabase={1}mdb,cn=config
changeType: modify
replace: olcSuffix
olcSuffix: dc=sleto,dc=net
-
replace: olcRootDN
olcRootDN: cn=root,dc=sleto,dc=net
-
replace: olcRootPW
olcRootPW: $rootpass" >  /opt/ldap/initial.ldif
ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/ldap/initial.ldif

Desactivation anonyme

Script pour désactiver l'accès en annonymous.

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: cn=config
changetype: modify
add: olcDisallows
olcDisallows: bind_anon

dn: cn=config
changetype: modify
add: olcRequires
olcRequires: authc

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
olcRequires: authc    
EOF

Ajout d'overlay

Les overlay sont des sortes d'extension ou plugin pour étendre des fonctionnalités dans OpenLDAP.

Ajout pour utiliser correctement la fonction MemberOf

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: memberof.la
EOF

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof.la
olcModulePath: /usr/lib/ldap
EOF

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: refint.la
EOF
    
ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: olcConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
EOF

Configuration avancée

D'autres réglages interessant dans la logique d'une mise en production.

SLL

Afin que la communication deviens chiffré.

Copier les clefs

cp /opt/tools/conf/ldap_server.key /etc/ldap/sasl2/ldap_server.key
cp /opt/tools/conf/ldap_server.crt /etc/ldap/sasl2/ldap_server.crt
cp /opt/tools/conf/ldap_ca-certificates.crt /etc/ldap/sasl2/ca-certificates.crt
chown -R openldap. /etc/ldap/sasl2

Voir l'article Configure OpenLDAP over TLS with Self Signed Certificate pour savoir comment créer ces clefs.

Et activer le SSL ainsi:

ldapmodify -Y EXTERNAL -H ldapi:/// << EOF    
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/sasl2/ca-certificates.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/sasl2/ldap_server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/sasl2/ldap_server.key    
EOF

Gestion d'accès

Pour gérer plus de sécurité, les modifications de l'annuaire seront fait par un utiliseur spécifique afin de ne pas utiliser root.
J'utiliserais alors un autre utilisateur dc=writer,dc=sleto,dc=net.
Cet utilisateur ne pourra que créer des comptes dans le dossier ou=users,dc=sleto,dc=net et que modifier l'attribut member de groupes de type groupOfNames.

Pour cela, on commence par supprimer les accès par défaut (il y en a normalement 3):

ldapmodify -Y EXTERNAL -H ldapi:/// << EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}
olcAccess: {1}
olcAccess: {2}
EOF

Et ensuite, on ajoute les 5 droits suivants:

ldapmodify -Y EXTERNAL -H ldapi:/// << EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword 
  by self write by anonymous auth 
  by * none
-
add: olcAccess
olcAccess: {1}to attrs=shadowLastChange
  by self write
  by * read
-
add: olcAccess
olcAccess: {2}to attrs=member
  by dn="dc=writer,dc=sleto,dc=net" write
  by * read
-
add: olcAccess
olcAccess: {3}to dn.subtree="ou=users,dc=sleto,dc=net"
  by dn="cn=dc=writer,dc=sleto,dc=net" write
  by * read
-
add: olcAccess
olcAccess: {4}to * by * read
EOF

On notera que les olcAccess {0},{1} et {4} était les droits par défaut que l'on viens de supprimer.
Il est important de les remettre dans cette ordre: en effet, si le dernier droit était en 3ème position, il empecherait d'activer les suivants.

Réplication

Utiliser une authentification centralisée pourrait fragiliser l'architecture d'hébergement.
En effet, cela peux devenir le maillon faible : si le serveur OpenLDAP tombe, plus aucune authentification n'est possible, même sur d'autres serveurs encore fonctionnels.

Pour palier cela, il est possible de configurer plusieurs serveurs OpenLDAP en réplication mutuel : à chaque modification de l'un d'eux, les autres sont automatiquement mis à jour.

Séquence réalisée d'après l'article Configure multi-master replication OpenLDAP

Cette configuration est a effectué sur chaque serveur OpenLDAP.
Dans l'exercice, nous allons supposer d'avoir 3 serveur: ldap1.sleto.net, ldap2.sleto.net, ldap3.sleto.net

Pour commencer, ajouter l'overlap nécessaire:

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/ldap
olcModuleLoad: syncprov.la
EOF

ldapadd -Y EXTERNAL -H ldapi:/// << EOF
dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpSessionLog: 100
EOF

Pour le serveur ldap1.sleto.net ajoutons la configuration suivante:

dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 001

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=2
  provider=ldap://ldap2.sleto.net/
  bindmethod=simple
  binddn="cn=root,dc=sleto,dc=net"
  credentials=<ROOT_PASSWORD>
  searchbase="dc=sleto,dc=net"
  scope=sub
  schemachecking=on
  type=refreshAndPersist
  retry="30 5 300 3"
  interval=00:00:05:00
olcSyncRepl: rid=3
  provider=ldap://ldap3.sleto.net/
  bindmethod=simple
  binddn="cn=root,dc=sleto,dc=net"
  credentials=<ROOT_PASSWORD>
  searchbase="dc=sleto,dc=net"
  scope=sub
  schemachecking=on
  type=refreshAndPersist
  retry="30 5 300 3"
  interval=00:00:05:00
-
add: olcMirrorMode
olcMirrorMode: TRUE

dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov

Pour les serveurs ldap2.sleto.net et ldap3.sleto.net, changer la valeur de olcServerID et permutter les champs provider pour que chacun voyent les 2 autres.

Insertion de données

Pour finir la configuration, il suffit d'injecter les données de configurations permettant d'initier l'annuaire. Noter: avec la replication, cette insertion n'est à faire que sur un seul des serveurs.

Voilà un exemple d'insertion initial.
Le but ici est d'avoir 2 dossiers (groups et users) et 3 utilisateurs (root, reader, writer).
Les variables $passwd, $readerpasswd et $writerpasswd comprennent respectivement les mots de passe des 3 utilisateurs.

echo "dn:              dc=sleto,dc=net
description:           LDAP Sleto
dc:                    sleto
o:                     Sleto
objectClass:           top
objectClass:           dcObject
objectClass:           organization
structuralObjectClass: organization

# administrator
dn:                    cn=root,dc=sleto,dc=net
objectClass:           simpleSecurityObject
objectClass:           organizationalRole
cn:                    admin
description:           LDAP administrator
userPassword:          $(slappasswd -s $passwd)
structuralObjectClass: organizationalRole

# reader
dn:                    cn=reader,dc=sleto,dc=net
objectClass:           simpleSecurityObject
objectClass:           organizationalRole
cn:                    reader
description:           LDAP reader
userPassword:          $(slappasswd -s $readerpasswd)
structuralObjectClass: organizationalRole

# modifier
dn:                    cn=writer,dc=sleto,dc=net
objectClass:           simpleSecurityObject
objectClass:           organizationalRole
cn:                    modifier
description:           LDAP modifier
userPassword:          $(slappasswd -s $writerpasswd)
structuralObjectClass: organizationalRole

# groups
dn: ou=groups,dc=sleto,dc=net
objectclass: organizationalUnit
objectclass: top
ou: groups

# users
dn: ou=users,dc=sleto,dc=net
objectclass: organizationalUnit
objectclass: top
ou: users" > /opt/ldap/new_ldap.ldif

slapadd -b "$rootdirectory" -v -l /opt/ldap/new_ldap.ldif