Installation d'OpenLDAP, PAM-LDAP, CCREDS, NFS et DHCP
Procédure validée sur Debian 13.
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
Ajouter l'overlay memberOf à la base de données. Pour cela, créer le fichier memberof-overlay.ldif :
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOf
objectClass: olcConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
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 ldapadd -Y EXTERNAL -H ldapi:/// -f memberof-overlay.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 :
systemctl restart slapd.service
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;
}
}
Redémarrer nftables :
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
- Un groupe groupOfNames (pour être vu comme memberOf lors d'une recherche)
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
dn: cn=monGroupe,ou=Groupes,dc=mondomaine,dc=local
objectClass: groupOfNames
objectClass: top
cn: monGroupe
description: Groupe utilisateur générique
member: cn=pdubois,ou=Utilisateurs,dc=mondomaine,dc=local
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,shadowetpasswd
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 :
systemctl restart nscd.service systemctl restart nslcd.service
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 :
systemctl restart nscd.service systemctl restart nslcd.service
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 install nfs-kernel-server
Configurer le serveur NFS
Fixer les ports NFS en modifiant le fichier /etc/nfs.conf :
[general] pipefs-directory=/run/rpc_pipefs [lockd] port=32768 udp-port=32768 [mountd] manage-gids=y port=32767 [statd] port=32765 outgoing-port=32766
É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 :
systemctl restart nfs-kernel-server.service
Autoriser le trafic vers le serveur NFS 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 111 accept
udp dport 111 accept
tcp dport 2049 accept
udp dport 2049 accept
tcp dport {32765,32768} accept
udp dport {32765,32768} 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
Installation et configuration du serveur DHCP
Cette configuration permet d'héberger les configurations et les baux statiques du serveur DHCP au sein de l'annuaire LDAP. Pour cela, nous allons installer les paquets nécessaires :
apt install isc-dhcp-server isc-dhcp-server-ldap schema2ldif
Autoriser le trafic vers le serveur DHCP, 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
udp dport 67 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;
}
}
Redémarrer nftables :
systemctl restart nftables.service
Ajouter les schemas associés au DHCP au serveur LDAP :
zcat /usr/share/doc/isc-dhcp-server-ldap/dhcp.schema.gz > dhcp.schema schema2ldif dhcp.schema > dhcp.ldif ldapadd -Q -Y EXTERNAL -H ldapi:/// -f dhcp.ldif
Ajout des index. Pour cela, créer le fichier index.ldif :
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: dhcpHWAddress eq
-
add: olcDbIndex
olcDbIndex: dhcpClassData eq
Appliquer les changements :
ldapmodify -Y EXTERNAL -H ldapi:/// -f index.ldif
Configuration du serveur DHCP
Nous allons créer la configuration du service DHCP en créant le fichier service.ldif :
dn: ou=Services,dc=mondomaine,dc=local objectClass: organizationalUnit ou: Services dn: cn=dhcpServer,ou=Services,dc=mondomaine,dc=local cn: dhcp objectClass: top objectClass: dhcpServer dhcpServiceDN: cn=dhcpConfig,ou=Services,dc=mondomaine,dc=local dn: cn=dhcpConfig,ou=Services,dc=mondomaine,dc=local cn: dhcpConfig objectClass: top objectClass: dhcpService dhcpPrimaryDN: cn=dhcpServer,ou=Services,dc=mondomaine,dc=local dhcpStatements: ddns-update-style none dhcpStatements: get-lease-hostnames true dhcpStatements: use-host-decl-names true
Appliquer les changements :
ldapadd -x -D "cn=admin,dc=mondomaine,dc=local" -f service.ldif -W
Configurer le serveur DHCP à se connecter au serveur LDAP en ajoutant les lignes suivantes au fichier /etc/dhcp/dhcpd.conf Utilisez l'IP du serveur LDAP et non son domaine :
ldap-server "127.0.0.1"; ldap-port 636; ldap-ssl ldaps; ldap-base-dn "ou=Services,dc=mondomaine,dc=local"; ldap-dhcp-server-cn "dhcpServer"; ldap-method dynamic; ldap-debug-file "/var/log/dhcp-ldap-debug.log"; ldap-username "cn=lecture,dc=mondomaine,dc=local"; ldap-password "MotDePasseLectureSeule"; ldap-tls-reqcert never;
Redémarrer le service :
systemctl restart isc-dhcp-server.service
Configuration d'un sous-réseau
Pour ajouter un sous-réseau à la configuration DHCP, créer le fichier subnet.ldif :
dn: cn=192.168.1.0,cn=dhcpConfig,ou=Services,dc=mondomaine,dc=local cn: 192.168.1.0 objectClass: top objectClass: dhcpSubnet objectClass: dhcpOptions dhcpNetMask: 24 dhcpRange: 192.168.1.100 192.168.1.200 dhcpOption: routers 192.168.1.1 dhcpOption: domain-name-servers 192.168.1.1 dhcpOption: subnet-mask 255.255.255.0
Appliquer les changements :
ldapadd -x -D "cn=admin,dc=mondomaine,dc=local" -f subnet.ldif -W
Configuration d'un bail statique
Pour ajouter un bail statique, créer le fichier lease.ldif :
dn: cn=pcAntoine,cn=dhcpConfig,ou=Services,dc=mondomaine,dc=local cn: pcAntoine objectClass: top objectClass: dhcpHost dhcpHWAddress: ethernet 01:23:45:67:89:ab dhcpStatements: fixed-address 192.168.1.10
Appliquer les changements :
ldapadd -x -D "cn=admin,dc=mondomaine,dc=local" -f lease.ldif -W