22
0
Fork 0
wiki/HowtoOpenLDAP.md

457 lines
14 KiB
Markdown
Raw Normal View History

2017-10-04 00:56:47 +02:00
**Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été complètement révisée.**
2016-12-29 11:25:39 +01:00
# Howto OpenLDAP
2017-10-04 00:56:47 +02:00
* Documentation : <http://www.openldap.org/doc/admin24/>
* Rôle Ansible
2016-12-29 11:25:39 +01:00
2017-10-04 00:56:47 +02:00
[OpenLDAP](http://www.openldap.org) est une implémentation libre du protocole LDAP développée par The OpenLDAP Project.
2016-12-29 11:25:39 +01:00
2017-10-04 00:56:47 +02:00
## Installation
2016-12-29 11:25:39 +01:00
~~~
2017-10-04 00:55:17 +02:00
# apt install slapd ldap-utils ldapvi shelldap
2016-12-29 11:25:39 +01:00
2017-10-04 00:55:17 +02:00
$ /usr/sbin/slapd -VV
@(#) $OpenLDAP: slapd (May 28 2017 16:59:46) $
Debian OpenLDAP Maintainers <pkg-openldap-devel@lists.alioth.debian.org>
2016-12-29 11:25:39 +01:00
2017-10-04 00:55:17 +02:00
# systemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
Loaded: loaded (/etc/init.d/slapd; generated; vendor preset: enabled)
Docs: man:systemd-sysv-generator(8)
Tasks: 3 (limit: 4915)
CGroup: /system.slice/slapd.service
└─23686 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
2016-12-29 11:25:39 +01:00
~~~
## Configuration
2017-10-04 00:55:17 +02:00
Depuis Debian 6, OpenLDAP stocke directement sa configuration et de son schéma dans l'arborescence *cn=config*.
Notez que si vous êtes fainéant, il est toujours possible d'utiliser un bon vieux `slapd.conf`.
2016-12-29 11:25:39 +01:00
2017-10-04 00:55:17 +02:00
Le contenu de cette arborescence est aussi stocké sous forme de fichiers, dans le répertoire `/etc/ldap/slapd.d/` et ceux-ci sont chargés au démarrage de OpenLDAP.
2016-12-29 11:25:39 +01:00
Selon vos goûts, différentes commandes pour visualiser la configuration :
~~~
# slapcat -b cn=config
$ ldapsearch -xLLL -b cn=config -x -D cn=admin,cn=config -W
# ldapvi -Y EXTERNAL -h ldapi:// -b cn=config
~~~
2017-10-04 00:55:17 +02:00
Note : cette dernière commande peut nécessiter que l'ACL (`olcAccess`) suivante soit positionnée sur l'entrée _olcDatabase={0}config,cn=config_ :
2016-12-29 11:25:39 +01:00
~~~
olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
olcRootDN: cn=admin,cn=config
~~~
### Modifier la configuration
2017-10-04 00:55:17 +02:00
On pourra donc modifier la configuration à chaud via `ldapvi` ou tout simplement `ldapmodify` et de superbes fichiers LDIF.
2016-12-29 11:25:39 +01:00
2017-10-04 00:55:17 +02:00
À savoir : lorsqu'on modifie à chaud la configuration, OpenLDAP met alors immédiatement à jour le contenu du fichier correspondant dans `/etc/ldap/slapd.d/` !
2016-12-29 11:25:39 +01:00
2017-10-04 00:55:17 +02:00
Une autre possibilité est de stopper **slapd**, de modifier les fichiers LDIF dans _/etc/ldap/slapd.d/_ et de le redémarrer.
Attention, cela risque de générer des warnings à propos de checksums sur les fichiers. Pour contourner cela, il faut ré-éditer les entrées à chaud pour que les dumps soient regénérés avec les bons checksums...
2016-12-29 11:25:39 +01:00
Autre détail important, avant la version 2.5 il n'est pas possible de faire un delete à chaud sur une entrée de _cn=config_ !
Il faut donc utiliser la méthode nécessitant l'arrêt de _slapd_, faire les modifications sur les fichiers LDIF et le relancer.
### Directives
Pour gérer les logs, on utilise la directive _olcLogLevel_ dans l'entrée _cn=config_.
Exemple pour désactiver les logs :
~~~
cn=config
olcLogLevel: 0
~~~
### Gestion des schémas
Autrefois, il suffisait d'un simple _include_ vers un fichier .schema pour ajouter un schéma.
Mais avec la configuration dans _cn=config_, il faut désormais convertir un schéma en LDIF puis l'injecter !
Voici les étapes pour convertir un .schema en .ldif (exemple avec _amavis.schema_) :
1. Créer un fichier _/tmp/convert-to-ldap.conf_ contenant une seule ligne :
~~~
include /etc/ldap/schema/amavis.schema
~~~
2. On lance la commande suivante :
~~~
# mkdir /tmp/convert
# slaptest -f /tmp/convert-to-ldap.conf -F /tmp/convert
config file testing succeeded
~~~
3. On obtient donc un fichier LDIF : _/tmp/convert/cn\=config/cn\=schema/cn\=\{0\}amavis.ldif_
Pour l'injecter, il faut le modifier :
* ajouter le base DN en fin de 1ère ligne : cn=schema,cn=config
* supprimer les dernières lignes du fichier spécifiques à LDAP : structuralObjectClass, entryUUID, creatorsName, etc.
* renumérotation du _cn={0}_ (dn: et cn:) en fonction des schémas déjà existants
On peut ainsi faire :
~~~
# ldapadd -Y EXTERNAL -H ldapi:/// -f /tmp/convert/cn\=config/cn\=schema/cn\=\{0\}amavis.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn={4}amavis,cn=schema,cn=config"
~~~
Note : Si besoin, on peut bien sûr convertir plusieurs schémas d'un coup via un fichier _/tmp/convert-to-ldap.conf_ du type :
~~~
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/collective.schema
[...]
include /etc/ldap/schema/monschema2.schema
~~~
### Gestion des ACL
Les ACL s'ajoutent via des règles du type :
~~~
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by self write by dn="cn=admin,dc=example,dc=com" write by peername.ip="127.0.0.1" read by * none
~~~
/!\ en cas de réplication, bien penser à inclure l'utilisateur de réplication pour les attrs=userPassword,shadowLastChange sous peine
de ne pas avoir de synchronisation des mots de passe !!!
Pour ne pas avoir un annuaire lisible publiquement mais accessible depuis l'extérieur, on peut forcer l'authentification en remplaçant "by peername.ip="127.0.0.1" read" par :
~~~
by users read by anonymous auth
~~~
### Réplication (master->slave)
*Sur le master :*
* Ajouter le module syncprov (dans l'objet cn=module{0},cn=config) :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
olcModuleLoad: {1}syncprov
~~~
* Ajouter l'objet suivant :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
dn: olcOverlay={0}syncprov,olcDatabase={1}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: {0}syncprov
structuralObjectClass: olcOverlayConfig
entryUUID: b5786b24-6688-1030-8824-91503a3ebf6f
creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
createTimestamp: 20110829124650Z
entryCSN: 20110829124650.326464Z#000000#000#000000
modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
modifyTimestamp: 20110829124650Z
olcSpSessionlog: 100
olcSpCheckpoint: 100 10
~~~
* Créer l' _ou_ ldapuser et l'utilisateur _repl_, et lui donner les droits de lecture sur l'ensemble de l'arbre LDAP
*Sur le slave :*
* S'assurer que le schéma LDAP soit le même que sur le master
* Ajouter le module syncprov (dans l'objet cn=module{0},cn=config) :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
olcModuleLoad: {1}syncprov
~~~
* Ajouter les attributs suivants à l'objet "dn: olcDatabase={1}hdb,cn=config" :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
olcDbIndex: entryUUID eq
olcSyncrepl: {0}rid=124 provider=ldap://ldap.example.com bindmethod=simple binddn="cn=repl,ou=ldapuser,dc=example,dc=com" credentials=XXX searchbase="dc=example,dc=com" retry="60 +" type=refreshAndPersist
~~~
### Gestion des index LDAP
On configure des index ainsi :
~~~
olcDbIndex: objectClass eq
olcDbIndex: default eq
olcDbIndex: phpgwContactOwner pres,eq,sub
olcDbIndex: uidNumber,gidNumber pres,eq
olcDbIndex: uid,mail eq,approx
~~~
Attention, si l'on modifie les index, il faut absolument les regénérer avec la commande suivante :
~~~
# /etc/init.d/slapd stop
# sudo -u openldap slapindex
# /etc/init.d/slapd start
~~~
### Activer SSL (LDAPS)
Rajouter dans _cn=config_ :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
olcTLSCertificateFile: /etc/ssl/certs/ssl-cert-snakeoil.pem
olcTLSCertificateKeyFile: /etc/ssl/private/ssl-cert-snakeoil.key
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
~~~
Et dans */etc/default/slapd* par exemple :
~~~
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldapi:/// ldaps:///"
~~~
Suite à cette mise en place, si en tentant de se connecter au serveur apparaît l'erreur `ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)`, il se peut que ça soit dû au certificat non reconnu. Pour désactiver la vérification du certificat, sur le client, ajouter cette ligne dans _/etc/ldap/ldap.conf_ :
~~~
TLS_REQCERT never
~~~
## Utilisation
### ldapvi
_ldapvi_ permet d'éditer un annuaire LDAP avec Vim.
Pour ajouter une entrée, on fera donc :
~~~
$ cat add.ldif
dn: ou=test,dc=example,dc=com
ou: test
objectClass:
2017-06-12 18:46:09 +02:00
$ ldapadd [-h <hostname>] -D uid=xxx,ou=xxx,dc=evolix,dc=net -f add.ldif -W
2016-12-29 11:25:39 +01:00
add: 1, rename: 0, modify: 0, delete: 0
Action? [yYqQvVebB*rsf+?] y
Done.
~~~
### .ldaprc
Le fichier _~/.ldaprc_ est utilisé pour les outils inclus dans `ldap-utils` il permet de définir des paramètres particulier.
On peut notamment autoriser les certifications non reconnus :
~~~
tls_reqcert never
~~~
## Backup
Rien de plus simple :
~~~
slapcat -l ldap.bak
~~~
Cela dump l'arbre ldap dans un seul fichier LDIF. Cette sauvegarde n'inclut *pas* cn=config.
Pour sauvegarder la configuration (ACLs, Schema...etc) :
~~~
slapcat -b cn=config -l config.ldif
~~~
## Restauration
~~~
/etc/init.d/slapd stop
rm -rf /var/lib/ldap/*
sudo -u openldap slapadd -l ldap.bak
/etc/init.d/slapd start
~~~
## Infos sur les attributs LDAP
### Attributs pour authentification Windows
*sambaPwdMustChange*: Timestamp Unix, date d'expiration du mot de passe Windows.
*sambaKickoffTime*: Timestamp Unix, date d'expiration du compte Windows.
*sambaPwdLastSet*: Timestamp Unix, dernière fois que le mot de passe a été changé. (Bizarrerie à ce propos...)
### Attributs pour authentification UNIX
'''
shadowExpire''': Durée en nombre de jours depuis le 1° Janvier 1970. Date d'expiration du compte.
*shadowInactive*: Combien de jours il faut accepter un mot de passe qui a expiré.
*shadowWarning*: Nombre de jours avant que le mot de passe expire et où le système va avertir de la proche expiration.
*shadowFlag*: -1 ???
*shadowLastChange*: Durée en nombre de jours depuis le 1° Janvier 1970 de la dernière fois que le mot de passe a été modifié (Ex: 15579 = 27/08/2012).
*shadowMin*: Age minimum en jours avant que l'utilisateur puisse changer son mot de passe. (Défaut à 0 = quand il veut).
*shadowMax*: Durée en jours de la validité du mot de passe. (Ex 365 = 1 an). Pour désactiver l'expiration du mot de passe, affecter la valeur -1.
## FAQ
2019-07-17 11:57:54 +02:00
### Changer un mot de passe LDAP
Lors de l'exécution de la commande, un mot de passe sera demandé :
~~~
slappasswd
~~~
2017-03-01 10:32:30 +01:00
### Logiciels pour gestion de l'annuaire
#### Windows
Client lourd : [http://www.ldapadmin.org/](http://www.ldapadmin.org/)
2017-03-01 10:43:19 +01:00
![Configurer la connexion au LDAP distant. Si pas de TLS activé, utiliser un tunnel SSH](/ldap_admin1.png)
![Rendu complet de l'annuaire](/ldap_admin2.png)
2017-03-01 10:32:30 +01:00
2016-12-29 11:25:39 +01:00
### could not parse entry
Lors d'ajout/modification d'un annuaire LDAP, si vous obtenez un message de ce type :
~~~
str2entry: invalid value for attributeType objectClass #0 (syntax 1.3.6.1.4.1.1466.115.121.1.38)
slapadd: could not parse entry (line=70)
structuralObjectClass: organizationalRole
~~~
C'est sûrement dû au fait que vos schémas spécifiques ne sont pas pris en compte car _slapd_
utilise la configuration présente dans _/etc/ldap/slapd.d_ si le dossier est présent.
### Insufficient access
~~~
Uncaught exception from user code:
Insufficient access at ./add.pl line 678, <STDIN> line 2.
~~~
Vérifier dans les acl que votre utilisateur a le droit de modifier l'attribut que vous modifier.
2017-03-14 12:16:59 +01:00
### ldapvi ouvre avec nano
Pour changer léditeur lors ouverture ldapvi :
~~~{ .bash }
EDITOR=vim ldapvi
2017-10-04 00:55:17 +02:00
~~~
### Too many open files
En wheezy bug rencontré :
~~~
slapd[15245]: warning: cannot open /etc/hosts.deny: Too many open files
~~~
Pour l'éviter ajouter dans /etc/default/slapd :
~~~
ulimit -n 8192
~~~
2018-01-28 17:29:42 +01:00
### TLS init def ctx failed: -1
Si vous obtenez un message du type :
~~~
slapd: main: TLS init def ctx failed: -1
~~~
Vérifiez que l'utilisation _openldap_ a bien accès aux clés privés et certificats définis dans sa configuration (vous pouvez utiliser `sudo -u openldap /bin/bash` pour vous en assurer).
### ldif_read_file: checksum error
Le répertoire `/etc/ldap/slapd.d/cn=config/` à du être modifié (à ne pas faire lorsque **slapd** tourne), il vous faudra regenérer le checksum manuellement.
On récupère le checksum actuel :
2018-01-28 17:29:42 +01:00
~~~
# apt install libarchive-zip-perl
# crc32 <(cat /etc/ldap/slapd.d/cn=config.ldif | tail -n +3)
2018-01-28 17:29:42 +01:00
42cd80b1
~~~
2018-01-28 17:29:42 +01:00
On le modifie exceptionnellement à la place de l'ancien :
2018-01-28 17:29:42 +01:00
~~~
vim /etc/ldap/slapd.d/cn=config.ldif
~~~
2018-01-28 17:29:42 +01:00
Ce qui donnera ce résultat :
~~~
# head -2 /etc/ldap/slapd.d/cn=config.ldif
2018-01-28 17:29:42 +01:00
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 42cd80b1
~~~
2018-03-23 16:42:06 +01:00
### Size limit exceeded
2018-04-02 17:47:15 +02:00
La limite par défaut lors d'un ldapseach est de 500. On peut l'augmenter en modifiant l'attribut olcSizeLimit, avec par exemple `ldapvi -Y EXTERNAL -h ldapi:// -b cn=config`.
### no equality matching rule
En cas d'erreur du type :
~~~
ldap_modify: Inappropriate matching (18)
additional info: modify/delete: foo_attribute: no equality matching rule
~~~
2018-09-12 18:29:41 +02:00
Vérifiez que l'attribut concerné a bien une règle EQUALITY dans le schéma LDAP.
2018-04-02 17:47:15 +02:00
2018-09-12 18:29:41 +02:00
Si ce n'est pas possible d'ajouter une règle EQUALITY dansle schéma LDAP (par exemple pour les SYNTAX binary comme jpegPhoto), n'utilisez pas ldapmodify (LDAP_MOD_REPLACE) mais plutôt suppression (et recréation si besoin) :
2018-04-02 17:47:15 +02:00
2018-09-12 18:29:41 +02:00
~~~
$ cat delete.ldif
dn: cn=foo,dc=example,dc=com
changetype: modify
delete: jpegPhoto
$ ldapvi --ldapmodify delete.ldif
~~~
2018-04-02 17:47:15 +02:00
### no such value
En cas d'erreur du type :
~~~
> ldap_modify: No such attribute (16)
> additional info: modify/delete: foo_attribute: no such value
~~~
Vérifier que votre attribut n'a pas des caractères spéciaux (saut de ligne, etc.), vous pouvez notamment d'abord remplacer votre ligne avec une valeur "test" pour voir si cela fonctionne.
### TLS error
Les erreurs SSL/TLS ne sont pas très explicites avec OpenLDAP, si vous en avez une, vérifiez d'abord que vos clés/certificats sont bien corrects avec des bons droits pour y accéder.