Comment uniformiser un réseau local avec NFS + Kerberos + LDAP

posted Jul 15, 2012, 6:16 PM by Olivier Diotte   [ updated Jul 17, 2013, 9:43 PM ]
Note: cet article est, à l'heure actuelle et ce, jusqu'à ce que que cette notice soit retirée, une ébauche incomplète à utiliser à vos risques et périls. Je ne la publie en l'état que parce qu'il m'a été demandé de le faire.
Ceci étant dit, tout commentaire est apprécié, particulièrement si un passage est faux ou ne fonctionne plus avec des versions récentes des logiciels. Vous pouvez faire parvenir ces commentaires par courriel à [mon prénom ici] at diotte.ca .
-- Olivier Diotte



Je me documente présentement sur comment configurer mon réseau local afin de le rendre plus uniforme, voici mon journal de bord documentant le processus. Peut-être cette page sera-t-elle utile à d'autres.

À l'heure actuelle, un seul ordinateur est utilisé et configuré avec les comptes des utilisateurs du réseau (i.e.: les membres de ma famille).
Tous les comptes utilisateur/groupes sont donc stocké dans les fichiers /etc/passwd, /etc/shadow et /etc/group.

Étant fréquemment à bonne distance du site pendant des périodes prolongées, j'ai pu me rendre compte de la difficulté de gérer le compromis entre stabilité et mise à jour régulières (vers les nouvelles versions d'Ubuntu, les postes utilisateur tournant sous ce système). Pour remédier à ce problème, j'ai décidé d'adapter le second ordinateur afin qu'un utilisateur puisse utiliser l'un ou l'autre de ces derniers sans inconvénient (i.e. accès aux données, mots de passe identiques, etc.). Par le fait même, on règle le problème des mises à jour: en effet, un des ordinateurs peut être conservé à une version stable/connue alors que le deuxième est en test sur une version récente et vice-versa.

