---
# System prepended metadata

title: TP LDAP

---

<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