Cette page contient des infos sur le fonctionnement de LDAP au CRANS. Des infos supplémentaires se trouvent sur MigrationLdap. On va se limiter ici à des informations de mise en place :
Sommaire
Les sujets suivant ne sont pas traités :
- remplir la base
- interroger la base pour les besoins du CRANS
- fonctionnement des scripts CRANS
Avec BCfg2
Mise en place du serveur principal
Il devrait suffir de l'installer comme réplicat, puis de modifier BCfg2 en conséquence pour qu'il soit considéré comme maître. Ça n'a pas été testé
Mise en place d'un réplicat
Il faut, dans BCfg2, ajouter le serveur au groupe db-replica. Après avoir installé les fichiers de configuration et slapd, il suffit de démarrer le serveur. La synchronisation à vert se fait automatiquement via le mécanisme de syncrepl.
Réparation d'un réplicat corrompu
- Arrêter monit et cron pour éviter un redémarrage intempestif du serveur slapd
- Arrêter slapd
Supprimer tous les fichiers de /var/lib/ldap, sauf DB_CONFIG (rm /var/lib/ldap/[^D]*)
- Redémarrer slapd
- Redémarrer monit et cron
La base doit se synchroniser en quelques minutes.
Modification du schéma
La configuration dans BCfg2 n'est plus à jour (passage à /etc/ldap/slapd.d).
Il suffit de modifier le schéma dans BCfg2, puis de répercuter la modification sur tous les serveurs LDAP.
Ajout d'un groupe Unix
Par exemple :
from ldap_crans import crans_ldap db = crans_ldap() db.conn.add_s('cn=webradio,ou=Group,dc=crans,dc=org', [('cn', 'webradio'), ('gidNumber', '613'), ('objectClass', ['posixGroup', 'top']), ('userPassword', '{crypt}x')])
avec, bien sûr, un gidNumber non utilisé ...
Utilisation de LDAP par les applications
nsswitch
Deux modules nss pour LDAP sont en utilisation au Cr@ns : libnss-ldap sur les serveurs sous etch (sauf zamok), et libnss-ldapd (sur les serveurs sous lenny).
libnss-ldap
Assez ancien, plus trop maintenu, on évite désormais de l'utiliser. Il ouvre une connexion à la base ldap par requête nss, donc il pose un certain nombre de problèmes lorsque la charge est importante (sur zamok par exemple).
La configuration associée est dans BCfg2 (et est installée si le client est dans le groupe ldap, hors du groupe nss-ldapd)
libnss-ldapd
Plus récent, c'est une réécriture de libnss-ldap plus propre. En effet, un démon (nslcd) fait la connexion entre la bibliothèque nss et la base ldap. Ce démon permet de mettre en cache les données récupérées, de limiter le nombre de connexions à la base, et accessoirement de simplifier la base de code.
La configuration associée est dans BCfg2 (et est installée si le client est dans le groupe ldap ainsi que dans le groupe libnss-ldapd, ce qui est le cas entre autres pour les serveurs sous lenny).
PAM
Pour les besoins d'authentification d'une grande part des applications sous Linux, PAM (Pluggable Authentication Modules) est utilisé. Ce framework permet d'unifier les requêtes d'authentification pour toutes les applications. Un module existe pour l'authentification via une base LDAP, c'est libpam-ldap. La configuration associée est dans BCfg2 (groupe auth).
Le reste
Les autres services utilisent directement nss ou pam... Sauf quelques exceptions notables, postfix et dovecot.
Authentification Apache2 via LDAP
Assez pratique (par exemple pour restreindre l'accès d'une page aux apprentis et nounous), à mettre dans le fichier de config :
<Location /> AuthType basic AuthName "Une authentification LDAP super cool" AuthBasicProvider ldap AuthLDAPURL ldap://10.231.136.2/ou=data,dc=crans,dc=org?uid??(|(droits=Nounou)(droits=Apprenti)) AuthLDAPBindDN cn=readonly,dc=crans,dc=org AuthLDAPBindPassword <le mot de passe qui va bien> </Location>
Il faut activer les modules auth_basic et authnz_ldap. Il faut forcer le https pour éviter que les données d'authentification transitent en clair.
Peuplement de la base de tests
La base de tests est un dump complet de la base normale, où les mots de passe ont été remplacés par le mot de passe de la base de tests (cf. /usr/scripts/gestion/ldap_crans.py).
Installation
On installe slapd normalement, et on copie la config depuis un autre serveur, par exemple sable :
sudo /etc/init.d/slapd stop sudo mv /etc/ldap/slapd.d /etc/ldap/slapd.old sudo scp -r sable:/etc/ldap/slapd.d /etc/ldap/
Il faut supprimer la référence à syncrepl dans le fichier de configuration, pour éviter que le serveur de tests ne tente de se répliquer. Voir dans /etc/ldap/slapd.d/cn=config/olcDatabase={1}bdb.ldif, vers la fin.
Récupération du schema
Utile seulement si le schema de la base de donnée à changer depuis la dernière fois.
Sur le serveur ldap maître (actuellement vert):
sudo slapcat -n 0 > schema.ldif
Récupération des données
Sur le serveur ldap maître (actuellement vert):
sudo slapcat | sed '/^userPassword/s/:.*$/: {SSHA}sB+dHA1zBf\/w4KZU3l5mFh+rvxHJo8D1/; /^info:/s/de prod/de dev/' > ldap_dump_date.ldif
Le mot de passe est remplacé par {SSHA}sB+dHA1zBf/w4KZU3l5mFh+rvxHJo8D1 dans chaque entrée (ce hash a été généré à l'aide de /usr/sbin/slappasswd -s <mot de passe de la base de tests> sur une machine qui a slapd installé). Les commentaires de la forme "je suis le $X de production" sont remplacés par la deuxième règle sed. Ceci permet de rapidement savoir si l'on est en environnement de dev ou de prod par simple whos sur son nom.
Repeuplement de la base
Sur le serveur de tests :
sudo su - monit stop slapd rm /var/lib/ldap/[^D]* slapadd -n 0 -l schema.ldif slapadd -l /home/.../ldap_dump_date.ldif monit start slapd
Enjoy.
Avant BCfg2
Les informations ci-après sont conservées dans un but pégago-historique, elles ne sont plus vraiment d'actualité -- WikiNicolasd 2008-12-07 22:49:27
Mise en place du serveur principal
Installation
On installe donc le serveur LDAP en paquet Debian.
aptitude install slapd
Configuration
On veut utiliser des sockets Unix (communication par un fichier spécial) donc on doit modifier /etc/default/slapd pour avoir quelque chose comme ça :
SLAPD_SERVICES="ldaps:/// ldapi://%2fvar%2frun%2fldapi/"
Ainsi, le serveur LDAP écoutera sur deux interfaces : l'une en TCP+TLS, donc sur le réseau et l'autre pour les clients locaux via une socket unix. Les %2f représentent un /.
Il n'est pas possible facilement de spécifier les droits sur la socket. On modifie donc /etc/init.d/slapd pour que les droits soient placés correctement au démarrage. Par exemple, dans la fonction do_start, on rajoute à la fin :
sleep 1 # Les droits sur les sockets chown root.adm /var/run/ldapi 2> /dev/null || true chmod 770 /var/run/ldapi 2> /dev/null || true # Performance pour le serveur LDAP renice -1 $(cat /var/run/slapd/slapd.pid) > /dev/null 2> /dev/null || true
Le renice permet d'avoir un serveur LDAP prioritaire si le système est chargé. Voici le fichier tout fait (tel qu'il est sur zamok) : slapd.
Ensuite, on doit modifier le fichier /etc/ldap/slapd.conf. Parmi les options importantes :
- spécifier le schéma de la base (en plus des schémas standards) :
include /etc/ldap/schema/crans.schema
- Spéficier le niveau de log ; mettre autre chose que 0 peut avoir des impacts importants sur la base :
loglevel 0
spécifier le backend à utiliser ; on utilise back_bdb :
moduleload back_bdb backend bdb
- préciser le suffixe :
suffix "dc=crans,dc=org"
- les directives d'accès aux différents champs ; par exemple :
access to attribute=userPassword by dn="cn=admin,dc=crans,dc=org" write by anonymous auth by self write by * none access to * by dn="cn=admin,dc=crans,dc=org" write by sockname="ldapi" read by dn="cn=readonly,dc=crans,dc=org" read by self read by * none
enfin, indexer les champs les plus utilisés comme uid ; cela a une grande importance pour les performances de la base.
index objectClass,memberUid,uid eq
- pour du SSL, on doit coller des certificats dont le CN est le nom de la machine (qualifié entièrement) :
TLSCipherSuite HIGH:MEDIUM:+SSLv3 TLSCertificateFile /etc/ssl/certs/egon.pem TLSCertificateKeyFile /etc/ssl/private/egon.key TLSCACertificateFile /etc/ssl/certs/CAcrans.pem TLSVerifyClient never
Installation de la base
La base est installée par un moyen inconnu (copie ou slapcat lorsque le serveur tourne).
Mise en place d'un miroir
Côté serveur
On doit d'abord ajouter dans la base un utilisateur replica en s'inspirant de l'utilisateur admin : on colle ceci dans un fichier :
dn: cn=replica,dc=crans,dc=org objectClass: simpleSecurityObject objectClass: organizationalRole cn: replica description: Replica pour slapd esclave userPassword: {SSHA}x
On ajoute l'utilisateur dans la base (qui doit être arrêtée)
sudo -u openldap slapadd -l machin
Cette méthode n'est pas terrible, surtout quand il y a des réplicas. Il vaut mieux utiliser ldapadd. Par exemple :
ldapadd -x -D "cn=admin,dc=crans,dc=org" -W -f machin
On lui attribue un mot de passe :
ldappasswd -x -D "cn=admin,dc=crans,dc=org" -W 'cn=replica,dc=crans,dc=org' -s passreplica
Ensuite, on rajoute dans slapd.conf :
replica uri=ldaps://egon.crans.org:636 binddn="cn=replica,dc=crans,dc=org" bindmethod=simple credentials=passreplica replogfile /var/log/ldap_replicate.log
On arrête la base. On met à jour /etc/ldap/ldap.conf comme pour un client.
Pour changer le mot de passe admin, on peut tapper :
sudo ldappasswd -H ldapi://%2fvar%2frun%2fldapi/ -x -D "cn=admin,dc=crans,dc=org" -W 'cn=admin,dc=crans,dc=org' -S
Il faut tapper deux fois le nouveau mot de passe admin, puis l'ancien.
Sur le client
- On install LDAP comme sur le serveur (on recopie les fichiers).
- On supprime les deux instructions pour les replica introduites ci-dessus.
On colle dans slapd.conf :
updatedn "cn=replica,dc=crans,dc=org" updateref ldaps://zamok.crans.org:636
- On copie la base du serveur (les deux LDAP sont stoppés !) à l'aide de slapcat et slapadd
- On relance les serveurs sur le serveur puis sur le client
En version rapide
Pour le serveur, recopier depuis zamok :
/etc/ldap/slapd.conf
/etc/ldap/ldap.conf
/etc/ldap.secret
/etc/init.d/slapd
/etc/default/slapd
/etc/ldap/schema/*
- les certificats qui vont bien
Pour le client, recopier les mêmes fichiers depuis egon. Puis copier les bases (serveurs arretés) et relancer sur le serveur d'abord puis sur le client ensuite.
Mise en place côté client
Côté client, on doit configurer notamment PAM, nsswitch et peut-être d'autres logiciels.
Attention ! En suivant ce qui suit, on donne le droit à tout le monde de se logguer sur les machines en question. Il faut mettre en place une restriction d'accès (par exemple au niveau de ssh)
nsswitch
nsswitch est utilisé par la libc pour savoir qui interroger pour les infos type groupe, mots de passe. Par défaut, on utilise les fichiers /etc/passwd, /etc/group et /etc/shadow par exemple. La première étape est de modifier /etc/nsswitch.conf :
passwd: files ldap group: files ldap shadow: files ldap
Tout le reste ne change pas. On doit laisser files pour les utilisateurs qui ne sont pas dans la base LDAP, style root. Il faut ensuite installer un daemon qui puisse faire les requêtes à la base ldap.
libnss_ldap
Il s'agit de l'ancienne solution utilisée, elle ne l'est plus notamment car elle ouvrait trop de connexions.
aptitude install libnss-ldap
On doit ensuite expliquer à nsswitch comment accéder à la base LDAP. On modifie /etc/libnss_ldap.conf :
base dc=crans,dc=org uri ldapi://%2fvar%2frun%2fldapi/ ldap_version 3 rootbinddn cn=admin,dc=crans,dc=org scope one nss_base_passwd ou=data,dc=crans,dc=org?one nss_base_shadow ou=data,dc=crans,dc=org?one nss_base_group ou=Group,dc=crans,dc=org?one
On lui indique comme accéder à la base (donc avec une socket ici), comment passer root (le mot de passe est dans /etc/ldap.secrets. Le reste ne concerne que de l'optimisation. On lui indique où trouver dans la base les informations les plus importantes ; il évite ainsi de chercher toute la base.
Pour améliorer l'ensemble, on peut utiliser le démon nscd qui cache les réponses. Il n'y a pas de configuration à faire.
libnss_ldapd
aptitude install libnss-ldapd
Il s'agit d'une réécriture plus propre de libnss-ldap.
Le fichier de conf sous lenny est /etc/nss-ldapd.conf, sous squeeze c'est /etc/nslcd.conf, en effet, il fournit un daemon nslcd qui va effectuer les requêtes ldap.
# Utilisateur sous lequel faire tourner le démon uid nslcd gid nslcd # Configuration de la communication avec le serveur uri ldap://10.231.136.2/ base dc=crans,dc=org binddn cn=readonly,dc=crans,dc=org bindpw s3kr3t ldap_version 3 timelimit 5 bind_timelimit 5 # Bases de recherche base passwd ou=data,dc=crans,dc=org base shadow ou=data,dc=crans,dc=org base group ou=Group,dc=crans,dc=org # Filtre de recherche filter passwd (|(droits=Nounou)(droits=Apprenti)(droits=Bureau))
PAM
aptitude install libpam-ldap
PAM permet à l'utilisateur de s'authentifier et de changer son mot de passe. La config se trouve dans /etc/pam.d. Normalement, il n'y a rien à modifier pour qu'il utilise la base LDAP : il passera par nsswitch (sauf pour le mot de passe). Toutefois, si on veut être sûr qu'il utilise LDAP, on doit :
s'assurer d'avoir des versions Debian des fichiers : la plupart ont une directive du type @include common-auth
modifier les fichiers common-auth et common-account pour ajouter en tête :
account sufficient pam_ldap.so account required pam_unix.so use_first_pass
auth sufficient pam_ldap.so auth required pam_unix.so nullok_secure use_first_pass
use_first_pass permet de ne pas redemander le mot de passe si l'authentification LDAP échoue.
On peut utiliser try_first_pass à la place ; si le mot de passe donné pour LDAP ne fonctionne pas pour Unix, on en demande un nouveau.
modifier common-password qui permet de changer de mot de passe :
password required pam_cracklib.so retry=10 minlen=8 difok=3 dcredit=-1 lcredit=-1 ucredit=-1 password required pam_ldap.so ignore_unknown_user md5 password optional pam_unix.so nullok obscure min=4 max=8 md5 try_first_pass
Avec cet exemple, on fait d'abord une vérif avec la crakclib, puis on change le mot de passe LDAP et optionnellement le mot de passe Unix. Le ignore_unknown_user permet de ne pas avoir d'erreur pour les utilisateurs qui ne sont pas dans la base LDAP. Si l'utilisateur est présent dans les deux bases, il doit changer les deux mots de passe.
Il faut ensuite modifier /etc/pam_ldap.conf. A peu de choses près, c'est le même que /etc/libnss_ldap.conf :
base dc=crans,dc=org uri ldapi://%2fvar%2frun%2fldapi/ ldap_version 3 rootbinddn cn=admin,dc=crans,dc=org scope one pam_password exop nss_base_passwd ou=data,dc=crans,dc=org?one nss_base_shadow ou=data,dc=crans,dc=org?one nss_base_group ou=Group,dc=crans,dc=org?one
Le reste
La plupart des services utilisent exclusivement PAM ou nsswitch, il n'y a donc rien à faire. Attention toutefois, si un service tourne dans une chroot et qu'on utilise une socket, il doit avoir accès à la socket. On peut donc demander à slapd d'ouvrir une seconde socket dans la chroot. C'est le cas avec postfix sur zamok.
Version courte
aptitude install libnss-ldap aptitude install libpam-ldap aptitude install libpam-cracklib
Puis copier depuis komaz :
/etc/libnss-ldap.conf
/etc/pam_ldap.conf
/etc/pam.d/*
/etc/nsswitch.conf
/etc/ldap.secret
/etc/ldap/ldap.conf
le certificat racine référencé dans le fichier en question (en gardant une console root à portée de main) : /etc/ssl/certs
Et pour un serveur, il faut copier depuis vert :
/etc/ldap/schema/*
Synchronisation des réplicas
Il s'agit de dumper la base du serveur maître, et de supprimer et repeupler les bases des réplicas. Lors du remplissage des bases des réplicas, il faut que slapd soit arrêter, et qu'il ne soit pas lancé pas des démons annexes. Voici la marche à suivre pour synchroniser sila et pegase (réplicas) sur vert (maître) :
- Ouvrir une console root (au cas où) dans le même répertoire (en NFS, son home par exemple) sur vert, sila et pegase.
- Explications
- pour le même répertoire : le dump doit être accessible sur les trois machines
- pour la console root : sudo utilise la base ldap pour l'authentification, donc si par malheur la base n'est pas dans un état "stable", on peut perdre la possibilité de faire des sudo !
- Sur sila et pegase, arrêter slapd :
/etc/init.d/cron stop /etc/init.d/monit stop /etc/init.d/slapd stop
- Explication
- monit surveille slapd, et cron relance monit. Dire à monit de ne plus monitorer slapd ne semble pas être efficace.
- Sur vert, dumper la base :
umask 077 /etc/init.d/cron stop /etc/init.d/monit stop /etc/init.d/slapd stop slapcat > ldap.dump rm -rf /var/spool/slurpd/replica/* || true /etc/init.d/slapd start /etc/init.d/monit start /etc/init.d/cron start
- Sur sila et pegase, repeupler les bases et relancer slapd :
### S'assurer que slapd est bien arrêté ### rm -rf /var/lib/ldap/* sudo -u openldap slapadd -l ldap.dump /etc/init.d/slapd start /etc/init.d/monit start /etc/init.d/cron start /etc/init.d/slapd restart
- Attention
La dernière phase peut être longue (5 minutes). Et en pratique, il y a souvent un truc qui merde, donc il vaut mieux prévoir du temps et de l'imagination
- Notamment vérifier bien les permissions: /var/lib/ldap et /var/lib/ldap_log (s'il existent) doivent appartenir à openldap.
- Si les lignes ci-dessus sont mises dans un script, l'exécuter avec l'option -e (s'arrêter à la moindre erreur).
Gestion des droits
Les droits sont gérés exclusivement par les directives access. Il y a plusieurs cas :
on accède via une socket unix qui a une directive access en write, donc tous ceux qui peuvent accéder à la socket ont le droit en écriture (actuellement, sur zamok, postfix a le droit en écriture, ce serait à modifier). On limite donc avec les droits Unix.
on accède par un autre moyen, il va donc falloir s'identifier. Il y a moyen de s'identifier avec des certificats (SASL), mais dans notre cas, on utilise des mots de passe. On en a donc un pour l'utilisateur cn=admin et un pour cn=replica. Ces deux là ont accès en écriture à la totalité de la base. On peut en rajouter d'autres (dans la base) et leur donner des droits particuliers. Sur komaz, on pourra par exemple avoir un utilisateur qui a le droit de mettre à jour le blacklistage uniquement. Ensuite, il y a quelques cas particuliers : un utilisateur peut voir ses infos ou mettre à jour son mot de passe (self) ou un anonyme peut utiliser le champ mot de passe pour s'authentifier.
En pratique, on donne le mot de passe admin à PAM et à nsswitch pour leurs besoins.