Le module PAM time

Commençons par le plus simple. Les Linux modernes comportent tous une couche d'authentification des utilisateurs modulaire, basée sur PAM. Ce système vérifie les mots de passe tapés dans des annuaires d'utilisateurs locaux ou distants (c'est le cas en entreprise notamment). Il est également capable d'ajouter des conditions à cette vérification ou encore de modifier les droits des utilisateurs en jouant sur les groupes auxquels ils appartiennent[1]. PAM sait donc interdire d'ouvrir une session selon différentes conditions mais PAM ne sait pas fermer les sessions en cours. Ainsi si vous limitez les heures d'accès et que vos utilisateurs se connectent 5 minutes avant l'heure fatidique, ils peuvent travailler comme si de rien n'était, en tout cas avec PAM seul. Nous verrons plus loin comment faire mieux grâce à timeoutd.

Dans les Linux Debian et dérivé, la configuration de PAM se trouve dans les fichiers texte du répertoire /etc/pam.d/ :

$ ls /etc/pam.d/
chfn            common-auth      cups           login   samba  xscreensaver
chsh            common-password  gdm            other   su
common-account  common-session   gdm-autologin  passwd  sudo

Si vous avez la curiosité d'ouvrir des fichiers relatifs aux sessions des utilisateurs (gdm et login par exemple), vous constaterez qu'ils incluent des références à d'autres fichiers de ce répertoire, en l'occurrence ceux dont le nom commence par common-. Aussi, plutôt que modifier chaque fichier relatif aux sessions comme l'indique le billet Fedora Core 6: Controlling Logins By Time, il semble plus judicieux de ne s'intéresser qu'à l'un des fichiers common-*. Nous allons donc modifier common-account de manière à ce qu'il mentionne le module pam_time :

$ sudo nano /etc/pam.d/common-account

Il faut alors que le texte après les commentaires[2] contienne ceci :

account requisite       pam_time.so
account required        pam_unix.so

Maintenant que PAM est au courant qu'il doit utiliser le module pam_time, il n'y a plus qu'à demander à celui-ci de limiter les plages horaires de connexion pour les personnes concernées. Ça se passe dans le fichier /etc/security/time.conf :

$ sudo nano /etc/security/time.conf

La syntaxe est expliquée dans les commentaires en début de fichier. Par défaut il ne contient d'ailleurs que ces commentaires, il vous faudra donc ajouter vos propres règles vous-même. En résumé chaque règle est faite de 4 informations :

services;ttys;users;times

Vraisemblablement vous ne jouerez principalement que sur l'utilisateur et l'heure de connexion, vos règles seront donc plutôt de cette forme :

*; *; users; times

Les heures sont spécifiées en accolant des jours codés sur 2 lettres tirées de l'anglais[3] et une plage horaire au format hhmm-hhmm. Par exemple :

# uniquement les jours de semaine (lundi à vendredi)
*; *; *; Wk0000-2400

# utilisateur « joe » non autorisé la nuit
*; *; joe; Al0800-2000

Pour terminer, si vous avez encore de vieux mauvais réflexes ;-), sachez qu'il est inutile de redémarrer et qu'il n'y a aucun service à redémarrer non plus : ça marche dès qu'on enregistre les fichiers de configuration de PAM !

L'outil timeoutd

L'outil timeoutd apporte des fonctionnalités complémentaires à pam_time parmi lesquelles :

  • fermer les sessions après une heure pré-définie, l'utilisateur est alors averti quelques minutes avant qu'il va être mis à la porte
  • mesurer le temps d'utilisation quotidien d'une machine par utilisateur ou par groupe et fermer les sessions en conséquences

En revanche timeoutd ne sait pas interdire la connexion comme PAM le fait. Passé l'heure ou le quota d'heures, l'utilisateur peut encore se connecter mais il est rapidement mis à la porte. Il est donc logique d'utiliser les deux conjointement. Remarque : faites attention à ne pas confondre le paquet timeoutd avec le paquet timeout qui est un outil qui limite la durée d'exécution d'une commande…

L'installation et la configuration sont très rapides comme l'indique le billet Computer time limitation using Timeoutd. La commande suivante l'installe :

$ sudo apt-get install timeoutd

Il suffit ensuite d'éditer le fichier /etc/timeouts :

$ sudo nano /etc/timeouts

Sa syntaxe fonctionne sur un principe similaire à pam_time, mais avec un ordre des paramètres différents et plus de paramètres puisqu'il faut pouvoir dire si la connexion est autorisée ou non et si oui, pour combien de temps. Voici quelques exemples :

# le groupe « bambins » ne peut se connecter tard dans la soirée
WkSu2000-2359:*:*:bambins:NOLOGIN
# mais un peu plus tard le samedi
Sa2130-2359:*:*:bambins:NOLOGIN

