Serveur OpenLDAP
The Lightweight Directory Access Protocol, or LDAP, is a protocol for querying and modifying a X.500-based directory service running over TCP/IP. The current LDAP version is LDAPv3, as defined in RFC4510, and the LDAP implementation used in Ubuntu is OpenLDAP, currently at version 2.4.25 (Oneiric).
Ainsi, ce protocole accède aux répertoires LDAP. Voici quelques concepts et termes clé :
-
Un répertoire LDAP est une arborescence d'entrées de données de nature hiérarchique qui est appelée arborescence du répertoire d'information (DIT).
-
Une entrée se compose d'un ensemble d'attributs.
-
Un attribut possède un type (un nom/description) et une ou plusieurs valeurs.
-
Chaque attribut doit être défini dans au moins une classe d'objet.
-
Les attributs et classes d'objets sont définis dans les schémas (une classe d'objet est en fait considérée comme un type particulier d'attribut).
-
Chaque entrée possède un identifiant unique : son Nom distinctif (DN ou dn). Il s'agit de son Nom distinctif relatif (RDN), suivi par le DN (nom distinctif) de l'entrée parente.
-
Le DN de l'entrée n'est pas un attribut. Il n'est pas considéré comme faisant partie de l'entrée elle-même.
Les termes objet, conteneur et nœud ont une certaine connotations mais ils ont tous essentiellement la même signification que entrée, le terme techniquement correct.
Par exemple, ci-dessous, nous avons une entrée unique composée de 11 attributs. Son DN est « cn=John Doe,dc=exemple,dc=com » ; son RDN est « cn=John Doe » et son DN parent est « dc=exemple,dc=com ».
dn: cn=John Doe,dc=example,dc=com cn: John Doe givenName: John sn: Doe telephoneNumber: +1 888 555 6789 telephoneNumber: +1 888 555 1232 mail: john@example.com manager: cn=Larry Smith,dc=example,dc=com objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top
L'entrée ci-dessus est au format LDIF (format d'échange de données LDAP). Toute information que vous fournirez dans votre DIT doit également être dans un tel format. Il est défini dans la RFC2849.
Although this guide will describe how to use it for central authentication, LDAP is good for anything that involves a large number of access requests to a mostly-read, attribute-based (name:value) backend. Examples include an address book, a list of email addresses, and a mail server's configuration.
Installation
Installez le démon du serveur OpenLDAP et les utilitaires de gestion traditionnels de LDAP. On les trouve respectivement dans les paquets slapd et ldap-utils.
The installation of slapd will create a working configuration. In particular, it will create a database instance that you can use to store your data. However, the suffix (or base DN) of this instance will be determined from the domain name of the localhost. If you want something different, edit /etc/hosts and replace the domain name with one that will give you the suffix you desire. For instance, if you want a suffix of dc=example,dc=com then your file would have a line similar to this:
127.0.1.1 nom_d'hote.example.com nom-d'hote
Vous pouvez annuler la modification après l'installation du paquet.
Ce guide utilisera un suffixe de base de données tel que dc=exemple,dc=com.
Procédez à l'installation :
sudo apt-get install slapd ldap-utils
Since Ubuntu 8.10 slapd is designed to be configured within slapd itself by dedicating a separate DIT for that purpose. This allows one to dynamically configure slapd without the need to restart the service. This configuration database consists of a collection of text-based LDIF files located under /etc/ldap/slapd.d. This way of working is known by several names: the slapd-config method, the RTC method (Real Time Configuration), or the cn=config method. You can still use the traditional flat-file method (slapd.conf) but it's not recommended; the functionality will be eventually phased out.
Ubuntu utilise maintenant la méthode slapd-config pour la configuration de slapd et ce guide reflète cela.
During the install you were prompted to define administrative credentials. These are LDAP-based credentials for the rootDN of your database instance. By default, this user's DN is cn=admin,dc=example,dc=com. Also by default, there is no administrative account created for the slapd-config database and you will therefore need to authenticate externally to LDAP in order to access it. We will see how to do this later on.
De nos jours, certains schémas classiques (cosine, nis, inetorgperson) sont intégrés avec slapd. Il y a aussi un schéma « de base », un pré-requis pour que les schémas puissent fonctionner.
Inspection post-installation
Le processus d'installation met en place 2 DIT. Un pour slapd-config et un pour vos propres données (dc=exemple, dc=com). Jetons-y un coup d’œil.
-
C'est ce à quoi la base de données slapd-config/DIT ressemble. Rappelons que cette base de données est basée sur LDIF et réside dans /etc/ldap/slapd.d :
/etc/ldap/slapd.d/ /etc/ldap/slapd.d/cn=config /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif /etc/ldap/slapd.d/cn=config/cn=schema /etc/ldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={1}cosine.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={2}nis.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={3}inetorgperson.ldif /etc/ldap/slapd.d/cn=config/cn=schema.ldif /etc/ldap/slapd.d/cn=config/olcBackend={0}hdb.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={0}config.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={-1}frontend.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif /etc/ldap/slapd.d/cn=config.ldif
Ne pas modifier la base de données slapd-config directement. Effectuez des modifications via le protocole LDAP (utilitaires).
-
Voici ce à quoi le DIT slapd-config ressemble avec le protocole LDAP :
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn dn: cn=config dn: cn=module{0},cn=config dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: olcBackend={0}hdb,cn=config dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}hdb,cn=config
Explication des entrées :
-
cn=config : paramètres globaux
-
cn=module{0},cn=config : un module chargé dynamiquement
-
cn=schema,cn=config: contains hard-coded system-level schema
-
cn={0}core,cn=schema,cn=config: the hard-coded core schema
-
cn={1}cosine,cn=schema,cn=config : le schéma cosine
-
cn={2}nis,cn=schema,cn=config : le schéma nis
-
cn={3}inetorgperson,cn=schema,cn=config : le schéma inetorgperson
-
olcBackend={0}hdb,cn=config: the 'hdb' backend storage type
-
olcDatabase={-1}frontend,cn=config: frontend database, default settings for other databases
-
olcDatabase={0}config,cn=config : base de données de configuration slapd (cn=config)
-
olcDatabase={1}hdb,cn=config : votre exemple de base de données (dc=exemle,dc=com)
-
-
C'est ce à quoi le DIT de dc=exemple,dc=com ressemble :
ldapsearch -x -LLL -H ldap:/// -b dc=example,dc=com dn dn: dc=example,dc=com dn: cn=admin,dc=example,dc=com
Explication des entrées :
-
dc=example,dc=com : base du DIT
-
cn=admin,dc=exemple,dc=com : administrateur (rootDN) pour ce DIT (mis en place lors de l'installation du paquet)
-
Modification/Remplissage de votre base de données
Introduisons un peu de contenu dans notre base de données. Nous allons ajouter ce qui suit :
-
un nœud appelé Gens (pour stocker les utilisateurs)
-
un nœud appelé Groupes (pour stocker les groupes)
-
a group called miners
-
un utilisateur appelé john
Créez le fichier LDIF suivant et appelez le add_content.ldif :
dn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People dn: ou=Groups,dc=example,dc=com objectClass: organizationalUnit ou: Groups dn: cn=miners,ou=Groups,dc=example,dc=com objectClass: posixGroup cn: miners gidNumber: 5000 dn: uid=john,ou=People,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: john sn: Doe givenName: John cn: John Doe displayName: John Doe uidNumber: 10000 gidNumber: 5000 userPassword: johnldap gecos: John Doe loginShell: /bin/bash homeDirectory: /home/john
It's important that uid and gid values in your directory do not collide with local values. Use high number ranges, such as starting at 5000. By setting the uid and gid values in ldap high, you also allow for easier control of what can be done with a local user vs a ldap one. More on that later.
Ajouter le contenu :
ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_content.ldif Enter LDAP Password: ******** adding new entry "ou=People,dc=example,dc=com" adding new entry "ou=Groups,dc=example,dc=com" adding new entry "cn=miners,ou=Groups,dc=example,dc=com" adding new entry "uid=john,ou=People,dc=example,dc=com"
Nous pouvons vérifier que l'information a été correctement ajoutée avec l'utilitaire ldapsearch :
ldapsearch -x -LLL -b dc=example,dc=com 'uid=john' cn gidNumber dn: uid=john,ou=People,dc=example,dc=com cn: John Doe gidNumber: 5000
Explication des changements :
-
La liaison« simple » -x: ; n'utilisera pas la méthode SASL par défaut
-
-LLL: désactive les informations externes d'impression
-
uid=john : un « filtre » pour trouver l'utilisateur john
-
cn gidNumber : demande l'affichage de certains attributs (la valeur par défaut fait s'afficher tous les attributs)
Modification de la base de données de configuration slapd
Le DIT de slapd-config peut également être interrogé et modifié. Voici quelques exemples.
-
Utilisez ldapmodify pour ajouter un « Index » (attribut DbIndex) à votre base de données {1}hdb,cn=config (dc=exemple,dc=com). Créez un fichier que vous appellerez uid_index.ldif contenant ce qui suit :
dn: olcDatabase={1}hdb,cn=config add: olcDbIndex olcDbIndex: uid eq,pres,sub
Puis, exécutez la commande suivante :
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f uid_index.ldif modification de l'entrée « olcDatabase={1}hdb,cn=config »
Vous pouvez confirmer le changement de cette manière :
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={1}hdb)' olcDbIndex dn: olcDatabase={1}hdb,cn=config olcDbIndex: objectClass eq olcDbIndex: uid eq,pres,sub
-
Ajoutons un schéma. Il devra d'abord être converti au format LDIF. Vous pouvez trouver des schémas non convertis, en plus de ceux convertis dans le dossier /etc/ldap/schema.
-
Il n'est pas courant de supprimer un schéma de la base de données slapd-config. Entrainez vous à l'ajout de schémas sur un système de test.
-
Before adding any schema, you should check which schemas are already installed (shown is a default, out-of-the-box output):
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=schema,cn=config dn dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config
Dans l'exemple suivant, nous ajouterons le schéma CORBA.
-
Créez le fichier de configuration de conversion schema_convert.conf contenant les lignes suivantes :
include /etc/ldap/schema/core.schema include /etc/ldap/schema/collective.schema include /etc/ldap/schema/corba.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/duaconf.schema include /etc/ldap/schema/dyngroup.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/java.schema include /etc/ldap/schema/misc.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/openldap.schema include /etc/ldap/schema/ppolicy.schema include /etc/ldap/schema/ldapns.schema include /etc/ldap/schema/pmi.schema
-
Créez le répertoire de sortie ldif_output.
-
Déterminez l'index du schéma :
slapcat -f schema_convert.conf -F ldif_output -n 0 | grep corba,cn=schema cn={1}corba,cn=schema,cn=config
When slapd ingests objects with the same parent DN it will create an index for that object. An index is contained within braces: {X}.
-
Utilisez slapcat pour effectuer la conversion :
slapcat -f schema_convert.conf -F ldif_output -n0 -H \ ldap:///cn={1}corba,cn=schema,cn=config -l cn=corba.ldif
Le schéma converti est maintenant dans cn=corba.ldif
-
Modifiez cn=corba.ldif pour atteindre les attributs suivants :
dn: cn=corba,cn=schema,cn=config ... cn: corba
Supprimez également les lignes suivantes à partir du bas :
structuralObjectClass: olcSchemaConfig entryUUID: 52109a02-66ab-1030-8be2-bbf166230478 creatorsName: cn=config createTimestamp: 20110829165435Z entryCSN: 20110829165435.935248Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20110829165435Z
Vos valeurs d'attributs varieront.
-
Enfin, utilisez ldapadd pour ajouter le nouveau schéma au DIT slapd-config :
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f cn\=corba.ldif ajout de nouvelle entrée « cn=corba,cn=schema,cn=config »
-
Confirmez les schémas actuellement chargés :
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: cn={4}corba,cn=schema,cn=config
-
For external applications and clients to authenticate using LDAP they will each need to be specifically configured to do so. Refer to the appropriate client-side documentation for details.
Journal
Activity logging for slapd is indispensible when implementing an OpenLDAP-based solution yet it must be manually enabled after software installation. Otherwise, only rudimentary messages will appear in the logs. Logging, like any other slapd configuration, is enabled via the slapd-config database.
OpenLDAP comes with multiple logging subsystems (levels) with each one containing the lower one (additive). A good level to try is stats. The slapd-config man page has more to say on the different subsystems.
Créez le fichier logging.ldif avec le contenu suivant :
dn: cn=config changetype: modify add: olcLogLevel olcLogLevel: stats
Appliquez le changement :
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logging.ldif
This will produce a significant amount of logging and you will want to throttle back to a less verbose level once your system is in production. While in this verbose mode your host's syslog engine (rsyslog) may have a hard time keeping up and may drop messages:
rsyslogd-2177 : imuxsock a perdu 228 messages du pid 2547 à cause de la limitation de débit
Vous pouvez envisager un changement dans la configuration de rsyslog. Dans /etc/rsyslog.conf, entrez :
# Désactivez la limitation de débit # (la limitation par défaut est de 200 messages en 5 secondes ; ci-dessous nous faisons que le 5 devienne 0) $SystemLogRateLimitInterval 0
Et puis redémarrez le démon rsyslog :
sudo service rsyslog restart
Réplication
The LDAP service becomes increasingly important as more networked systems begin to depend on it. In such an environment, it is standard practice to build redundancy (high availability) into LDAP to prevent havoc should the LDAP server become unresponsive. This is done through LDAP replication.
Replication is achieved via the Syncrepl engine. This allows changes to be synchronized using a Consumer - Provider model. The specific kind of replication we will implement in this guide is a combination of the following modes: refreshAndPersist and delta-syncrepl. This has the Provider push changed entries to the Consumer as soon as they're made but, in addition, only actual changes will be sent, not entire entries.
Configuration du fournisseur
Commencez par configurer le Fournisseur.
-
Créez un fichier LDIF avec le contenu suivant et nommez-le provider_sync.ldif :
# Add indexes to the frontend db. dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryCSN eq - add: olcDbIndex olcDbIndex: entryUUID eq #Load the syncprov and accesslog modules. dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov - add: olcModuleLoad olcModuleLoad: accesslog # Accesslog database definitions dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap/accesslog olcSuffix: cn=accesslog olcRootDN: cn=admin,dc=example,dc=com olcDbIndex: default eq olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart # Accesslog db syncprov. dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE # syncrepl Provider for primary db dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE # accesslog overlay definitions for primary db dn: olcOverlay=accesslog,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogSuccess: TRUE # scan the accesslog DB every day, and purge entries older than 7 days olcAccessLogPurge: 07+00:00 01+00:00
Changer le rootDN dans le fichier LDIF pour qu'il corresponde à celui que vous avez pour votre répertoire.
-
Le profil apparmor pour slapd devra être ajusté en ce qui concerne l'emplacement du journal d’accès de la base de données. Modifiez /etc/apparmor.d/local/usr.sbin.slapd en ajoutant ce qui suit :
/var/lib/ldap/accesslog/ r, /var/lib/ldap/accesslog/** rwk,
Créez un répertoire, mettez en place un fichier de configuration de base de données, et rechargez le profil apparmor :
sudo -u openldap mkdir /var/lib/ldap/accesslog sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog sudo service apparmor reload
-
Ajoutez le nouveau contenu et, en raison du changement dans apparmor, redémarrez le démon :
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif sudo service slapd restart
Le fournisseur est maintenant configuré.
Configuration de l'utilisateur
Et maintenant configurez le Consumer (Consommateur).
-
Installez le logiciel en passant par Installation. Assurez-vous que la base de données slapd-config est identique à celle du fournisseur. En particulier, assurez-vous que les schémas et le suffixe de base de données sont les mêmes.
-
Créez un fichier LDIF avec le contenu suivant et nommez-le consumer_sync.ldif :
dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryUUID eq - add: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.exemple.com bindmethod=simple binddn="cn=admin,dc=exemple,dc=com" credentials=secret searchbase="dc=exemple,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog - add: olcUpdateRef olcUpdateRef: ldap://ldap01.exemple.com
Vérifiez que les attributs suivants ont les bonnes valeurs :
fournisseur (nom d’hôte du serveur fournisseur -- ldap01.exemple.com dans cet exemple -- ou l'adresse IP)
binddn (le DN administrateur que vous utilisez)
credentials (le mot de passe administrateur DN que vous utilisez)
searchbase (le suffixe de base de données que vous utilisez)
olcUpdateRef (nom d’hôte du serveur fournisseur ou adresse IP)
rid (réplique d'identifiant unique à 3 chiffres qui définie la réplique. Chaque utilisateur devrait avoir au moins une réplique d'identifiant)
-
Ajoutez le nouveau contenu :
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f consumer_sync.ldif
Vous avez terminé. Les deux bases de données (suffixe : dc=exemple,dc=com) devraient maintenant se synchroniser.
Tests
Une fois que la réplication démarre, vous pouvez la suivre en exécutant
ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b dc=exemple,dc=com contextCSN dn: dc=example,dc=com contextCSN: 20120201193408.178454Z#000000#000#000000
sur le fournisseur et l'utilisateur. Une fois que la sortie (20120201193408.178454Z#000000#000#000000 dans l'exemple ci-dessus) correspond aux deux machines, vous avez la réplication. Chaque fois qu'une modification est effectuée pour le fournisseur, cette valeur changera, ainsi que celle des utilisateurs.
If your connection is slow and/or your ldap database large, it might take a while for the consumer's contextCSN match the provider's. But, you will know it is progressing since the consumer's contextCSN will be steadly increasing.
If the consumer's contextCSN is missing or does not match the provider, you should stop and figure out the issue before continuing. Try checking the slapd (syslog) and the auth log files in the provider to see if the consumer's authentication requests were successful or its requests to retrieve data (they look like a lot of ldapsearch statements) return no errors.
To test if it worked simply query, on the Consumer, the DNs in the database:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b dc=example,dc=com dn
You should see the user 'john' and the group 'miners' as well as the nodes 'People' and 'Groups'.
Contrôle d'accès
The management of what type of access (read, write, etc) users should be granted to resources is known as access control. The configuration directives involved are called access control lists or ACL.
When we installed the slapd package various ACL were set up automatically. We will look at a few important consequences of those defaults and, in so doing, we'll get an idea of how ACLs work and how they're configured.
To get the effective ACL for an LDAP query we need to look at the ACL entries of the database being queried as well as those of the special frontend database instance. The ACLs belonging to the latter act as defaults in case those of the former do not match. The frontend database is the second to be consulted and the ACL to be applied is the first to match ("first match wins") among these 2 ACL sources. The following commands will give, respectively, the ACLs of the hdb database ("dc=example,dc=com") and those of the frontend database:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={1}hdb)' olcAccess dn: olcDatabase={1}hdb,cn=config 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 * read
The rootDN always has full rights to it's database. Including it in an ACL does provide an explicit configuration but it also causes slapd to incur a performance penalty.
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={-1}frontend)' olcAccess dn: olcDatabase={-1}frontend,cn=config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred, cn=external,cn=auth manage by * break olcAccess: {1}to dn.exact="" by * read olcAccess: {2}to dn.base="cn=Subschema" by * read
La toute première ACL est cruciale :
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none
Ceci peut être représenté différemment pour une digestion plus facile :
to attrs=userPassword by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none to attrs=shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none
Cette ACL composée (il y en a deux) implique ce qui suit :
-
Anonymous 'auth' access is provided to the userPassword attribute for the initial connection to occur. Perhaps counter-intuitively, 'by anonymous auth' is needed even when anonymous access to the DIT is unwanted. Once the remote end is connected, howerver, authentication can occur (see next point).
-
Authentication can happen because all users have 'read' (due to 'by self write') access to the userPassword attribute.
-
L'attribut Mot_de_passe_utilisateur est par ailleurs inaccessible aux autres utilisateurs, à l'exception de rootDN, qui a l’accès complet à celui-ci.
-
Pour permettre aux utilisateurs de changer leurs mots de passe en utilisant la commande passwd ou d'autres utilitaires, l'attribut shadowLastChange doit être accessible une fois qu'un utilisateur s'est authentifié.
This DIT can be searched anonymously because of 'by * read' in this ACL:
to * by self write by dn="cn=admin,dc=example,dc=com" write by * read
Si ce n'est pas désiré, il vous faut modifier les ACLs. Pour forcer l'authentification lors d'une demande de liaison, vous pouvez alternativement (ou en combinaison avec l'ACL modifiée) utiliser la directive « olcRequire: authc ».
Comme mentionné précédemment, il n'existe pas de compte administrateur créé pour la base de données slapd-config. Il y a cependant une identité SASL accordée pour un accès complet à celle-ci. Il représente le super-utilisateur de l'hôte local (root/sudo). Le voici :
dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
La commande suivante affichera les ACL (listes de contrôle d’accès) de la base de données slapd-config :
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={0}config)' olcAccess dn: olcDatabase={0}config,cn=config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred, cn=external,cn=auth manage by * break
Since this is a SASL identity we need to use a SASL mechanism when invoking the LDAP utility in question and we have seen it plenty of times in this guide. It is the EXTERNAL mechanism. See the previous command for an example. Note that:
-
You must use sudo to become the root identity in order for the ACL to match.
-
Le mécanisme EXTERNE fonctionne via IPC (sockets de domaine UNIX). Cela signifie que vous devez utiliser le format URI ldapi.
Voici une façon rapide d'obtenir toutes les ACL :
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcAccess=*)' olcAccess olcSuffix
Il y a beaucoup à dire sur le sujet du contrôle d'accès. Voir la page de manuel sur les accès.slapd.
TLS
Pour s'authentifier sur un serveur OpenLDAP, il est préférable d'utiliser une session chiffrée. Cela peut être accompli en utilisant le protocole TLS (Transport Layer Security).
Ici, nous serons notre propre autorité de certification (CA), puis nous allons créer et signer notre certificat de serveur LDAP en tant que CA. Puisque slapd est compilé avec la bibliothèque gnutls, nous utiliserons l'utilitaire certtool pour effectuer ces tâches.
-
Installez les paquets gnutls-bin et ssl-cert :
sudo apt-get install gnutls-bin ssl-cert
-
Créer une clé privée pour l'autorité de certification :
sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
-
Créez le modèle ou le fichier /etc/ssl/ca.info pour définir le CA :
cn = Entreprise Exemple ca cert_signing_key
-
Créer le certificat d'autorité de certification auto-signé :
sudo certtool --generate-self-signed \ --load-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ca.info \ --outfile /etc/ssl/certs/cacert.pem
-
Créer une clef privée pour le serveur :
sudo certtool --generate-privkey \ --bits 1024 \ --outfile /etc/ssl/private/ldap01_slapd_key.pem
Replace ldap01 in the filename with your server's hostname. Naming the certificate and key for the host and service that will be using them will help keep things clear.
-
Créez le fichier d'informations /etc/ssl/ldap01.info contenant :
organization = Compagnie Exemple cn = ldap01.example.com tls_www_server encryption_key signing_key expiration_days = 3650
Le certificat ci-dessus est valable pendant 10 ans. Ajustez en conséquence.
-
Créer le certificat du serveur :
sudo certtool --generate-certificate \ --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ldap01.info \ --outfile /etc/ssl/certs/ldap01_slapd_cert.pem
Créez le fichier certinfo.ldif avec le contenu suivant (ajustez en conséquence, notre exemple suppose que nous avons créé les certificats en utilisant https://www.cacert.org) :
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
Utilisez la commande ldapmodify pour informer slapd de notre emploi de TLS via la base de données slapd-config :
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ssl/certinfo.ldif
Contrairement à la croyance populaire, vous n'avez pas besoin de ldaps :// dans /etc/default/slapd pour utiliser le chiffrement. Vous devriez avoir seulement :
SLAPD_SERVICES="ldap:/// ldapi:///"
LDAP over TLS/SSL (ldaps://) is deprecated in favour of StartTLS. The latter refers to an existing LDAP session (listening on TCP port 389) becoming protected by TLS/SSL whereas LDAPS, like HTTPS, is a distinct encrypted-from-the-start protocol that operates over TCP port 636.
Resserrez la propriété et les autorisations :
sudo adduser openldap ssl-cert sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
Redémarrez OpenLDAP :
sudo service slapd restart
Consultez les fichiers de journalisation de votre hôte (/var/log/syslog) pour voir si le serveur a démarré correctement.
Réplication et TLS
If you have set up replication between servers, it is common practice to encrypt (StartTLS) the replication traffic to prevent evesdropping. This is distinct from using encryption with authentication as we did above. In this section we will build on that TLS-authentication work.
The assumption here is that you have set up replication between Provider and Consumer according to Réplication and have configured TLS for authentication on the Provider by following TLS.
As previously stated, the objective (for us) with replication is high availablity for the LDAP service. Since we have TLS for authentication on the Provider we will require the same on the Consumer. In addition to this, however, we want to encrypt replication traffic. What remains to be done is to create a key and certificate for the Consumer and then configure accordingly. We will generate the key/certificate on the Provider, to avoid having to create another CA certificate, and then transfer the necessary material over to the Consumer.
-
Sur le fournisseur,
Créez un répertoire (qui sera utilisé pour le transfert éventuel), puis la clé privée de l'utilisateur :
mkdir ldap02-ssl cd ldap02-ssl sudo certtool --generate-privkey \ --bits 1024 \ --outfile ldap02_slapd_key.pem
Créez un fichier info, ldap02.info, pour le serveur utilisateur, en ajustant ses valeurs en conséquence :
organization = Compagnie Exemple cn = ldap02.example.com tls_www_server encryption_key signing_key expiration_days = 3650
Créer le certificat du consommateur :
sudo certtool --generate-certificate \ --load-privkey ldap02_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template ldap02.info \ --outfile ldap02_slapd_cert.pem
Obtenir une copie du certificat CA :
cp /etc/ssl/certs/cacert.pem .
Nous avons terminé. Maintenant transférez le répertoire ldap02-ssl à l'utilisateur. Ici, nous utilisons scp (ajustez en conséquence) :
cd .. scp -r ldap02-ssl utilisateur@consumer :
-
Sur l'utilisateur,
Configurer l'authentification TLS :
sudo apt-get install ssl-cert sudo adduser openldap ssl-cert sudo cp ldap02_slapd_cert.pem cacert.pem /etc/ssl/certs sudo cp ldap02_slapd_key.pem /etc/ssl/private sudo chgrp ssl-cert /etc/ssl/private/ldap02_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap02_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap02_slapd_key.pem
Créez le fichier /etc/ssl/certinfo.ldif avec le contenu suivant (ajustez en conséquence) :
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap02_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap02_slapd_key.pem
Configurer la base de données slapd-config :
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
Configurez /etc/default/slapd comme sur le fournisseur (SLAPD_SERVICES).
-
Sur l'utilisateur,
Configure TLS for Consumer-side replication. Modify the existing olcSyncrepl attribute by tacking on some TLS options. In so doing, we will see, for the first time, how to change an attribute's value(s).
Créez le fichier utilisateur_sync_tls.ldif avec le contenu suivant :
dn: olcDatabase={1}hdb,cn=config replace: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog starttls=critical tls_reqcert=demand
The extra options specify, respectively, that the consumer must use StartTLS and that the CA certificate is required to verify the Provider's identity. Also note the LDIF syntax for changing the values of an attribute ('replace').
Mettre en œuvre ces changements :
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f consumer_sync_tls.ldif
Et redémarrez slapd :
sudo service slapd restart
-
Sur le fournisseur,
Check to see that a TLS session has been established. In /var/log/syslog, providing you have 'conns'-level logging set up, you should see messages similar to:
slapd[3620]: conn=1047 fd=20 ACCEPT from IP=10.153.107.229:57922 (IP=0.0.0.0:389) slapd[3620]: conn=1047 op=0 EXT oid=1.3.6.1.4.1.1466.20037 slapd[3620]: conn=1047 op=0 STARTTLS slapd[3620]: conn=1047 op=0 RESULT oid= err=0 text= slapd[3620]: conn=1047 fd=20 TLS established tls_ssf=128 ssf=128 slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" method=128 slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0 slapd[3620]: conn=1047 op=1 RESULT tag=97 err=0 text
Authentification LDAP
Une fois que vous avez un serveur LDAP fonctionnel, vous devrez installer des bibliothèques sur le client qui saura comment et quand les contacter. Sur Ubuntu, ceci a été traditionnellement fait par l'installation du paquet libnss-ldap. Ce paquet apportera d'autres outils qui vous assisteront dans l'étape de configuration. Maintenant, installez ce paquet :
sudo apt-get install libnss-ldap
Vous serez invité à entrer les détails de votre serveur LDAP. Si vous faites une erreur, vous pouvez essayer à nouveau en utilisant :
sudo dpkg-reconfigure ldap-auth-config
Le résultat de la configuration est visible dans /etc/ldap.conf. Si votre serveur requiert des options non couvertes par l'assistant, modifiez ce fichier en conséquence.
Maintenant, configurez le profil LDAP pour NSS :
sudo auth-client-config -t nss -p lac_ldap
Configurez le système pour qu'il utilise LDAP pour l'authentification :
sudo pam-auth-update
Dans le menu, choisissez LDAP et les autres mécanismes d'authentification dont vous avez besoin.
Vous devriez maintenant être capable de vous connecter en utilisant les informations d'identification basées sur LDAP.
Les clients LDAP devront se référer à plusieurs serveurs si la réplication est en cours d'utilisation. Dans /etc/ldap.conf, vous devriez avoir quelque chose comme :
uri ldap://ldap01.example.com ldap://ldap02.example.com
The request will time out and the Consumer (ldap02) will attempt to be reached if the Provider (ldap01) becomes unresponsive.
Si vous envisagez d'utiliser LDAP pour stocker les utilisateurs Samba, vous devrez configurer le serveur Samba pour qu'il s'authentifie en utilisant LDAP. Voir Samba et LDAP pour plus de détails.
Une alternative au paquet libnss-ldap est libnss-ldapd. Cependant, ceci apportera le paquet nscd qui est probablement indésirable. Il vous suffit de le retirer par la suite.
Gestion des groupes et utilisateurs
The ldap-utils package comes with enough utilities to manage the directory but the long string of options needed can make them a burden to use. The ldapscripts package contains wrapper scripts to these utilities that some people find easier to use.
Installez le paquet :
sudo apt-get install ldapscripts
Puis éditez le fichier /etc/ldapscripts/ldapscripts.conf pour arriver à quelque chose de semblable à ce qui suit :
SERVER=localhost BINDDN='cn=admin,dc=example,dc=com' BINDPWDFILE="/etc/ldapscripts/ldapscripts.passwd" SUFFIX='dc=example,dc=com' GSUFFIX='ou=Groups' USUFFIX='ou=People' MSUFFIX='ou=Computers' GIDSTART=10000 UIDSTART=10000 MIDSTART=10000
Maintenant, créez le fichier ldapscripts.passwd pour permettre l'accès de rootDN au répertoire :
sudo sh -c "echo -n 'secret' > /etc/ldapscripts/ldapscripts.passwd" sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
Remplacez « secret » par le mot de passe actuel de l'utilisateur rootdn de votre base de données.
Les scripts sont maintenant prêts à vous aider à gérer votre répertoire. Voici quelques exemples de la façon de les utiliser :
-
Créez un nouvel utilisateur :
sudo ldapadduser laurence exemple
Ceci créera un utilisateur ayant pour UID laurence et pour groupe primaire (GID) exemple.
-
Modifiez un mot de passe utilisateur :
sudo ldapsetpasswd laurence Modifier le mot de passe de l'utilisateur uid=laurence,ou=People,dc=example,dc=com Nouveau mot de passe : Nouveau mot de passe (vérification) :
-
Supprimer un utilisateur :
sudo ldapdeleteuser laurence
-
Ajouter un groupe :
sudo ldapaddgroup qa
-
Supprimer un groupe :
sudo ldapdeletegroup qa
-
Ajouter un utilisateur à un groupe :
sudo ldapaddusertogroup laurence qa
Vous devez avoir maintenant un attribut memberUid ayant pour valeur laurence pour le groupe qa.
-
Supprimer un utilisateur d'un groupe :
sudo ldapdeleteuserfromgroup laurence qa
L'attribut memberUid ne doit plus apparaître dans le groupe qa group.
-
Le script ldapmodifyuser vous permet d'ajouter, supprimer ou modifier les attributs des utilisateurs. Il utilise la même syntaxe que ldapmodify. Par exemple :
sudo ldapmodifyuser laurence # About to modify the following entry : dn: uid=laurence,ou=People,dc=example,dc=com objectClass: account objectClass: posixAccount cn: george uid: george uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/laurence loginShell: /bin/bash gecos: george description: User account userPassword:: e1NTSEF9eXFsTFcyWlhwWkF1eGUybVdFWHZKRzJVMjFTSG9vcHk= # Enter your modifications here, end with CTRL-D. dn: uid=laurence,ou=People,dc=example,dc=com replace: gecos gecos: Laurence Bibot
Le gecos de l'utilisateur doit être maintenant « Laurence Bibot ».
-
L'une des fonctionnalités intéressantes de ldapscripts est son système de modèles qui permettent de personnaliser les attributs d'utilisateur, de groupe et des objets machine. Par exemple, pour activer le modèle utilisateur, modifiez /etc/ldapscripts/ldapscripts.conf en changeant :
UTEMPLATE="/etc/ldapscripts/ldapadduser.template"
Des modèles types se trouvent dans le répertoire /etc/ldapscripts. Copiez ou renommer le fichier ldapadduser.template.sample en /etc/ldapscripts/ldapadduser.template :
sudo cp /usr/share/doc/ldapscripts/examples/ldapadduser.template.sample \ /etc/ldapscripts/ldapadduser.template
Modifiez le nouveau modèle pour ajouter les attributs désirés. Ce qui suit va créer de nouveaux utilisateurs avec un objectClass de inetOrgPerson :
dn: uid=<user>,<usuffix>,<suffix> objectClass: inetOrgPerson objectClass: posixAccount cn: <user> sn: <ask> uid: <user> uidNumber: <uid> gidNumber: <gid> homeDirectory: <home> loginShell: <shell> gecos: <user> description: User account title: Employee
Remarquez l'option <ask> utilisée pour l'attribut sn. Cela fera que ldapadduser vous demandera sa valeur.
Il existe des utilitaires dans le paquet qui n'ont pas été abordés ici. En voici la liste complète :
ldaprenamemachine ldapadduser ldapdeleteuserfromgroup ldapfinger ldapid ldapgid ldapmodifyuser ldaprenameuser lsldap ldapaddusertogroup ldapsetpasswd ldapinit ldapaddgroup ldapdeletegroup ldapmodifygroup ldapdeletemachine ldaprenamegroup ldapaddmachine ldapmodifymachine ldapsetprimarygroup ldapdeleteuser
Archivage et restauration
ldap tourne maintenant tout juste comme nous le voulons, il est temps de s'assurer que nous pouvons enregistrer l'ensemble de notre travail et le restaurer si nécessaire.
What we need is a way to backup the ldap database(s), specifically the backend (cn=config) and frontend (dc=example,dc=com). If we are going to backup those databases into, say, /export/backup, we could use slapcat as shown in the following script, called /usr/local/bin/ldapbackup:
#!/bin/bash BACKUP_PATH=/export/backup SLAPCAT=/usr/sbin/slapcat nice ${SLAPCAT} -n 0 > ${BACKUP_PATH}/config.ldif nice ${SLAPCAT} -n 1 > ${BACKUP_PATH}/example.com.ldif nice ${SLAPCAT} -n 2 > ${BACKUP_PATH}/access.ldif chmod 640 ${BACKUP_PATH}/*.ldif
These files are uncompressed text files containing everything in your ldap databases including the tree layout, usernames, and every password. So, you might want to consider making /export/backup an encrypted partition and even having the script encrypt those files as it creates them. Ideally you should do both, but that depends on your security requirements.
Then, it is just a matter of having a cron script to run this program as often as we feel comfortable with. For many, once a day suffices. For others, more often is required. Here is an example of a cron script called /etc/cron.d/ldapbackup that is run every night at 22:45h:
MAILTO=backup-emails@domain.com 45 22 * * * root /usr/local/bin/ldapbackup
Les fichiers étant créés, ils doivent être copiés sur un serveur de sauvegarde.
En supposant que nous ayons fait une réinstallation fraîche de ldap, le processus de restauration pourrait être quelque chose comme ceci :
sudo service slapd stop sudo mkdir /var/lib/ldap/accesslog sudo slapadd -F /etc/ldap/slapd.d -n 0 -l /export/backup/config.ldif sudo slapadd -F /etc/ldap/slapd.d -n 1 -l /export/backup/domain.com.ldif sudo slapadd -F /etc/ldap/slapd.d -n 2 -l /export/backup/access.ldif sudo chown -R openldap:openldap /etc/ldap/slapd.d/ sudo chown -R openldap:openldap /var/lib/ldap/ sudo service slapd start
Ressources
-
La ressource principale est la documentation amont : www.openldap.org
-
Il y a de nombreuses pages de manuel fournies avec le paquet slapd. Voici quelques pages importantes, surtout au vu des documents présentés dans ce guide :
-
Autres pages de manuel :
-
Le site de Zytrax, LDAP for Rocket Scientists ; un peu magistral mais qui traite complètement de LDAP
-
Une page wiki en anglais sur OpenLDAP de la communauté Ubuntu qui comporte un ensemble de notes sur le sujet
-
LDAP System Administration sur le site de O'Reilly (manuel ; 2003)
-
Maîtriser OpenLDAP (en anglais) sur le site Packt (manuel ; 2007)