Voici une alternative au très connu trio NSS + PAM + MySQL. Ce dernier permet de mettre en place une authentification des utilisateurs de manière centralisé.
Les utilisateurs et les groupes sont stockés dans une base de données (ici PostgreSQL).
PostgreSQL est un SGBD puissant, très robuste de plus il est très proche de la norme SQL et il mérite à mon goût d'être plus connu.
Ce tuto à été réalisé sur une Debian Lenny (stable). Il vous sera nécessaire d'installer certains packages.
# aptitude install postgresql libnss-pgsql2 libpam-pgsql
La première étape consiste à configurer correctement PostgreSQL. Nous commençons par le faire écouter sur le réseau. Pour cela il faut éditer le fichier /etc/postgresql/8.3/main/postgresql.conf
listen_addresses = '*' #listen_addresses = 'localhost' # what IP address(es) to listen on;
Puis autoriser les connexion depuis votre réseau local –> editer /etc/postgresql/8.3/main/pg_hba.conf et rajouter la ligne suivante avec le réseau correspondant
host all all 192.168.0.0/24 md5
Pour la suite il vous sera nécessaire de vous familiariser avec psql. L'utilisateur postgres peut se connecter sans mot de passe en local et à tous les droits.
# su postgres $ psql =# CREATE DATABASE manage; =# \c manage =# CREATE SCHEMA pam;
Nous avons donc maintenant créé une base de données manage avec un schema pam qui contiendra nos informations.
Il faut donc maintenant créer les utilisateurs nécessaires et leurs attribuer les droits correspondants.
# su postgres $ psql =# \c manage =# CREATE USER nss ENCRYPTED PASSWORD 'toto'; =# CREATE USER nssroot ENCRYPTED PASSWORD 'titi'; =# CREATE USER manager ENCRYPTED PASSWORD 'god'; =# GRANT USAGE ON SCHEMA pam TO nss,nssroot; =# GRANT ALL ON SCHEMA pam TO manager; =# GRANT SELECT ON pam.groups,pam.users,pam.user_group TO nss; =# GRANT SELECT UPDATE ON pam.groups,pam.users,pam.user_group TO nssroot;
Nous avons créé 3 utilisateurs. nss ne peut que lire les données, nssroot peut les lire et les mettre à jour et manager à tous les droits sur le schéma, c'est cet utilisateur qui vous permettra de gérer vos utilisateurs.
Le script de création de la base de données que je vous propose ici n'est pas tout à fait le même que celui de la documentation officielle, mais je trouve cela plus simple et moins redondant.
Il faut ici exécuter ce script en tant que manager (voir la commande psql).
SET client_encoding = 'UTF8'; SET standard_conforming_strings = off; SET check_function_bodies = false; SET client_min_messages = warning; SET escape_string_warning = off; SET search_path = pam, pg_catalog; CREATE SEQUENCE group_id INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1000 CACHE 1; CREATE TABLE groups ( gid integer DEFAULT NEXTVAL('group_id'::regclass) NOT NULL, group_name character varying(30) DEFAULT ''::character varying NOT NULL, STATUS character(1) DEFAULT 'A'::bpchar, group_password character varying(64) DEFAULT 'x'::character varying NOT NULL ); CREATE TABLE user_group ( uid integer DEFAULT 0 NOT NULL, gid integer DEFAULT 0 NOT NULL ); CREATE SEQUENCE user_id INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1000 CACHE 1; CREATE TABLE users ( uid integer DEFAULT NEXTVAL('user_id'::regclass) NOT NULL, user_name character varying(50) NOT NULL, realname character varying(32) NOT NULL, shell character varying(20) DEFAULT '/bin/false'::character varying NOT NULL, password character varying(40) NOT NULL, gid integer DEFAULT 65534 NOT NULL, homedir character varying(32) NOT NULL, lastchange integer DEFAULT 0 NOT NULL, min integer DEFAULT 0 NOT NULL, max integer DEFAULT 0 NOT NULL, warn integer DEFAULT 7 NOT NULL, inact integer DEFAULT (-1) NOT NULL, expire integer DEFAULT (-1) NOT NULL, flag integer DEFAULT 0 NOT NULL );
Configurons maintenant la librairie NSS pour quelle utilise les informations de la BDD PostgreSQL.
Il y a un fichiers à éditer et deux à créer.
Ce premier fichier à créer contient les requêtes à utiliser pour récupérer les infos classiques depuis la BDD.
connectionstring = hostaddr=127.0.0.1 dbname=manage user=nss password=toto connect_timeout=1 sslmode=disable # you can use anything postgres accepts as table expression # Must return "usernames", 1 column, list getgroupmembersbygid = SELECT user_name FROM pam.users WHERE gid = $1 # Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid getpwnam = SELECT user_name, 'x', realname, homedir, shell, uid, gid FROM pam.users WHERE user_name = $1 # Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid getpwuid = SELECT user_name, 'x', realname, homedir, shell, uid, gid FROM pam.users WHERE uid = $1 # All users allusers = SELECT user_name, 'x', realname, homedir, shell, uid, gid FROM pam.users # Must return group_name, group_passwd, group_gid getgrnam = SELECT group_name, group_password, gid, ARRAY(SELECT u.user_name FROM pam.user_group ug RIGHT OUTER JOIN pam.users u ON u.uid = ug.uid WHERE ug.gid = groups.gid OR u.gid = groups.gid) AS members FROM pam.groups WHERE group_name = $1 # Must return group_name, group_passwd, group_gid getgrgid = SELECT group_name, group_password, gid, ARRAY(SELECT u.user_name FROM pam.user_group ug RIGHT OUTER JOIN pam.users u ON u.uid = ug.uid WHERE ug.gid = groups.gid OR u.gid = groups.gid) AS members FROM pam.groups WHERE gid = $1 # Must return gid. %s MUST appear first for username match in where clause groups_dyn = SELECT ug.gid FROM pam.users u JOIN pam.user_group ug USING (uid) where u.user_name = $1 and u.gid <> $2 allgroups = SELECT group_name, group_password, gid, ARRAY(SELECT u.user_name FROM pam.user_group ug RIGHT OUTER JOIN pam.users u ON u.uid = ug.uid WHERE ug.gid = groups.gid OR u.gid = groups.gid) AS members FROM pam.groups
Ce deuxième fichier contient les infos nécessaire pour “accèder” aux infos de type shadows (modifier le mot de passe par exemple).
shadowconnectionstring = hostaddr=127.0.0.1 dbname=manage user=nssroot password=titi connect_timeout=1 sslmode=disable shadowbyname = SELECT user_name, password, lastchange, min, max, warn, inact, expire, flag FROM pam.users WHERE user_name = $1 shadow = SELECT user_name, password, lastchange, min, max, warn, inact, expire, flag FROM pam.users
Ce fichier ne doit être accessible que de l'utilisateur root:
# chmod 600 /etc/nss-pgsql-root.conf
Ce fichier configure nss pour utiliser certain modules.
passwd: compat pgsql group: compat pgsql shadow: compat pgsql hosts: files dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis
A ce stade si vous créer un utilisateur toto dans la BDD, vous devriez être capable de récupérer des infos sur lui grace à la commande id.
# id toto uid=1000(toto) gid=1000(toto) groupes=1000(toto)
Il ne reste plus qu'a configurer PAM.
Ce fichier contient les requêtes nécessaire pour PAM pour obtenir les infos et les mettre à jour si nécessaire.
connect = hostaddr=127.0.0.1 user=nssroot dbname=manage password=titi connect_timeout=1 sslmode=disable auth_query = SELECT password FROM pam.users WHERE user_name = %u pwd_query = UPDATE pam.users SET password = %p, lastchange = CAST(extract(EPOCH from current_timestamp)/60/60/24 AS INTEGER) WHERE user_name = %u acct_query = SELECT (expire < CAST(extract(EPOCH from current_timestamp)/60/60/24 AS INTEGER) AND expire <> -1), ((lastchange+max) < CAST(extract(EPOCH from current_timestamp)/60/60/24 AS INTEGER) AND max > 0), (password = NULL) FROM pam.users WHERE user_name = %u pw_type = crypt_md5 debug
Dans ce répertoire il faut éditer trois fichiers.
C'est ici que les informations de type expiration d'un compte, d'un mot de passe … sont pris en compte.
account sufficient pam_pgsql.so account required pam_unix.so
Utilisé pour authentifier un utilisateur.
auth sufficient pam_pgsql.so auth required pam_unix.so nullok_secure
Celui ci est assez évident.
password sufficient pam_pgsql.so authok password required pam_unix.so nullok obscure md5 try_first_pass
Et voila la configuration est terminée, vous pouvez dès maintenant créer vos utilisateurs dans votre BDD et les voir apparaître magiquement sur tout vos systèmes utilisant cette BDD.
Il vous faudra bien sûr créer vos propres outils d'administration d'utilisateur ou utiliser une interface du type PgAdmin III.