Voilà qui règle le problème des mises à jour, mais qui en introduit un nouveau: le problème de l'accès aux données d'un ordinateur à l'autre. Pour remédier à ce nouveau pépin, on configurera un serveur NFS sur chaque client afin que l'un puisse monter le /home de l'autre et vice-versa. Mais voilà une nouvelle complication: par défaut NFS est une vraie passoire: le serveur identifie les utilisateurs par UID/GID, sans authentification ce qui, même dans un réseau local sécuritaire comme j'aimerais que le mien soit, équivaut à chercher les ennuis (même avec root_squash, un individu mal intentionné pourrait avoir accès aux fichiers en tant que n'importe quel utilisateur (système ou non). Qui plus est, si le serveur ne connaît pas un UID/GID, le fichier est assigné à  l'utilisateur nobody (respectivement, le groupe nogroup). Encore un point qui me déplaît énormément.

Pourquoi ne pas simplement utiliser un fichier static_map (permettant de spécifier des correspondance UID client à UID serveur)? Parce que je n'ai pas envie de créer plein d'utilisateurs sur mon portable Gentoo, que c'est du travail sur chaque client, que c'est très fastidieux et ennuyant et que c'est peu sécuritaire de façon inhérente puisque le client est responsable d'assurer la sécurité du système complet.

Reste l'option Kerberos qui semble, au moment de «mettre sous presse», parfaitement adapté. En effet, Kerberos (v5) nous permet d'authentifier autant les machines que les utilisateurs et permet de choisir entre (en ordre croissant de sécurité): krb5: authentification, transactions subséquentes inchangées, krb5i: authentification + intégrité, les données peuvent toujours être interceptées et lues, mais une tentative d'altération sera détectée et krb5p: authentification + chiffrement («privacy»), les données sont complètement chiffrées lors du transport. Bien sûr, plus on sécurise les transactions, plus la performance en souffre. À noter toutefois que dans tous les cas l'authentification est faite de façon entièrement sécuritaire (le chiffrement utilisé est configurable par Kerberos).

On peut maintenant authentifier machines et utilisateurs, bien. Reste maintenant le problème d'associer ces derniers à un concept que la machine puisse associer aux fichiers afin de pouvoir sécuriser correctement les données des utilisateurs les uns vis-à-vis des autres (on ne veut pas que tout le monde puisse écrire partout).

Pour cela, on utilisera LDAP, ce qui vient, par la même occasion, résoudre un problème qui s'était sournoisement imposé: la centralisation de la gestion utilisateur.


TODO: Touch up this section

Préconfiguration

Avant même de configurer quoi que ce soit, il faut prévoir certains choix: Kerberos realm, LDAP entries, NFSv4 rootdir, ?

Voici le contexte utilisé dans cet article:
  • mediacenter.parents.local est le serveur NFS, le serveur LDAP et le serveur Kerberos
  • Enzo.parents.local et Cecil.parents.local sont les clients NFS, LDAP et Kerberos
  • Enzo.parents.local et Cecil.parents.local s'exportent réciproquement un répertoire par NFS

Configuration NFS

Commençons par faire fonctionner NFS de façon correcte. D'abord, il faut installer le serveur NFS sur chaque poste:

Gentoo:
RPCSEC_GSS_KRB5 doit être activé dans le kernel.
https://www.soljerome.com/blog/2011/08/31/gentoo-nfsv4-and-mit-kerberos/

Debian:
apt-get install nfs-kernel-server
Ce qui installe les autres paquets nécessaires (libnfsidmap2, nfs-common, etc) automatiquement.

TODO: Check this part
Ubuntu:

apt-get install nfs-kernel-server


Bien, maintenant configurons le partage NFSv4. Pour ce faire, il faut choisir un répertoire racine (je suggère de créer un répertoire spécifiquement pour cela). Ici, nous nommerons ce répertoire /media/storage/nfs (mais vous pouvez donner le nom que vous voulez):
# mkdir /media/storage/nfs


/etc/exports:
/media/storage/nfs gss/krb5i(rw,sync,fsid=0,no_subtree_check,root_squash,crossmnt)

Les options importantes ici sont fsid=0 (défini le partage comme étant la racine NFSv4) et crossmnt. Cette dernière option nous évite d'avoir à ajouter nohide à chaque «submount». De cette façon, l'on peut utiliser des bindmounts afin de permettre l'accès à des répertoires locaux à l'extérieur de la racine NFS, en voici un exemple:
mount --bind /home /media/storage/nfs/home

Cette dernière commande monte le répertoire /home sur /media/storage/nfs/home (ce dernier répertoire doit exister, bien sûr) permettant ainsi de partager le répertoire /home par NFSv4. On peut par la suite automatiser cette commande en ajoutant une entrée à la fin de /etc/fstab:
/home /media/storage none bind 0 0

Voir http://wiki.linux-nfs.org/wiki/index.php/Enduser_doc_kerberos#Kerberos_5_setup_for_NFSv4 et exports(5) pour plus d'informations

Il faut ensuite configurer les fichiers suivants:
Debian:
/etc/nsswitch.conf

[General]
Domain = parents.local
Local-Realm = PARENTS.LOCAL

[Translation]
Method = nsswitch

/etc/default/nfs-common
NEED_IDMAPD=yes
NEED_GSSD=yes

/etc/default/nfs-kernel-server
NEED_SVCGSSD=yes


TODO: Flesh out this part
Ubuntu:


Configuration Kerberos

[libdefaults]
  default_realm = PARENTS.LOCAL
  #This is needed for NFS at the moment
  allow_weak_crypto = true

[realms]
  PARENTS.LOCAL = {
    kdc = 127.0.0.1
    admin_server = 127.0.0.1
    default_domain = parents.local
  }

FIXME: Must [domain_realm] NOT contain .parents.local and parents.local mappings? Need to test if putting these mappings prevent things from working correctly
FIXME: Must weak crypto still be used with Debian Squeeze?


/etc/krb5kdc/kadm5.acl
kadmin/admin *

/etc/krb5.keytab
Il s'agit du fichier contenant les principals de chaque hôte. Les clés contenues dans ce fichier devraient donc être protégées jalousement et n'être connues que de l'hôte et du serveur Kerberos.

Mais avant de pouvoir créer ce fichier, il faut créer les principals sur le serveur Kerberos:
# kadmin.local
kadmin.local: addprinc -randkey nfs/cecil.parents.local@PARENTS.LOCAL

kadmin.local: addprinc -randkey ldap/cecil.parents.local@PARENTS.LOCAL
kadmin.local: addprinc -randkey nfs/enzo.parents.local@PARENTS.LOCAL
kadmin.local: addprinc -randkey ldap/enzo.parents.local@PARENTS.LOCAL
kadmin.local: addprinc -randkey nfs/mediacenter.parents.local@PARENTS.LOCAL
kadmin.local: addprinc -randkey ldap/mediacenter.parents.local@PARENTS.LOCAL

kadmin.local: addprinc -pwexpire now -pw vhann vhann@PARENTS.LOCAL
On a ici créé les principals nfs et ldap pour cecil, enzo et mediacenter. Il est à noter qu'en l'état, Kerberos ne fait pas de différence entre serveur et client, il ne se préoccupe que des « services » (par conséquent, tous les hôtes pourraient être configurés en serveur LDAP sans modification à la configuration Kerberos).

La dernière ligne crée un utilisateur 'vhann' dans le royaume (realm) PARENTS.LOCAL (vhann@PARENTS.LOCAL) dont le mot de passe est 'vhann' (-pw vhann) et dont le mot de passe devra être changé à la prochaine connexion (-pwexpire now).

FIXME: At current time, no Desktop Manager is able to handle expired passwords in either Ubuntu nor Debian (KDE works, but actually never prompts the user to change their password instead allowing the old one and throwing out the expiration error).
FIXME: Talk about host-based security (e.g.: .k5login).


Il ne reste plus qu'à se connecter sur chaque poste pour créer le fichier /etc/krb5.keytab qui contiendra les
principals
de l'hôte en question. Par exemple, pour enzo.parents.local, on procéderait ainsi:
root@enzo:/etc,0# kadmin -p kadmin/admin
Password for kadmin/admin@PARENTS.LOCAL:
kadmin: ktadd -k /etc/krb5.keytab -glob *enzo.parents.local
Où kadmin/admin est votre administrateur Kerberos (tel que défini lors de l'installation du paquet sous Debian).
La commande ktadd ajoute tous les principals se terminant par enzo.parents.local dans le fichier /etc/krb5.keytab.

Il est à noter que la commande ajoute (append) au fichier et n'écrase pas son contenu précédent. Il faut donc supprimer le fichier ou, alternativement, le modifier avec ktutil pour retirer des entrées. À noter que seul l'utilisateur à qui appartient le processus Kerberos (nécessairement root) devrait avoir accès au fichier. Il faut donc s'assurer d'avoir les permissions 600 ou 400 sur le fichier et s'assurer qu'il appartient bel et bien à root.

Configuration iptables

FIXME: Describe how to poke holes through iptables to allow access to services

Configuration LDAP

Il s'agit probablement de la plus grosse pièce de configuration.

/etc/ldap/ldap.conf
URI  ldap://[nomDuServeur]
BASE dc=parents,dc=local
Remplacer [nomDuServeur] par 127.0.0.1 sur le serveur lui-même et par son adresse IP ou son hostname sur les clients.


/etc/ldap/slapd.keytab
Il s'agit d'un fichier qu'on n'édite pas directement. Il contient les clés privées (Kerberos principals) nécessaires au serveur openLDAP afin d'obtenir un service ticket lui autorisant l'accès au service LDAP. On le crée de la même façon que l'on a créé le fichier /etc/krb5.keytab plus haut, excepté qu'il ne devrait contenir que les principals ldap

Par conséquent, ce fichier devrait contenir seulement le principal ldap/[nomDuServeur] (potentiellement sous plusieurs types de chiffrement différents).

Dans le cas présent, ce fichier ne sera présent que sur mediacenter puisque c'est le seul serveur LDAP.


/etc/default/slapd
Sous Debian, il faut décommenter (ou ajouter) la ligne suivante:
export KRB5_KTNAME=/etc/ldap/slapd.keytab
On pourrait laisser le fichier par défaut (/etc/krb5.keytab), mais il faudrait alors permettre à l'utilisateur sous lequel slapd a été lancé (sous Debian il s'agit de l'utilisateur "openldap") l'accès en lecture au fichier /etc/krb5.keytab. Ce qui constituerait un risque de sécurité énorme puisque n'importe quelle faille de sécurité de slapd comprometterait tous les principals contenus dans /etc/krb5.keytab.

Il faut ensuite redémarrer le serveur slapd.
root@mediacenter:~,0# /etc/init.d/slapd restart


Add schema files
Il faut ensuite ajouter les schema files umich permettant de configurer NFSv4 de façon à utiliser l'authentification LDAP.

FIXME: Describe how to do this with the dynamic schema system. In the mean time, see this: http://www.linuxquestions.org/questions/linux-server-73/how-to-add-a-new-schema-to-openldap-2-4-11-a-700452/

FIXME: Describe how to create LDIF files, add users, configure the LDAP database, etc.

Configuration clients

FIXME: Describe how to configure nsswitch, nss-pam-ldap, etc.


Kerberos:
/etc/krb5.conf
/etc/krb5kdc/kadm.acl
/etc/krb5.keytab
http://wiki.debian.org/NFS/Kerberos
http://web.mit.edu/kerberos/krb5-current/doc/


OpenLDAP:
http://www.openldap.org/doc/admin24/

SASL:


NSS:
/etc/nsswitch.conf
nss-ldapd AKA nss-pam-ldap (better but newer than nss-ldap)
http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html


NFS:
/etc/idmapd
/etc/exports
http://www.citi.umich.edu/projects/nfsv4/
http://www.citi.umich.edu/projects/nfsv4/ldap/
http://www.citi.umich.edu/projects/nfsv4/linux/faq/
http://www.citi.umich.edu/projects/nfsv4/crossrealm/libnfsidmap_config.html
http://www.citi.umich.edu/projects/nfsv4/crossrealm/ldap_server_setup.html
http://nfs.sourceforge.net/
http://wiki.linux-nfs.org/wiki/index.php/Enduser_doc_kerberos#Kerberos_5_setup_for_NFSv4

Liens utiles:

https://wiki.duckcorp.org/SqueezeKerberosNFSv4StrongCrypto

http://www.tldp.org/HOWTO/NIS-HOWTO/settingup_client.html
http://tldp.org/HOWTO/NFS-HOWTO/troubleshooting.html
http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/idmapper.html
http://www.troubleshooters.com/linux/nfs.htm



http://arthurdejong.org/nss-pam-ldapd/README
http://ldots.org/ldap/
http://wiki.debian.org/LDAP/NSS
http://www.citi.umich.edu/projects/nfsv4/crossrealm/libnfsidmap_config.html
http://arthurdejong.org/nss-pam-ldapd/design
https://docs.google.com/viewer?a=v&q=cache:eGIweDGmLVMJ:nfsv4.bullopensource.org/doc/kerberosnfs/krbnfs_howto_v3.pdf+nfs+kerberos+wrong+principal+in+request&hl=en&gl=ca&pid=bl&srcid=ADGEESh4BbDoM0oWGgzeP4I5xq8UoiMnjVf-dWL6g-Wdyq1Lk9l4Yfq2mEON2hq2_9FdEkxCWP9g6k8G_LddRU-SQn6jfcGG8tijEQ_aeQas_63DO8C-A0mIkxfiAGfCSUf1QmPW3Xx7&sig=AHIEtbQ_duoylWrrgKja8LNatT0WRDpLsw
http://www.shrubbery.net/solaris9ab/SUNWaadm/SYSADV6/p28.html
http://wiki.debian.org/NFS/Kerberos
http://lists.freebsd.org/pipermail/freebsd-questions/2005-February/075193.html
http://wiki.debian.org/LDAP/NSS
http://www.informit.com/guides/content.aspx?g=security&seqNum=34
http://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-admin/Configuring-Your-Firewall-to-Work-With-Kerberos-V5.html
http://www.danbishop.org/2011/05/01/ubuntu-11-04-sbs-small-business-server-setup-part-6-%E2%80%93-account-management/
http://www.padl.com/OSS/MigrationTools.html
http://arthurdejong.org/nss-pam-ldapd/setup
http://arthurdejong.org/nss-pam-ldapd/docs.html
http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol#RFCs
http://www.citi.umich.edu/projects/nfsv4/crossrealm/ldap_server_setup.html

Comments