Samba AD DC - Partage NFSv4 avec authentification Kerberos
Le partage de données se fait communément avec le protocole SMB (Server Message Block). Ce protocole a l'avantage d'être supporté par l'ensemble des plate-formes (Windows, Apple, Linux, Unix).
Une alternative à celui-ci est NFS (Network File System) qui, historiquement, est le protocole de partage de données dans le monde Unix et plus tard Linux. Ces trois premières versions manquaient cruellement de sécurité. La quatrième version apporte des éléments de sécurité concrets dont :
- L'authentification des intervenants qui a pour but de vérifier l'identité de la personne ou de la machine avec qui l'on communique.
- La signature des communications qui a pour but de détecter si la communication a été modifiée entre son émission et sa réception.
- Le chiffrement des communications qui a pour but d'empêcher la compréhension de la communication si elle est interceptée.
Prérequis
- Avoir un contrôleur de domaine Samba AD (ou son équivalent Windows) →Se référer à Samba - Active Directory Domain Controller (AD DC)
- Avoir deux machines dans ce domaine →Se référer à Samba AD DC - Intégration de machines au domaine
- Avoir une connaissance de NFS →Se référer à NFS
Paramètres
Pour cette documentation, les paramètres suivants seront utilisés 1)
Nom de domaine | Royaume (realm) |
---|---|
example.com | EXAMPLE.COM |
Nom de machine | Adresse IP | Role |
---|---|---|
ubndc01 | 192.0.2.11 | Contrôleur de domaine |
ubnfs01 | 192.0.2.12 | Serveur de fichier |
ubnws01 | 192.0.2.13 | Machine client |
Le répertoire partagé sera le répertoire /media/home/example présent sur le serveur de fichier et contenant les répertoires home des utilisateurs du domaine. Ce répertoire sera monté sur chaque machine du domaine afin de permettre à chaque utilisateur d'accéder à son répertoire home depuis n'importe quelle machine du domaine.
Quelques notions à propos de Kerberos
Le User Principal Name (UPN) est un identifiant unique pour l'identité de sécurité d'un utilisateur ou d'un ordinateur. Il existe deux type d'UPN
- L' iUPN (implicit UPN) constitué de l'attribut samAccountName@<REALM>
- L' eUPN (explicit UPN) défini par l'attribut userPrincipalName.
Dans le cas où deux objets auraient leur eUPN et iUPN en commun, l' eUPN a une priorité supérieure.
Le Service Principal Name (SPN) est un identifiant unique pour un service tournant sur un ordinateur. Il prend la forme <service>/<hostname>:<port>/<service_name>@<REALM> avec le champ hostname qui peut être juste le nom de l'ordinateur ou son nom pleinement qualifié (FQDN). Les champs port et service_name sont optionnels.
Un UPN permet de demander un ticket au serveur Kerberos afin de communiquer avec un SPN. Par défaut, les objets 'utilisateur' d'Active Directory possède un UPN. Mais, les objets 'ordinateur' d'Active Directory n'en possède pas par défaut. Dans le cadre de SSH, c'est l'utilisateur qui établit la communication avec le service distant. Dans le cadre de NFS avec Kerberos, c'est l'ordinateur qui établit la communication avec le service distant.
Configuration du serveur de fichier
Installation du serveur NFS
L'installation de NFS se fait avec le paquet nfs-kernel-server
sudo apt-get install nfs-kernel-server
Définition des partages NFS
Avant de faire fonctionner NFS, il faut préparer le partage. NFSv4 base son partage sur une racine virtuelle définie. Bien qu'il soit possible d'utiliser des répertoires déjà existants, il est recommandé d'en créer un à la racine du système de fichier, par exemple /export. Ensuite pour chaque répertoire qui sera partagé, il faut créer un sous répertoire dans la structure NFS, par exemple /export/home/example.
sudo mkdir -p /export/home/example
A ce stade, les données partagées le seraient sur la partition Root ce qui n'est pas une bonne pratique. Afin de ne pas modifier le reste du serveur de fichier, il faut procéder à la jonction du répertoire /export/home/example avec le répertoire qui contiendra réellement les données, /home/example. Dans le cas où le répertoire contenant les données représente une partition entière, la partition peut alors être directement montée sur la structure NFS.
En ligne de commande
sudo mount --bind /home/example /export/home/example
Ou en ajoutant une ligne dans le fichier /etc/fstab pour que l'opération soit effectuée à chaque redémarrage
- /etc/fstab
# Export NFS4 /home/example /export/home/example none bind 0 0
Cette structure de répertoires sous /export doit être considérée comme une structure virtuelle permettant le fonctionnement de NFS et non pas comme une structure pour le stockage de fichiers directement. Ainsi, l'impact en espace disque sur la partition Root est quasi nul.
La configuration des partages se fait au travers du fichier /etc/exports
- /etc/exports
/export 192.0.2.0/24(ro,sync,fsid=0,no_subtree_check,crossmnt,sec=krb5) /export/home/example 192.0.2.0/24(rw,sync,no_subtree_check,sec=krb5)
La première ligne avec l'option fsid=0 (ou fsid=root) définit la racine virtuelle du système de fichiers partagés. Il n'y a aucune nécessité de donner des droits d'écriture sur cette racine. Tous les fichiers et répertoires sous /export sont accessibles par le partage NFS.
L'option sec=krb5 définit le niveau de sécurité exigé. Il en existe 3:
- krb5: Authentification Kerberos
- krb5i: Authentification Kerberos avec signature des communications (i pour integrity)
- krb5p: Authentification Kerberos avec chiffrement des communications (p pour privacy)
Lancement du service NFS
A ce stade, le démarrage du serveur NFS ne devrait pas encore fonctionner.
sudo service nfs-kernel-server start * Exporting directories for NFS kernel daemon... [ OK ] * Starting NFS kernel daemon [fail]
Afin de remédier au problème, il faut avant tout l'identifier correctement. Et pour ce faire, il faut accéder aux logs (fichiers d'historique d’événements).
- /var/log/syslog
Oct 6 18:13:26 ubnfs01 rpc.svcgssd[25763]: unable to obtain root (machine) credentials Oct 6 18:13:26 ubnfs01 rpc.svcgssd[25763]: do you have a keytab entry for nfs/<your.host>@<YOUR.REALM> in /etc/krb5.keytab?
Le service n'arrive pas à démarrer parce qu'il ne trouve pas son SPN (Service Principal Name) dans le fichier keytab par défaut (/etc/krb5.keytab) qui, par défaut, serait nfs/ubnfs01.example.com@EXAMPLE.COM. Plus clairement, le service ne trouve pas son identité afin de s'authentifier. Pour modifier le fichier keytab, il faut utiliser l'outil net avec les commandes ads keytab. Il faut également avoir les droits super-utilisateurs. Pour rappel, vu l'importance de ce fichier, les permissions sur celui-ci sont très restrictives root:root 600. Seul l'utilisateur root peut y accéder en lecture et écriture. Il faut également interagir avec le serveur Kerberos présent sur le DC. Pour cela, la meilleure façon de procéder consiste à s'authentifier avec un compte administrateur du domaine à chaque commande avec l'option -U Administrator.
sudo net ads keytab add nfs -U Administrator Enter Administrator's password: sudo net ads keytab list Vno Type Principal 6 des-cbc-crc host/ubnfs01.example.com@EXAMPLE.COM ... 6 arcfour-hmac-md5 UBNFS01$@EXAMPLE.COM 6 des-cbc-crc nfs/ubnfs01.example.com@EXAMPLE.COM ... 6 arcfour-hmac-md5 nfs/ubnfs01@EXAMPLE.COM
La commande add <service> ajoute deux SPN au fichier keytab (un pour le hostname et un pour le fqdn). Parallèlement, deux attributs 'servicePrincipalName' sont ajoutés à l'object Active Directory représentant l'ordinateur (ubnfs01) (<service>/<hostname> et <service>/<fqdn>)..
La commande list liste les UPN et SPN présents dans le fichier keytab.
La commande flush vide le fichier keytab et supprime l'ensemble des SPN associés à la machine.
La commande create crée le fichier keytab par défaut avec l'iUPN et l'eUPN, si l'attribut userPrincipalName a été définit, et les SPN host/<hostname>@<REALM> et host/<fqdn>@<REALM>.
Conseils
Le service nfs-kernel-server lorsqu'il démarre va lire le fichier de configuration /etc/default/nfs-kernel-server. Par défaut, il ne faut rien y changer. Cependant, si l'on veut augmenter la quantité d'informations envoyées dans le fichier log. On peut ajouter l'option "très bavard" au démon rpc.svcgssd (responsable de l'authentification de la machine vis-à-vis du serveur Kerberos)
- /etc/default/nfs-kernel-server
RPCSVCGSSDOPTS="-vvv"
De façon plus générale, la page de manuel du démon rpc.svcgssd propose d'autres options plus avancées.
Configuration de la machine cliente
Installation du client NFS
L'installation du client NFS se fait avec le paquet nfs-common
sudo apt-get install nfs-common
Montage du partage
Le partage se monte avec la commande mount et le type nfs4 qui va rediriger l'appel vers la commande spécifique mount.nfs4. Afin de test l'accès au partage, le partage sera monté sur /mnt/test au lieu de /home/example.com
sudo mount -t nfs4 -o sec=krb5 ubnfs01.example.com:/home/example /home/example
L'option sec=krb5 précise que le montage se fera avec authentification Kerberos.
Erreurs et solutions
Le résultat de la commande mount ci-dessus devrait être : "Access denied by server while mounting ubnfs01.example.com:/home/example"
Les raisons sont multiples et vont être parcourues ci-après
Activation du démon rpc.gssd
Le démon rpc.gssd est responsable de l'authentification par Kerberos. Il faut donc le démarrer manuellement (via son script Upstart, /etc/init/gssd.conf)
sudo start gssd
Ou de façon automatique en modifiant le fichier /etc/default/nfs-common
- /etc/default/nfs-common
NEED_GSSD="yes"
A la lecture du script Upstart du démon rpc.gssd, on constate que ce démon va charger plusieurs modules dont rpcsec_gss_krb5 et que si le fichier /etc/fstab contient une ligne avec une option du type sec=krb5, le démon sera automatiquement démarré.
Afin de faciliter le dépannage en cas de problème avec ce démon, il est possible d'activer son mode "très, très bavard" avec l'option "-vvv".
sudo stop gssd sudo rpc.gssd -vvv
La page de manuel de ce démon liste d'autres options plus avancées.
DNS inversé
Dans le fichier log, on identifie vite le problème
- /var/log/syslog
Oct 6 22:09:42 ubnws01 rpc.gssd[3609]: ERROR: unable to resolve 192.0.2.12 to hostname: Name or service not known Oct 6 22:09:42 ubnws01 rpc.gssd[3609]: ERROR: failed to read service info
La cause est l'absence de résolution inverse sur le serveur DNS (également fournit par Samba AD DC). Pour y remédier, il faut ajouter la zone 2.0.192.in-addr.arpa et le pointeur ubnfs01.example.com pour l'adresse 12
samba-tool dns zonecreate ubndc01 2.0.192.in-addr.arpa Zone 2.0.192.in-addr.arpa created successfully samba-tool dns add ubndc01 2.0.192.in-addr.arpa 12 PTR ubnfs01.example.com Record added successfully
La commande samba-tool utilise le ticket kerberos de l'utilisateur pour réaliser ces opérations. Si l'utilisateur n'a pas de ticket Kerberos, il peut utiliser l'option -U Administrator.
A cause du Bug 9404 de Samba 4, la zone fraîchement créée n'est pas automatiquement chargée par le serveur DNS interne de Samba. Il faut redémarrer le service samba-ad-dc sur le contrôleur de domaine.
ssh ubndc01 ... sudo service samba-ad-dc restart samba-ad-dc stop/waiting samba-ad-dc start/running, process 11129 exit
Absence d'identité
Le démon rpc.gssd va chercher une identité dans le fichier /etc/krb5.keytab pour s'authentifier vis-à-vis du serveur Kerberos. Il essaie premièrement l'UPN de l'ordinateur <FQDN$>@<REALM> et ensuite les SPN root/<fqdn>@<REALM>, nfs/<fqdn>@<REALM> et host/<fqdn>@<REALM>.
- /var/log/syslog
Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: No key table entry found for UBNWS01.EXAMPLE.COM$@EXAMPLE.COM while getting keytab entry for 'UBNWS01.EXAMPLE.COM$@EXAMPLE.COM' Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: No key table entry found for root/ubnws01.example.com@EXAMPLE.COM while getting keytab entry for 'root/ubnws01.example.com@EXAMPLE.COM' Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: No key table entry found for nfs/ubnws01.example.com@EXAMPLE.COM while getting keytab entry for 'nfs/ubnws01.example.com@EXAMPLE.COM' Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: No key table entry found for host/ubnws01.example.com@EXAMPLE.COM while getting keytab entry for 'host/ubnws01.example.com@EXAMPLE.COM' Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: ERROR: gssd_refresh_krb5_machine_credential: no usable keytab entry found in keytab /etc/krb5.keytab for connection with host ubnfs01.example.com Oct 7 20:17:08 ubnws01 rpc.gssd[6173]: ERROR: No credentials found for connection to server ubnfs01.example.com
Normalement, s'il a été crée, le fichier /etc/krb5.keytab contient le bien le SPN <host>/<fqdn>@<REALM>. L'erreur devient alors
- /var/log/syslog
Oct 7 22:16:44 ubnws01 rpc.gssd[6173]: Success getting keytab entry for 'host/ubnws01.example.com@EXAMPLE.COM' Oct 7 22:16:44 ubnws01 rpc.gssd[6173]: WARNING: Client 'host/ubnws01.example.com@EXAMPLE.COM' not found in Kerberos database while getting initial ticket for principal 'host/ubnws01.example.com@EXAMPLE.COM' using keytab 'FILE:/etc/krb5.keytab' Oct 7 22:16:44 ubnws01 rpc.gssd[6173]: ERROR: No credentials found for connection to server ubnfs01.example.com
Le démon rpc.gssd est multi-usage. Dans le cas de NFSv4 avec Kerberos, il a besoin de l'UPN de l'ordinateur (cfr Notions Kerberos). Le fichier /etc/krb5.keytab possède déjà l' iUPN (<HOSTNAME$>@<REALM>) mais le démon rpc.gssd recherche l'UPN <FQDN$>@<REALM>. Il faut donc ajouter l' eUPN équivalent à l'objet représentant la machine cliente dans l'Active Directory. Ceci consiste à ajouter l'attribut 'userPrincipalName' avec la valeur <FQDN$>@<REALM>. Il y a une multitude de façon de procéder :
- Utiliser une machine Windows dans le domaine avec les outils d'administrations pour Active Directory.
- Utiliser un logiciel avec une interface graphique proche de ce que Windows propose, par exemple Apache Directory Studio, qui n'est pas inclus dans la distribution Ubuntu.
- Utiliser les outils LDAP
ldapmodify -H ldap://ubndc01.example.com -U Administrator << EOF dn: cn=ubnws01,cn=computers,dc=example,dc=com changetype: modify add: userPrincipalName userPrincipalName: UBNWS01.EXAMPLE.COM\$@EXAMPLE.COM EOF
Cette méthode ne modifie pas les identités existantes de la machine. On peut alors ajouter la nouvelle identité (eUPN) au fichier keytab avec la commande
sudo net ads keytab add UBNWS01.EXAMPLE.COM\$ -U Administrator
- Utiliser la commande net ads join qui sert à joindre la machine au domaine.
sudo net ads join createupn=UBNWS01.EXAMPLE.COM\$@EXAMPLE.COM -U Administrator
sudo net ads keytab flush -U Administrator sudo net ads keytab create -U Administrator
Eureka
Après avoir résolu ces quelques problèmes, il est possible de monter le partage NFS et d'y accèder.
Automatisation
Deux approches sont possibles pour l'automatisation du montage des partages NFS.
- Ajouter une ligne dans le fichier /etc/fstab
- Utiliser autofs
La première possibilité implique que la machine doit avoir une connectivité réseau avant de procéder au montage. C'est typiquement le cas des serveurs mais pas des machines de bureau (fixes ou portables). De plus, il y a la problématique de la gestion des ressources. En effet, chaque partage monté consomme des ressources sur la machine cliente mais surtout sur la machine serveur. La seconde possibilité apporte donc une solution à ces deux problèmes.
Mise en oeuvre avec /etc/fstab
- /etc/fstab
ubnfs01:/home/example /home/example nfs4 sec=krb5 0 0
Mise en oeuvre sur base de autofs
Installation du paquet autofs
sudo apt-get install autofs
Ajout d'une entrée dans le fichier maître /etc/auto.master
- /etc/auto.master
/home/example /etc/auto.home --timeout=90
Définition de la règle auto.home
- /etc/auto.home
* -fstype=nfs4,sec=krb5 ubnfs01.example.com:/home/example/&
En résumé
Sur le serveur DNS
Créer une zone DNS inversé
samba-tool dns zonecreate ubndc01 2.0.192.in-addr.arpa Zone 2.0.192.in-addr.arpa created successfully
Ajouter un pointeur vers le serveur de fichier
samba-tool add ubndc01 2.0.192.in-addr.arpa 12 PTR ubnfs01.example.com Record added successfully
Redémarrer le contrôleur de domaine pour pallier au Bug 9404
ssh ubndc01 sudo service samba-ad-dc restart exit
Sur le serveur de fichier
Installation du paquets NFS server
sudo apt-get install nfs-kernel-server
Création de la structure de répertoire pour NFS
sudo mkdir -p /export/home/example
Jonction du répertoire réel avec la structure NFS
- /etc/fstab
# Export NFS4 /home/example /export/home/example none bind 0 0
sudo mount /export/home/example
Ajout du SPN dans le keytab
sudo net ads keytab add nfs -U Administrator
Lancement du service
sudo service nfs-kernel-server start
Sur les clients NFS
Installation du paquet NFS client
sudo apt-get install nfs-common
S'il n'est pas déjà définit dans l'Active Directory, définir l'eUPN de l'ordinateur
ldapmodify -H ldap://ubndc01.example.com -U Administrator << EOF dn: cn=ubnws01,cn=computers,dc=example,dc=com changetype: modify add: userPrincipalName userPrincipalName: UBNWS01.EXAMPLE.COM\$@EXAMPLE.COM EOF
S'il n'est pas déjà présent dans le fichier /etc/krb5.keytab, ajouter l'eUPN au fichier
sudo net ads keytab add UBNWS01.EXAMPLE.COM\$ -U Administrator
Monter la ressource partagée manuellement
sudo mount -t nfs4 -o sec=krb5 ubnfs01.example.com:/home/example /home/example
Ou automatiquement (cfr Automatisation)
Références
Contributeur principal : Qedinux