Installation d'OpenLDAP, PAM-LDAP, CCREDS et NFS
Procédure validée sur Debian 12.
Présentation du projet
Nous souhaitons créer un serveur central d'authentification et de fichiers sous Debian permettant à des clients Debian de s'y connecter pour l'authentification de leurs utilisateurs. Nous utiliserons CCREDS pour l'authentification des équipements avec mise en cache de l'annuaire (par exemple les ordinateurs portables).
Installation et configuration du serveur OpenLDAP
OpenLDAP est un annuaire informatique qui fonctionne sur le modèle client/serveur. Il contient des informations de n'importe quelle nature qui sont rangées de manière hiérarchique.
Pour bien comprendre le concept, il est souvent comparé aux Pages Jaunes (Yellowpages), où le lecteur recherche un numéro de téléphone particulier: il va d'abord sélectionner la profession, puis la ville, puis le nom de l'entrée pour trouver au final le numéro de téléphone. En pratique, il est utilisé pour enregistrer une grande quantité d'utilisateurs ou de services (parfois des centaines de milliers) dans un réseau informatique. Il permet d'organiser hiérarchiquement les utilisateurs par département, par lieu géographique ou par n'importe quel autre critère.
Source : Wikipedia
Installation des paquets
Sur le serveur, installer les paquets slapd
et ldap-utils
:
apt install slapd ldap-utils nftables
Configuration de l'annuaire
Afin de configurer l'annuaire, taper :
dpkg-reconfigure slapd
Répondez aux questions comme suit :
- Voulez-vous omettre la configuration d'OpenLDAP
- Non
- Nom de domaine
- Votre nom de domaine (exemple : mondomaine.local)
- Nom d'entité
- Votre nom de domaine (exemple : mondomaine.local)
- Mot de passe de l'administrateur
- Un mot de passe assez fort
- Faut-il supprimer la base de données à la purge du paquet
- Comme vous voulez
- Faut-il déplacer l'ancienne base de données
- Oui
Autoriser le trafic vers le serveur LDAP et en loopback en modifiant le fichier /etc/nftables.conf. Adapter selon les autres services déjà installés :
#!/usr/sbin/nft -f flush ruleset table inet tableinet { chain input { type filter hook input priority filter; policy drop; iifname lo accept tcp dport 389 accept ct state {established,related} accept } chain forward { type filter hook forward priority filter; } chain output { type filter hook output priority filter; } }
Activer et redémarrer nftables :
systemctl enable nftables.service systemctl restart nftables.service
Associer le domaine à l'IP 127.0.0.1
dans le fichier /etc/hosts :
127.0.0.1 mondomaine.local
Désactivation du compte anonyme et création du compte en lecture seule
Le compte en lecture seule aura accès au mots de passe des comptes utilisateurs. Créer le fichier lecture.ldif :
dn: cn=lecture,dc=mondomaine,dc=local objectClass: simpleSecurityObject objectClass: organizationalRole cn: lecture description: Compte lecture seule pour serveurs de messagerie userPassword: MotDePasseLectureSeule
Créez le fichier anon.ldif :
dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcAccess olcAccess: to attrs=userPassword by self write by anonymous auth by dn="cn=lecture,dc=mondomaine,dc=local" read by dn="cn=admin,dc=mondomaine,dc=local" write by * none olcAccess: to dn.base="dc=mondomaine,dc=local" by users read olcAccess: to * by self write by dn="cn=admin,dc=mondomaine,dc=local" write by * read by anonymous none
Pour activer ce module nécessaire pour la gestion des groupes, créer le fichier memberof.ldif :
dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: memberof.la
Modifiez le fichier /etc/ldap/ldap.conf comme suit :
BASE dc=mondomaine,dc=local URI ldap://mondomaine.local
Éxécutez les scripts LDIF :
ldapadd -x -H ldap://localhost -D "cn=admin,dc=mondomaine,dc=local" -f lecture.ldif -W ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f anon.ldif ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f memberof.ldif
Configuration avec SSL/TLS
Pour sécuriser les communications avec votre annuaire, il faut chiffrer les communications entre le serveur et les clients LDAP. Nous allons décrire ici comment créer des certificats auto-signés, mais il est possible d'utiliser des certificats fournis par votre autorité de certification.
Pour cela, nous allons installer OpenSSL :
apt install openssl
Création d'une autorité de certification auto-signée
Nous allons créer l'arborescence qui accueillera les clefs et certificats :
mkdir -p /etc/ssl/openldap/{private,certs}
Créer la clef privée de l'autorité de certification :
openssl genrsa -out /etc/ssl/openldap/private/ca.key 4096
Créer le certificat de l'autorité de certification :
openssl req -new -x509 -days 3650 -key /etc/ssl/openldap/private/ca.key -out /etc/ssl/openldap/certs/ca.crt
Pour créer la clef privée utilisée par le serveur LDAP :
openssl genrsa -out /etc/ssl/openldap/private/openldap.key 4096
Nous allons générer la requête de certificat pour le serveur LDAP. Renseigner le nom de domaine de la machine dans le champ CN :
openssl req -new -key /etc/ssl/openldap/private/openldap.key -out /etc/ssl/openldap/certs/openldap.csr
Signer la demande de certificat avec la clef privée de l'autorité de certification :
openssl x509 -req -CA /etc/ssl/openldap/certs/ca.crt -CAkey /etc/ssl/openldap/private/ca.key -in /etc/ssl/openldap/certs/openldap.csr -out /etc/ssl/openldap/certs/openldap.crt -CAcreateserial
Changer le propriétaire des fichiers générés précédement :
chown -R openldap:openldap /etc/ssl/openldap/
Configuration d'OpenLDAP pour utiliser les certificats
Créer le fichier ssl.ldif :
dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/openldap/certs/ca.crt - replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/openldap/certs/openldap.crt - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/openldap/private/openldap.key
Éxécutez le script LDIF :
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f ssl.ldif
Définir le chemin du certificat de l'autorité de certification dans /etc/ldap/ldap.conf :
URI ldaps://mondomaine.local TLS_CACERT /etc/ssl/openldap/certs/ca.crt
Autoriser le trafic LDAPS en modifiant la ligne suivante dans /etc/default/slapd. Pour n'autoriser que le trafic LDAPS, supprimer le service ldap:///
:
SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
Redémarrer le serveur LDAP :
service slapd restart
Autoriser le trafic vers le serveur en LDAPS et en loopback en modifiant le fichier /etc/nftables.conf. Adapter selon les autres services déjà installés :
#!/usr/sbin/nft -f flush ruleset table inet tableinet { chain input { type filter hook input priority filter; policy drop; iifname lo accept tcp dport 636 accept ct state {established,related} accept } chain forward { type filter hook forward priority filter; } chain output { type filter hook output priority filter; } }
Activer et redémarrer nftables :
systemctl enable nftables.service systemctl restart nftables.service
Tester la connexion :
ldapwhoami -H ldaps://mondomaine.local -x -D "cn=admin,dc=mondomaine,dc=local" -W
Peuplement de l'annuaire
Deux choix s'offrent à nous :
- Peupler à l'aide d'un script LDIF
- Peupler à l'aide d'un script Python
Les deux exemples ci-dessous créent les mêmes objets dans la base LDAP :
- Un OU (organizational unit) pour stocker les utilisateurs
- Un OU (organizational unit) pour stocker les groupes
- Un utilisateur
- Un groupe POSIX destiné à être administrateur sur les clients
Peuplement avec un script LDIF
Voici un script LDIF permettant de créer les éléments. Chaque objet doit être séparé du précédent avec une ligne vide.
Pour générer le hash salé du mot de passe utilisateur, utiliser la commande slappasswd
.
Pour cela, créer le fichier peuplement.ldif :
dn: ou=Utilisateurs,dc=mondomaine,dc=local objectClass: organizationalUnit ou: Utilisateurs dn: cn=pdubois,ou=Utilisateurs,dc=mondomaine,dc=local objectClass: top objectClass: inetOrgPerson objectClass: posixAccount cn: Paul Dubois userPassword: {SSHA}lIE//AggDjIfUXCR0s/Yox2oi3ddokFP sn: Dubois givenname: Paul uidNumber: 1200 gidNumber: 1200 homeDirectory: /home/pdubois uid: pdubois mail: pdubois@mondomaine.local loginShell: /bin/bash dn: ou=Groupes,dc=mondomaine,dc=local objectClass: organizationalUnit ou: Groupes dn: cn=admins,ou=Groupes,dc=mondomaine,dc=local objectClass: top objectClass: posixGroup cn: admins gidNumber: 1100 description: Groupe des administrateurs memberUid: pdubois
Peupler l'annuaire avec la commande suivante :
ldapadd -x -D "cn=admin,dc=mondomaine,dc=local" -f peuplement.ldif -W
Peuplement avec un script Python
Nous allons ajouter une librairie au serveur :
apt install python3-ldap
Voici le code permettant de se connecter à l'annuaire (remplacer par vos valeurs) :
import ldap,os,hashlib from base64 import encodebytes as encode from base64 import decodebytes as decode import ldap.modlist as modlist dc="dc=mondomaine,dc=local" l = ldap.initialize('ldaps://mondomaine.local') l.simple_bind_s("cn=admin," + dc,"MotDePasseLdap")
Le code permettant d'ajouter les OU (organizational unit) :
dn="ou=Utilisateurs," + dc attrs = {} attrs['objectclass'] = [b"organizationalUnit"] attrs['ou'] = [b"Utilisateurs"] ldif = modlist.addModlist(attrs) l.add_s(dn,ldif) dn="ou=Groupes," + dc attrs = {} attrs['objectclass'] = [b"organizationalUnit"] attrs['ou'] = [b"Groupes"] ldif = modlist.addModlist(attrs) l.add_s(dn,ldif)
Voici le code pour hacher le mot de passe :
def makeSecret(password): salt = os.urandom(4) h = hashlib.sha1(password.encode('utf-8')) h.update(salt) salted = (encode(h.digest() + salt)[:-1]).decode('utf-8') return("{SSHA}" + salted)
Le code permettant d'ajouter un utilisateur :
dn="cn=pdubois,ou=Utilisateurs," + dc attrs = {} attrs['objectclass'] = [b"top",b"inetOrgPerson",b"posixAccount"] attrs['cn'] = [b"Paul Dubois"] attrs['userPassword'] = makeSecret("MonMotDePasseSuperSecurise").encode('utf-8') attrs['sn'] = [b"Dubois"] attrs['givenname'] = [b"Paul"] attrs['uidNumber'] = [b"1200"] attrs['gidNumber'] = [b"1200"] attrs['homeDirectory'] = [b"/home/pdubois"] attrs['uid'] = [b"pdubois"] attrs['mail'] = [b"pdubois@mondomaine.local"] attrs['loginShell'] = [b"/bin/bash"] ldif = modlist.addModlist(attrs) l.add_s(dn,ldif)
Le code permettant d'ajouter un groupe :
dn="cn=admins,ou=Groupes," + dc attrs = {} attrs['objectclass'] = [b"top",b"posixGroup"] attrs['cn'] = [b"admins"] attrs['gidNumber'] = [b"1100"] attrs['description'] = [b"Groupe des administrateurs"] attrs['memberUid'] = [b"pdubois"] ldif = modlist.addModlist(attrs) l.add_s(dn,ldif)
Tester le peuplement du LDAP :
print(l.search_s(dc,ldap.SCOPE_SUBTREE,'(cn=pdubois)',['dn','objectclass','userPassword']))
Configurer un annuaire LDAP multi-domaines
Pour créer plusieurs bases dans un annuaire LDAP, créer un fichier creation-db.ldif décrivant les autres domaines. Voici un exemple créant deux bases supplémentaires :
dn: olcDatabase={2}mdb,cn=config # Incrémenter le nombre à chaque nouvelle base changetype: add objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb olcDbMaxSize: 1073741824 olcDbCheckpoint: 512 30 olcLastMod: TRUE olcSuffix: dc=mondeuxiemedomaine,dc=local olcDbDirectory: /var/lib/ldap-mondeuxiemedomaine-local # Le répertoire où sera stockée la base olcRootDN: cn=admin,dc=mondeuxiemedomaine,dc=local olcRootPW: {SSHA}wpGpcAKFTpUTBigFzIs2T2dwlhz3KRaZ # Le mot de passe admin obtenu avec slappasswd olcDbIndex: objectClass eq olcDbIndex: cn,uid eq olcDbIndex: uidNumber,gidNumber eq olcDbIndex: member,memberUid eq olcAccess: to attrs=userPassword by self write by anonymous auth by * none olcAccess: to attrs=shadowLastChange by self write by * read olcAccess: to * by * read dn: olcDatabase={3}mdb,cn=config changetype: add objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb olcDbMaxSize: 1073741824 olcDbCheckpoint: 512 30 olcLastMod: TRUE olcSuffix: dc=montroisiemedomaine,dc=local olcDbDirectory: /var/lib/ldap-montroisiemedomaine-local olcRootDN: cn=admin,dc=montroisiemedomaine,dc=local olcRootPW: {SSHA}wpGpcAKFTpUTBigFzIs2T2dwlhz3KRaZ olcDbIndex: objectClass eq olcDbIndex: cn,uid eq olcDbIndex: uidNumber,gidNumber eq olcDbIndex: member,memberUid eq olcAccess: to attrs=userPassword by self write by anonymous auth by * none olcAccess: to attrs=shadowLastChange by self write by * read olcAccess: to * by * read
Appliquer les changements :
ldapmodify -Y EXTERNAL -H ldapi:/// -f creation-db.ldif
Configuration du client LDAP
Le serveur LDAP peut également être client de lui-même pour l'authentification.
Sur les clients, installer les paquets suivants :
apt install libpam-ldapd libnss-ldapd nscd
Réponder aux questions comme suit :
- L'URI du serveur LDAP
ldaps://mondomaine.local
- Base de recherche du serveur LDAP
ou=Utilisateurs,dc=mondomaine,dc=local
- Contrôle du certificat SSL du serveur
- Autoriser
- Service de nom à configurer
group
,shadow
etpasswd
Paramétrer le compte en lecture seule dans le fichier /etc/nslcd.conf :
binddn cn=lecture,dc=mondomaine,dc=local bindpw MotDePasseLectureSeule
Finaliser la configuration en entrant :
pam-auth-update
On vous demandera quels modules activer, ajouter LDAP Authentication et Create home directory on login et valider.
Définir l'URI du serveur LDAP le chemin du certificat de l'autorité de certification dans /etc/ldap/ldap.conf :
URI ldaps://mondomaine.local TLS_CACERT /etc/ssl/openldap/certs/ca.crt
Pour ajouter un groupe parmi les administrateurs du client (sudoers), ajouter au fichier /etc/sudoers avant la directive @includedir
:
%admins ALL=(root) ALL
Permettre l'association des groupes LDAP aux droits sudo en ajoutant la ligne suivante au fichier /etc/nsswitch.conf :
sudoers: ldap files
Redémarrer les services nscd et nslcd :
service nscd restart service nslcd restart
Tester le bon fonctionnement avec getent
:
getent passwd getent group
Pour un client graphique, configurer LightDM en ajoutant ce qui suit au fichier de configuration /etc/lightdm/lightdm.conf :
[Seat:*] allow-guest=false greeter-hide-users=true greeter-show-manual-login=true
Configuration pour un usage hors ligne (ordinateur portable)
Installer le module PAM CCREDS :
apt install libpam-ccreds
Nous allons allonger la durée du cache NSS. Pour cela, modifier le fichier /etc/nscd.conf pour augmenter la durée du cache à 30 jours :
positive-time-to-live passwd 2592000 positive-time-to-live group 2592000
Redémarrer les services nscd et nslcd :
service nscd restart service nslcd restart
Une première connexion avec le réseau connecté est nécessaire pour mettre en cache les identifiants.
Vous pouvez vérifier le cache des identifiants avec la commande suivante :
cc_dump
Installation et configuration du serveur NFS
Network File System (ou 'NFS', système de fichiers en réseau) est à l'origine un protocole développé par Sun Microsystems en 1984 qui permet à un ordinateur d'accéder à des fichiers via un réseau. Il fait partie de la couche application du modèle OSI et utilise le protocole RPC.
Ce système de fichiers en réseau permet de partager des données principalement entre systèmes UNIX. Des versions existent pour Macintosh ou Microsoft Windows.
NFS est compatible avec IPv6 sur la plupart des systèmes.
Source : Wikipedia
Installation des paquets
Sur le serveur, installer le paquet nfs-kernel-server
:
apt-get install nfs-kernel-server
Configurer le serveur NFS
Définir le port d'écoute du serveur NFS en éditant la ligne suivante dans le fichier /etc/default/nfs-kernel-server :
RPCMOUNTDOPTS="--manage-gids -p 892"
Éditer le fichier /etc/exports :
/home/ 192.168.1.0/24(rw,sync)
Redémarrer le service NFS pour prendre en compte de vos modifications :
service nfs-kernel-server restart
Autoriser le trafic vers le serveur LDAP et en loopback en modifiant le fichier /etc/nftables.conf. Adapter selon les autres services déjà installés :
#!/usr/sbin/nft -f flush ruleset table inet tableinet { chain input { type filter hook input priority filter; policy drop; iifname lo accept tcp dport 2049 accept tcp dport 111 accept tcp dport 892 accept udp dport 2049 accept udp dport 111 accept udp dport 1194 accept udp sport 1194 accept ct state {established,related} accept } chain forward { type filter hook forward priority filter; } chain output { type filter hook output priority filter; } }
Activer et redémarrer nftables :
systemctl enable nftables.service systemctl restart nftables.service
Configurer le client NFS
Nous allons installer le module NFS sur le client :
apt-get install nfs-common
Puis effectuons le point de montage. Pour cela, éditer le fichier /etc/fstab et y ajouter la ligne suivante :
192.168.1.100:/home/ /home nfs defaults 0 0