Principe de l'authentification MySQL via libnss-mysql-bg

Les données d'authentification (à savoir UID, login, mot de passe, répertoire personnel, date d'expiration, GID, groupes, etc.) sont stockées sur un serveur MySQL. Ce serveur MySQL est accessible par tous les postes clients.

Lorsqu'un utilisateur veut se connecter sur un poste client, ce dernier vérifie l'authenticité de la personne et la validité du compte (non-expiration) en utilisant les informations du serveur MySQL.

Mise en place

Sur le serveur

  1. Mettre en place un serveur MySQL, accessible en IP depuis tous les postes clients qui utilisent l'authentification centralisée. A noter qu'il est conseillé de bien vérifier que le serveur MySQL est configuré dès le départ en utf-8 (voir Etude/Unicode).

  2. Créer une base qui contiendra les données d'authentification, nommée par exemple nss. Voici les schémas des tables que nous utilisons à l'AUF :

    • la table users contient la description de chaque compte. Il s'agit des données de /etc/passwd et de /etc/shadow regroupées dans un seul enregistrement. A l'AUF, on y ajoute trois champs supplémentaires (sources, creation, modification) pour savoir d'où vient le compte, à quel moment il a été crée et la date de sa dernière modification.

      • CREATE TABLE `users` (
            `username` varchar(128) NOT NULL PRIMARY KEY,
            `password` varchar(64) NOT NULL,
            `uid` integer NOT NULL UNIQUE,
            `gid` integer NOT NULL,
            `gecos` varchar(128) NOT NULL,
            `homedir` varchar(255) NOT NULL UNIQUE,
            `shell` varchar(64) NOT NULL,
            `lstchg` integer NOT NULL,
            `min` integer NOT NULL,
            `warn` integer NOT NULL,
            `max` integer NOT NULL,
            `inact` integer NOT NULL,
            `expire` integer NOT NULL,
            `flag` integer NOT NULL,
            `source` varchar(10) NOT NULL,
            `creation` datetime NOT NULL,
            `modification` datetime NOT NULL
        );
    • la table groups décrit les groupes systèmes. Il s'agit des données de /etc/groups :

      • CREATE TABLE `groups` (
            `name` varchar(32) NOT NULL UNIQUE,
            `password` varchar(64) NOT NULL,
            `gid` integer AUTO_INCREMENT NOT NULL PRIMARY KEY
        );
    • la table grouplist fait le lien entre les utilisateurs et leur groupes secondaires :

      • CREATE TABLE `grouplist` (
            `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
            `gid` integer NOT NULL,
            `username` varchar(128) NOT NULL,
            UNIQUE (`gid`, `username`)
        );
  3. Vous pouvez également ajouter des contraintes reliant les tables. Ce n'est pas obligatoire, mais cela fera en sorte que les données resteront cohérentes. Par exemple, un utilisateur ne pourra pas avoir un groupe qui n'existe pas. Voici les quelques contraintes conseillées :
    • ALTER TABLE `users` ADD CONSTRAINT gid_refs_gid_60c371b8 FOREIGN KEY (`gid`) REFERENCES `groups` (`gid`);
      ALTER TABLE `grouplist` ADD CONSTRAINT username_refs_username_5efc4794 FOREIGN KEY (`username`) REFERENCES `users` (`username`);
      ALTER TABLE `grouplist` ADD CONSTRAINT gid_refs_gid_6d7c9cff FOREIGN KEY (`gid`) REFERENCES `groups` (`gid`);
  4. Créer des utilisateurs MySQL pour l'accès en lecture à cette base :
    • un utilisateur MySQL pour la lecture des données publiques, c'est-a-dire tout sauf les mots de passe (plus exactement : tout sauf les données correspondantes à /etc/shadow)

    • un autre utilisateur MySQL pour la lecture des données d'authentification, c'est-à-dire toutes les données.

  5. Mettre en place les données dans la base. Pour ce faire, tout dépend de votre organisation actuelle :
    • Si vous utilisez déjà un MySQL, adaptez le schéma de votre base actuelle ;
    • Si vous utilisez déjà un autre SGBD, passez à MySQL avec le schéma proposé en 2;
    • Si vous êtes déjà en NIS ou LDAP ou autre, vous pouvez soit migrer les données, soit programmer un script de synchronisations qui sera lancé lors de l'ajout, de la modification ou de la suppression d'un utilisateur.
  6. Adaptez vos outils de gestion des comptes à cette base MySQL :
    • installez l'outil AUF de gestion auf-django-users

    • si vous avez déjà un outil plus efficace chez vous, programmez un synchronisateur de ce système vers MySQL (par exemple si vous avez une authentification NIS, laisser le système ajouter l'utilisateur "comme avant" et lancez la synchro juste après)

Sur les clients

Utilisation du paquet auf-poste-client-fixe

Installez le paquet auf-poste-client-fixe disponible pour Ubuntu (Jaunty et suivantes) dans le dépôt AUF. Il suffit de modifier les données de connexion dans /etc/libnss-mysql.conf et /etc/libnss-mysql-root.conf pour que ça fonctionne.

A la main

  1. Installer le paquet libnss-mysql-bg pour que la bibliothèque de résolution de nom (nss = name service switch) sache interroger MySQL.

  2. Configurer libnss-mysql-bg dans les deux fichiers /etc/libnss-mysql.cfg et /etc/libnss-mysql-root.cfg. Vous trouverez la documentation et beaucoup d'exemples dans /usr/share/doc/libnss-mysql-bg/. Voici un exemple qui fonctionne avec la base au format AUF décrit ci-dessus :

    # Exemple de fichier /etc/libnss-mysql.cfg 
    # Pour chaque type de donnée on écrit la requete SQL correspondante... Facile. Souple. Efficace.
    getpwnam    SELECT username,'x',uid,gid,gecos,homedir,'/bin/bash' \
                FROM users \
                WHERE username= binary '%1$s' \
                LIMIT 1
    getpwuid    SELECT username,'x',uid,gid,gecos,homedir,'/bin/bash' \
                FROM users \
                WHERE uid='%1$u' \
                LIMIT 1
    getspnam    SELECT username,password,lstchg,min,max,warn,inact,expire,flag \
                FROM users \
                WHERE username= binary '%1$s' \
                LIMIT 1
    getpwent    SELECT username,'x',uid,gid,gecos,homedir,'/bin/bash' \
                FROM users
    getspent    SELECT username,password,lstchg,min,max,warn,inact,expire,flag \
                FROM users
    getgrnam    SELECT name,password,gid \
                FROM groups \
                WHERE name='%1$s' \
                LIMIT 1
    getgrgid    SELECT name,password,gid \
                FROM groups \
                WHERE gid='%1$u' \
                LIMIT 1
    getgrent    SELECT name,password,gid \
                FROM groups
    memsbygid   SELECT username \
                FROM grouplist \
                WHERE gid='%1$u'
    gidsbymem   SELECT gid \
                FROM grouplist \
                WHERE username= binary '%1$s'
    
    host        123.45.67.89    <-- mettre une IP et pas un nom de machine
    database    authnss
    username    nsslire         <-- utilisateur ayant les accès en lecture sur les données publiques
    password    fautpasrever
    timeout     3
    compress    0
    # Exemple de fichier /etc/libnss-mysql-root.cfg
    # on indique uniquement l'utilisateur ayant accès aux données d'authentification
    # (en gros le mot de passe, l'expiration, etc : comme pour /etc/shadow)
    username    nssroot
    password    ktchrootuut
  3. Activer le module mysql de NSS :
    # (... extrait de /etc/nsswitch.conf pour y ajouter mysql ...)
    passwd:         files mysql
    group:          files mysql
    shadow:         files mysql
  4. <!> Installer nscd (nscd = name service cache daemon) pour que le système garde en mémoire les données de connexion, afin d'éviter de faire des requêtes MySQL sans arrêt... et fasse tout planter !

  5. Petit bug avec le déverrouillage d'écran : faire un sudo chmod u+s /sbin/unix_chkpwd pour autoriser la vérification des mots de passe pour le déverrouillage de l'écran.

  6. Et à partir de là, ça doit marcher...

Note : les groupes peuvent être indiqués dans la base MySQL centrale, mais cela peut vite être fastidieux. Vous préférerez sans doute la technique indiquée sur la page GestionDesGroupes, plus souple dans le cadre des postes clients.

Que faire lorsque « ça ne marche pas »

Attention !! Il ne faut pas confondre la phase d'authentification (libnss) avec l'accés aux fichiers (NFS). Si l'erreur se produit aprés l'authentification, et se présente sous quelquechose de la forme d'une petite fenêtre «Votre dossier personnel est censé être "/home/xxxx" mais il semble ne pas exister», c'est plutôt sur l'infrastructure NFS qu'il faudra se pencher.

Est-ce que le problème se pose pour tous les comptes ou pour quelques comptes seulement ?

Sur le serveur, vérifier les points suivants

Sur le poste client, vérifier les points suivants

Autres utilisations

Le fait de posséder une base MySQL contenant les informations d'authentification vous simplifiera la vie sur vos autres soucis d'authentification. En effet cette base peut être utilisée :

AuthentificationCentralisée/NssMysql (dernière édition le 2014-04-04 18:49:58 par WillyManga)