<center> # TP LDAP </center> ## 1. Préparation du BE Les deux machines sont importés sur VirtualBox. Ils sont sont connectés à une interface NAT et reliées par un réseau privé (192.168.8.1/24). Machine ServeurLDAP: ![](https://i.imgur.com/nkql3Ix.png) Machine StationLDAP: ![](https://i.imgur.com/gBEHBwR.png) ## 2. Authentification LDAP ### 2.1 Configuration du serveur LDAP Pour consulter la configuration actuelle du serveur LDAP, on execute: ```bash $ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" ``` 1. `-Y mech (SASL mechanism)` La méthode EXTERNAL est utilisée, ce qui signifie que l'opération de recherche sera authentifiée en utilisant les informations d'identification de l'utilisateur actuel qui exécute la commande `ldapsearch`. 2. `-H URI (LDAP Uniform Resource Identifier(s))`: Cette option spécifie l'URI du serveur LDAP auquel se connecter. Dans ce cas, l'URI est `ldapi:///`, ce qui signifie que le serveur LDAP fonctionne sur le système local et utilise le transport LDAPI. 3. `-b basedn` Cet argument spécifie le DN de base (nom distinctif) à utiliser pour l'opération de recherche. Dans ce cas, le DN de base est défini sur cn=config, qui est la racine de la configuration du serveur LDAP. #### Questions: 1. **Dans quelle partie de l’arbre sont stockés les schémas ? Quels sont les schémas d’installés ?** Les schéma sont stockés dans dans l'attribut subSchemaSubentry de l'entrée `cn=schema,cn=config`. Pour avoir la liste des schémas installes, on execute: ```bash $ ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config subSchemaSubentry ``` Ceci renvoie: ```ldap # schema, config dn: cn=schema,cn=config subschemaSubentry: cn=Subschema # {0}core, schema, config dn: cn={0}core,cn=schema,cn=config subschemaSubentry: cn=Subschema # {1}cosine, schema, config dn: cn={1}cosine,cn=schema,cn=config subschemaSubentry: cn=Subschema # {2}nis, schema, config dn: cn={2}nis,cn=schema,cn=config subschemaSubentry: cn=Subschema # {3}inetorgperson, schema, config dn: cn={3}inetorgperson,cn=schema,cn=config subschemaSubentry: cn=Subschema ``` On retrouve alors 4 schémas: `core`, `cosine`, `nis` et `inetorgperson`. 2. **Dans quelle partie de l’arbre de configuration est stockée la configuration de la base de données de cet arbre de configuration ? Quelle autre base de données est configurée par défaut ?** La configuration de la base de données pour l'arbre de configuration LDAP est stockée dans l'entrée `olcDatabase={0}config,cn=config`. On exécute la commande suivante : ```bash $ ldapsearch -Y EXTERNAL -H ldapi:/// -b "olcDatabase={0}config,cn=config" ``` Ceci revoit les information suivantes: ```ldap # {0}config, config dn: 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 ``` Cependant, il y a des autres bases de données configurés. Pour lister tout les backends, on éxecute: ```bash $ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" -LLL | grep -E "^olcDatabase" ``` Ce qui renvoie: ```ldap olcDatabase: {-1}frontend olcDatabase: {0}config olcDatabase: {1}mdb ``` 3. **D’après la configuration actuelle, qui peut modifier la configuration du serveur ?** D'après la configuration actuelle, la modification de la configuration du serveur LDAP est limitée à l'utilisateur ayant le DN `cn=admin,cn=config`. Cela est spécifié dans la ligne suivante de l'entrée `olcDatabase={0}config,cn=config` ```ldap olcRootDN: cn=admin,cn=config ``` 4. **Quel est le DN de l’administrateur de l’arbre de configuration ?** Le DN de l'administrateur de l'arbre de configuration est `cn=admin,cn=config`. #### Configuration du mot de passe de l'administrateur de l'arbre `config` ![](https://i.imgur.com/Y6DLqpL.png) #### Configuration de la DIT 1. On modifie le champs `olcSuffix` ![](https://i.imgur.com/pFIp03F.png) 2. On modifie les identifiants: ![](https://i.imgur.com/0rDgrvZ.png) 3. On se connecte via JXplorer à ces nouveau identifiants pour recevoir immédiatement l'erreur suivante: ![](https://i.imgur.com/B82FKTa.png) Cette erreur indique généralement que le client LDAP ne peut pas trouver l'entrée spécifiée dans l'arbre d'information du répertoire (DIT). Dans notre cas, l'entrée "dc=centralesupelec,dc=fr" n'existe pas encore dans le DIT En s'inpirant de l'exemple présenté dans le TP, on crée le ficheir `centralesupelec_fr_dit.ldif`: ![](https://i.imgur.com/hOYvLHf.png) On utilise après `ldapadd` pour ajotuer les unités organizationelles: ![](https://i.imgur.com/32yZBWX.png) On vérifie que ceci à bien marché en fesant une recherche avec `ldapsearch`: ![](https://i.imgur.com/w6E645R.png) On peut également connecter sur JXplorer pour vérifier les résultats: ![](https://i.imgur.com/8pKGoDW.png) Top 👍 #### Ajout des groupes et des membres ##### Groupes On s'inspirant de l'exemple présenté dans le TP, on crée un fichier `add_groups_centralesupelec.ldif`: ![](https://i.imgur.com/oxCdjxY.png) Puis on utilise ldapadd pour appliquer les changements: ![](https://i.imgur.com/MC2wHKp.png) ##### Membres On s'inspirant de l'exemple présenté, on crée un ficheir `add_users_centralesupelec.ldif` qui ajoute deux utilisateurs bob et alice avec des mot de passes identiques à leurs uid et appartenant au groupe `ssimember (gid 1006)`: ![](https://i.imgur.com/WAg71E1.png) Puis on utilise `ldapadd` pour ajouter ces nouvelles entrées. On vérifie que tout c'est bien passé en fesant un `ldapsearch` ou en regardant sur JXplorer: ![](https://i.imgur.com/N4Dwnns.png) #### Connexion en tant que `bob`: Sur JXplorer, on se connecte avec les identifiants suivants: ![](https://i.imgur.com/weiZJ3S.png) On observe des résultats très proche mais differentes. Ceci est le cas car chaque utilisateur a des permissions et des attributs différents dans l'annuaire LDAP. Par exemple `alice` ne peut pas voir le champs `User Password` de bob. ### 2.2 Sécurisation des communications et de l’accès au serveur #### Analyse des échanges 1. **Quels paquets correspondent à la phase d’authentification ?** Les paquets correspondant à la phase d'authentifcation sont les suivants: ![](https://i.imgur.com/nbVqPvG.png) 2. **Dans quel champs se situe le mot de passe ? Comment est échangé le mot de passe ?** Le mot de passe se situe dans le packet `bindRequest`. ![](https://i.imgur.com/TGmOGOh.png) On remarque que le mot de passe est échangé en clair. #### Configuration du serveur OpenLDAP avec un certificat SSL/TLS Sur la machine `serveurLDAP`, on crée les répertoire pour contenir les certificats et clé qu'on va générer. Puis on configure openSSL (`/usr/lib/ssl/openssl.cnf`) pour déposer les résultats dans `/etc/ssl/openldap`: ![](https://i.imgur.com/oNZpK2L.png) Après avoir créer les fichiers nécessaire pour lancer openssl (serial et db), on génère une clé (modulus 2048 bit) RSA en éxecutant: ```bash $ openssl genrsa -aes256 -out /etc/ssl/openldap/private/cakey.pem 2048 $ openssl rsa -in /etc/ssl/openldap/private/cakey.pem -out \ /etc/ssl/openldap/private/cakey.pem # Remove passphrase ``` Puis on crée un certificat CA signé par la clé privée qu'on vient de générer: ```bash $ openssl req -new -x509 -days 3650 -key /etc/ssl/openldap/private/cakey.pem \ -out /etc/ssl/openldap/certs/cacert.pem ``` Maintenant les étapes suivantes sont de générer une certificat pour le serveur LDAP puis la faire signer par la clé privée de la CA. ![](https://i.imgur.com/by5zoHU.png) Top 👍 Maintenant, il faut modifier le propriétaire des répertoires et des fichiers de certificat et de clé, pour qu’ils appartiennent à l’utilisateur correspondant au service slapd (le serveur openLDAP) : ```bash $ chown -R openldap: /etc/ssl/openldap/ ``` Finalement, il faut modifier la configuration de OpenLDAP pour prendre en charge les certificat et la clé privée du serveur. On ajoute le fichier `add_tls.ldif`: ![](https://i.imgur.com/OoztfmL.png) Puis on execute: ```bash $ ldapmodify -Y EXTERNAL -H ldapi:/// -f fichier.ldif ``` ![](https://i.imgur.com/9T6tg8g.png) La commande a réussi, on peut vérifier ceci en regardant jxplorer: ![](https://i.imgur.com/SN9UctP.png) #### Verification 1. **Quelle option faut-il passer à la commande pour qu’elle utilise obligatoirement TLS ?** On peut utiliser soit `-Z` or `--starttls` pour lancer `ldapsearch` avec TLS. Par exemple: ```bash $ ldapsearch -ZZ -h ServeurLDAP -D "cn=admin,cn=config" -w sis -b "cn=config" ``` 2. **Vérifiez votre configuration en tentant de vous connecter de manière anonyme, puis en vous authentifiant** L'authentification échoue: ![](https://i.imgur.com/PU9QeND.png) La raison derrière est que LDAPS n'est pas lancé. Pour corriger, il faut modifier `/etc/default/slapd` et ajouter `ldaps:///`à `SLAPD_SERVICES` En relancant le service, on constante (grâce à `netstat`) que `slapd` qui écoute sur le port 636: ![](https://i.imgur.com/pjz8tHf.png) Finalement, le programme se plaint que il n'y a pas de subject alternate name sur le certificat. Il a bien raison, la façon la plus facile de contourner ceci et d'ajouter une entrée dans `/etc/hosts` qui donne l'addresse IP du `ServeurLDAP`, puis connecter avec `ServeurLDAP` comme hôte. Il faut modifier `/etc/ldap/ldap.conf` sur le client pour qu'il accept mes certificats auto-signés avec `TLS_REQCERT ALLOW` (Ceci n'est pas obligatoire sur Jxplorer). ```bash $ ldapsearch -h ServeurLDAP -D "cn=admin,cn=config" -w sis -b "cn=config" -ZZ -v ``` Top 👍 #### Restriction des accès au serveur LDAP **1. Qu’est-ce qu’un bind anonyme dans LDAP ?** Un bind anonyme dans LDAP est une opération de liaison qui ne nécessite pas de fournir d'identifiant et de mot de passe. Il permet à un client LDAP de se connecter au serveur LDAP sans avoir besoin de s'authentifier. Cette opération est souvent utilisée pour récupérer des informations publiques, telles que les noms des entrées dans l'annuaire LDAP. **2. Effectuez une recherche sur votre serveur en utilisant un bind anonyme** Pour lancer un bind anonyme, on utilise l'option `-x`: ```bash $ ldapsearch -x -H ldaps://ServeurLDAP:636 -b "dc=centralesupelec,dc=fr" ``` **3. Quelles informations obtenez-vous ? Qu’en pensez-vous ?** On obtient toutes les entrées sous le DIT `dc=centralesupelec,dc=fr`. Les informations renvoyés ne devrait pas être publiques, ainsi il faut refuser cette requête dans le cas où on n'est pas authentifié. ##### Interdiction des bind anonymes. D'après la documentation de openLDAP, Le mécanisme de liaison anonyme est activé par défaut, mais peut être désactivé en spécifiant `disallow bind_anon` dans le fichier `slapd.conf`. Mais on note que la désactivation du mécanisme de liaison anonyme n'empêche pas l'accès anonyme à l'annuaire. Pour exiger une authentification pour accéder à l'annuaire, il convient de spécifier `require authc`. Cependant les nouvelles version de ldap n'utilisent plus `slapd.conf`. Pour exiger une authentification dans OpenLDAP, on doit modifier les règles de contrôle d'accès dans la base de données `cn=config`. On crée un fichier `add_auth.ldiff` ``` 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 ``` Puis on éxecute: ```bash $ ldapmodify -Y external -H ldapi:/// -f add_auth.ldif ``` pour la dernière fois. dorénavant, on utilisera: ```bash $ ldapmodify -H ldapi:/// -f add_auth.ldif -D "cn=admin,cn=config" -w sis ``` ##### Vérification ![](https://i.imgur.com/T8jFfLh.png) Top 👍 ### Configuration du client - PAM (Pluggable Authentication Modules) fournit une interface pour authentifier les utilisateurs lorsqu'ils se connectent à un système. Il permet d'ajouter facilement des modules pour implémenter différents types d'authentification, tels que l'authentification par mot de passe, l'authentification par carte à puce, l'authentification par empreinte digitale, etc. - NSS (Name Service Switch) fournit une interface pour résoudre les noms d'utilisateurs, de groupes, de machines, etc. Il permet de centraliser la gestion des informations d'identification pour les différents services sur un système, tels que les connexions SSH, les partages de fichiers NFS, les serveurs de messagerie, etc. NSS peut utiliser différents systèmes de stockage pour les informations d'identification, tels que les fichiers locaux, LDAP, NIS, etc. **Pour l’instant, quelles bases de données sont utilisées pour stocker les comptes utilisateurs ?** Les utilisateurs sont stockés dans une base de données appelée `ou=people,dc=centralesupelec,dc=fr`. **Quel(s) module(s) PAM est utilisé pour authentifier les utilisateurs ?** Le module PAM couramment utilisé pour l'authentification des utilisateurs est `pam_unix.so`. Dans `/etc/pam.d/common-auth`, on retrouve la ligne suivante: ```pam auth [success=1 default=ignore] pam_unix.so nullok ``` Cette ligne appelle le module `pam_unix`, qui fournit une authentification unix standard configurée dans le fichier `/etc/nsswitch.conf`. ```nsswitch.config passwd: files systemd group: files systemd ... ``` Dans notre, cas `files systemd` signifie simplement vérifier les fichiers /etc/passwd et /etc/shadow, sinon faire un `User/Group Record Lookup API via Varlink`. ##### System Security Services Daemon **Quelles bases de données sont utilisées pour rechercher les comptes utilisateurs ?** Comme on n'a pas configuré de base de recherche pour les comptes utilisateurs, alors la base de recherche par défaut sera la racine du serveur LDAP. Cela signifie que la recherche commencera à partir de la racine et parcourra toutes les entrées jusqu'à ce qu'elle trouve le compte utilisateur recherché **Comment se déroule maintenant la phase d’identification ?** Le contenu de `/etc/nsswitch.conf` contient maintenant la valeur `sss`: ```nsswitch.conf passwd: files systemd sss group: files systemd sss shadow: files sss ... ``` Ceci ne change pas la phase d'identification, mais il y a des changement dans la phase d'authentification. **Quel(s) module(s) PAM sont maintenant impliqués dans l’authentification ?** Le contenu de `/etc/pam.d/common-auth` est devenu: ```pam auth [success=2 default=ignore] pam_unix.so nullok auth [success=1 default=ignore] pam_sss.so use_first_pass ``` Ainsi le module PAM impliqué sont `pam_unix.so` (comme toujours) et `pam_sss.so`. **Comment se déroule maintenant l’authentification ?** SSSD permet à l'utilisateur de s'authentifier sur plusieurs sources, y compris des bases de données locales et des serveurs LDAP (W.I.P), ce qui peut améliorer la sécurité et la flexibilité de l'authentification ##### Création de compte machine et ACL On crée un compte machine et ajoute des règles d'accèss suivantes ``` dn: olcDatabase={1}mdb,cn=config changetype: modify add: olcAccess olcAccess: {0}to * by self read by dn.base="uid=machine,ou=people,dc=centralesupelec,dc=fr" read by * auth ``` En appliquant ces changement et on se connectant en tant que `machine`, on accès à la lecture des mot de passes des autres utilisateurs (ce qui n'était pas le cas). ##### Installation du certificat sur la station Depuis la machine StationLDAP: ```bash scp ServeurLDAP:/etc/ssl/openldap/certs/cacert.pem /etc/ssl/openldap/certs/cacert.pem ``` On écrit le fichier `/etc/sssd/sssd.conf`: ```sssd [sssd] services = nss, pam config_file_version = 2 domains = default [nss] override_shell = /bin/bash [pam] offline_credentials_expiration = 60 [domain/default] ldap_id_use_start_tls = True cache_credentials = True ldap_search_base = "ou=people,dc=centralesupelec,dc=fr" id_provider = ldap auth_provider = ldap chpass_provider = ldap ldap_uri = ldaps://ServeurLDAP:636 ldap_default_bind_dn = "uid=machine,ou=people,dc=centralesupelec,dc=fr" ldap_default_authtok = machine ldap_tls_reqcert = never ldap_tls_cacert = cacert.pem ldap_tls_cacertdir = /etc/ssl/openldap/certs/ ldap_search_timeout = 50 ldap_network_timeout = 60 ``` ![](https://i.imgur.com/LWtcUvq.png) Top 👍 ##### Vérification **Vérifiez que tous les utilisateurs sont bien connus de la station à l’aide de la commande id.** ![](https://i.imgur.com/ebs8dvP.png) Top 👍 **Vérifiez que les utilisateurs Bob et Alice peuvent s’authentifier sur la station.** ![](https://i.imgur.com/Cv1aBSt.png) Top 👍 **Modifiez la configuration de PAM pour qu’un utilisateur correctement authentifié sur le système ait son répertoire personnel automatiquement créé lorsqu’il n’existe pas déjà.** Dans mon cas, ni bob ni alice ont un repertoire personel. Il faut aller dans `/etc/pam.d/common-session` et ajouter la ligne suivante ```pam session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 ``` Cette ligne indique à PAM d'utiliser le module `pam_mkhomedir` pour créer un répertoire personnel pour l'utilisateur s'il n'existe pas déjà. L'option `skel` spécifie l'emplacement du répertoire squelette qui est utilisé pour remplir le nouveau répertoire personnel. L'option umask définit les autorisations sur le répertoire personnel nouvellement créé. ![](https://i.imgur.com/3Y4XrcF.png) Top 👍 ### Conclusion WIP, TBD, TShortDR