# limiter « joe » et « emma » à 60 min. en semaine, 180 min. le week-end
# ils sont prévenus 10 min. avant l'atteinte du quota
Wk:*:*:joe,emma:*:*:60:10
We:*:*:joe,emma:*:*:180:10

Une fois les modifications effectuées, contrairement à PAM, il faut redémarrer le service timeoutd avec la commande suivante :

$ sudo /etc/init.d/timeoutd restart

Lorsqu'un de vos utilisateur atteindra une des limites fixées, il aura soit une fenêtre d'avertissement dans son environnement graphique, soit un texte d'avertissement dans sa console, puis une déconnexion brutale quelques minutes plus tard. Par exemple dans la console on obtient ce genre de message lorsqu'on se connecte après l'heure fatidique (donc avec PAM non activé) :

$ /usr/sbin/timeoutd charlelie tty7


Logins not allowed at this time.  Please try again later.

Malheureusement tout ceci ne marche pas correctement dans Debian Lenny à cause d'un bug rapporté chez Ubuntu. Un patch a été proposé et permet de remettre en marche timeoutd. Comme l'application du patch nécessite de recompiler, je vous propose de récupérer ma version pour l'architecture i386 à partir de mon dépôt de paquet Debian DoudouLinux, dans la mesure où vous me faites suffisamment confiance[4]. Sinon il vous faudra suivre les instructions ci-dessous pour re-générer votre paquet vous-même à partir du code source. Éventuellement vous pouvez aussi récupérer une version que j'ai modifiée afin d'avoir une fenêtre d'avertissement plus esthétique et, surtout, en français ![5]

Recompiler timeoutd avec le patch Ubuntu

Tout d'abord il faut récupérer le code source du paquet avec la commande suivante :

$ sudo apt-get source timeoutd

Le code source du paquet sera alors téléchargé dans le répertoire courant. Ceci suppose que vous ayez activé dans votre gestionnaire de paquets les dépôts de paquets sources en plus de ceux des paquets compilés. Le fichier /etc/apt/sources.list contiendra donc une ligne de ce genre :

deb-src http://ftp.fr.debian.org/debian/ stable main contrib non-free

Le patch sera ensuite récupéré sur Internet avec la commande wget :

$ wget http://launchpadlibrarian.net/18225966/fix_local_x.patch

Il s'agit d'un fichier texte qui peut directement être utilisé pour corriger le code de timeoutd à l'aide de la commande patch :

$ sudo patch -d timeoutd-1.5/ < fix_local_x.patch

Il ne reste plus qu'à modifier le nom du paquet ainsi corrigé pour ne pas le confondre avec l'original. Ceci se passe dans le fichier changelog du sous-répertoire debian du paquet source :

$ sudo nano timeoutd-1.5/debian/changelog

Vous ajouterez alors en début de fichier un texte de ce genre en respectant bien l'indentation :

timeoutd (1.5-10.1-ubuntupatch1) unstable; urgency=low
 * custom version with Ubuntu Launchpad patch
   see https://bugs.launchpad.net/ubuntu/+source/timeoutd/+bug/165254

 -- Jean-Michel Philippe <philipjm@free.fr>  Sun, 29 Mar 2009 22:15:25 +0200

Toutefois il subsiste un petit problème de paramètres de compilation qui n'est pas traité par le patch. Il vous faudra pour le résoudre éditer le fichier Makefile :

$ sudo nano timeoutd-1.5/Makefile

Puis modifier la ligne suivante :

$(CC) $(CFLAGS) -o timeoutd -L/usr/X11R6/lib timeoutd.o -lXss -lXext

en :

$(CC) $(CFLAGS) -o timeoutd -L/usr/X11R6/lib timeoutd.o -lXss

La recompilation du paquet binaire se fait pour finir avec la commande suivante :

$ sudo apt-get -b source timeoutd

Celle-ci créera un paquet timeoutd_1.5-10.1-ubuntupatch1_i386.deb qu'il n'y a alors plus qu'à installer :

$ sudo dpkg -i timeoutd_1.5-10.1-ubuntupatch1_i386.deb

Et voilà !

Notes

[1] par exemple un utilisateur local pourra être systématiquement autorisé à monter les clefs USB en lui ajoutant le groupe plugdev à l'ouverture de session

[2] les commentaires sont très classiquement indiqués par un signe dièse « # » en début de ligne

[3] Mo Tu We Th Fr Sa Su Wk Wd Al, les 3 derniers étant les jours de semaine, le week-end et tous les jours respectivement

[4] il s'agit du paquet timeoutd_1.5-10.1-ubuntupatch1_i386.deb

[5] il s'agit du paquet timeoutd_1.5-10.1-jmp2_i386.deb