Configuration d'un système d'authentification pour Ikiwiki🔗

Posted by Médéric Ribreux 🗓 In blog/ Sysadmin/

Introduction

Ikiwiki permet d'éditer des pages en ligne. Jusqu'à présent, j'utilisais uniquement Git pour commiter des articles sur ma plate-forme Ikiwiki. C'est un moyen assez efficace pour publier des articles car j'utilise mon éditeur de texte favori (Emacs) pour le faire et ça ne pose aucun problème.

Néanmoins, parfois, on a besoin d'effectuer juste une petite correction et le faire dans un navigateur Web reste sans doute le moyen le plus efficace. Mais qui dit édition en ligne, dit sécurité ! Il ne faut pas en effet que n'importe qui puisse réaliser ces modifications sans contrôle.

Mon cas d'utilisation est assez simple: il n'y a qu'un seul utilisateur qui publie sur la plate-forme. Je n'ai donc pas besoin de mettre en place un système complexe basé sur une base de données. De plus, j'aimerais bien pouvoir réutiliser une des méthodes d'authentification dont je me sers fréquemment.

Ces besoins impliquent d'utiliser un plugin particulier d'Ikiwiki qui se nomme httpauth. Ce dernier permet de déléguer le mécanisme d'authentification au serveur Web. En cas d'authentification réussie, ce dernier passe la main au CGI d'Ikiwiki avec les bons paramètres.

Cet article tente d'illustrer la configuration de ce plugin dans Ikiwiki ainsi que la mise en place du mécanisme d'authentification de manière à disposer d'une édition en ligne sécurisée.

Installation des paquets nécessaires à l'authentification

Pour faire fonctionner le plugin httpauth, il est nécessaire de disposer des bons modules Perl. En effet, le CGI d'Ikiwiki ne permet pas grand-chose sans les bons paquets. Si vous tentez d'utiliser le plugin httpauth sans ces modules, le CGI retournera une erreur.

# aptitude install libcgi-session-perl libcgi-formbuilder-perl

Avec ces modules, le CGI d'Ikiwiki est capable de générer des formulaires web ainsi que de gérer des sessions. C'est tout ce dont nous avons besoin à ce niveau.

Configuration d'Ikiwiki

si vous consultez la documentation d'Ikiwiki sur l'authentification, vous pourrez constater qu'il y a plusieurs méthodes autres que httpauth. Par défaut, Ikiwiki utilise passwordauth. Ce dernier créé une base de données utilisateur (dans le répertoire .ikiwiki/userdb) qui gère les accès. Par défaut, cette base est ouverte, c'est à dire qu'on peut s'y enregistrer simplement en remplissant un formulaire. En conclusion, si vous laissez Ikiwiki sans modifier sa configuration, n'importe qui pourra créer et modifier des articles en créant un compte bidon. Voilà pourquoi il faut enchaîner toute de suite avec la configuration du plugin httpauth.

Vous devez modifier votre fichier de configuration Ikiwiki (fichier .setup). Voici ce que j'ai fait au mien:

# plugins to add to the default configuration
add_plugins => [qw{goodstuff format highlight toggle img rawhtml favicon sidebar meta calendar search editpage httpauth}],
# plugins to disable
disable_plugins => [qw{passwordauth openid anonok}],# httpauth plugin
# url to redirect to when authentication is needede
cgiauthurl => 'https://example.org/auth/ikiwiki.cgi',

J'ai tout simplement ajouté le plugin editpage pour permettre l'édition de pages ainsi que le plugin httpauth pour la gestion de l'authentification.

Ensuite, j'ai préventivement désactivé tous les autres plugins liés à l'authentification (passwordauth, openid et anonok).

Enfin, j'ai renseigné une variable nommée cgiauthurl. Cette dernière permet au CGI d'Ikiwiki d'être accédé depuis une autre URL lorsqu'aucune session valide n'a été repérée. C'est ce mécanisme qui va nous permettre de gérer l'authentification. Il suffira de déclencher une authentification lorsqu'un utilisateur désire accéder à https://example.org/auth/ et le tour sera joué. Remarquez que cette page est accédée via TLS (HTTPS) ce qui n'est pas un hasard.

Vous aurez sans doute besoin de créer le répertoire défini par cgiauthurl. Dans mon cas, j'ai juste créé le répertoire /var/www/auth avec les bons droits (ceux pour www-data) et réalisé un lien symbolique de /var/www/ikiwiki vers /var/www/auth/ikiwiki.cgi:

# mkdir /var/www/auth
# chown www-data:www-data /var/www/auth
# ln -s /var/www/ikiwiki.cgi /var/www/auth/ikiwiki.cgi

Il faudra bien sûr adapter ces chemins à votre installation d'Ikiwiki.

Pour prendre en compte ce changement de configuration vous aurez besoin de regénérer le CGI d'Ikiwiki. Cette opération est déclenchée lorsque vous reconstruisez l'ensemble du site:

$ ikiwiki --setup ikiwiki.setup

Configuration Apache

Maintenant que nous avons configuré Ikiwiki, il reste à s'occuper d'Apache. En effet, c'est bien le serveur HTTP qui va réaliser une authentification de type Basic et passer la main au CGI d'Ikiwiki si l'authentification s'est correctement déroulée. Le serveur Web envoie le nom de l'utilisateur authentifié au CGI via une variable d'environnement, nommée REMOTE_USER.

Puisque l'authentification se fera en mode Basic, une connexion chiffrée est indispensable ! C'est à cet effet que nous avons délibérément configuré la variable Ikiwiki cgiauthurl en https. Ainsi, lorsqu'un utilisateur tente d'éditer une page en mode HTTP standard, il est automatiquement redirigé vers la partie HTTPS du site et aucun mot de passe ne transitera en clair sur le réseau.

Il faut donc éditer cette partie au niveau de la configuration d'Apache pour déclencher une authentification. Je ne vais pas rentrer dans les détails car votre configuration peut être très différente de la mienne. Dans mon cas, j'ai juste défini un nouvel emplacement dans la configuration du VirtualHost dédié à HTTPS:

# Ikiwiki authentication
<Directory /var/www/auth/>
	Options -Indexes FollowSymLinks MultiViews +ExecCGI
	AllowOverride None
	Order allow,deny
	Allow from all
	AuthType Basic
	AuthName "Ikiwiki authentication"
	AuthUserFile /etc/apache2/my_userdb
	Require valid-user
</Directory>

Attention, le CGI d'Ikiwiki utilise la variable d'environnement REMOTE_USER retournée par Apache pour déterminer le nom de l'utilisateur authentifié. Si vous avez défini cette variable (avec un SetEnv par exemple) dans votre configuration Apache et même si cette valeur est nulle, Ikiwiki l'utilisera et considérera que l'utilisateur est authentifié. Dans mon cas, j'avais un comportement assez particulier: Ikiwiki ne me demandait jamais de m'authentifier et le nom de l'utilisateur pour la session était vide. J'avais tout simplement initialisé la variable d'environnement REMOTE_USER par défaut car j'avais mis en place sur mon serveur un accès Git par HTTP (git-http-backend). Ce dernier définissait la variable de la manière suivante:

SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER

Lorsque j'accède à mes dépôts Git via HTTP(S), le client Git remonte la variable REDIRECT_REMOTE_USER. Mais lorsqu'on n'utilise pas Git (ce qui est le cas lorsqu'on édite une page avec le CGI d'Ikiwiki), la variable d'environnement REDIRECT_REMOTE_USER est vide. Cette configuration Apache créé la variable REMOTE_USER, peu importe le cas. Cette définition est trop générale (et risquée).

À la place, il faut définir autrement cette variable dans la configuration Apache:

SetEnvIf Request_URI "^/git/" REMOTE_USER=$REDIRECT_REMOTE_USER

Dans ce cas, la variable REMOTE_USER n'est définie que pour les URLs qui commencent par /git/ (ce qui n'est pas le cas lorsqu'on édite une page avec le CGI d'Ikiwiki). Ne pas redéfinir cette variable en mode conditionnel conduit à un vrai trou de sécurité ! Alors faîtes bien attention à votre configuration Apache…

Conclusion

Dans cet article, on voit que la mise en place d'un système d'authentification est assez accessible. Il y a juste quelques modules Perl à installer ainsi qu'un minimum de configuration d'Ikiwiki et d'Apache. Je ne peux que vous recommander d'effectuer quelques tests en pré-production avant de valider la configuration car l'enjeu est important: si vous n'avez pas assez sécurisé cette partie, n'importe quel attaquant pourra vous pourrir vos articles (ou faire du DDOS).

Maintenant, je peux faire de l'édition en ligne de manière sécurisée. Cet article a d'ailleurs été complètement rédigé en ligne !

Note de l'auteur du 12/04/2020: Avec le temps, je n'ai finalement jamais utilisé cette fonction d'édition en ligne: une fois sur deux je paumais mon mot de passe tellement je ne créais plus de contenu sur cette plate-forme. Aujourd'hui, je passe exclusivement par un éditeur de texte et un commit. D'une manière générale, avec l'expérience, on ne peut pas combiner rédaction sérieuse et publication rapide. Il faut toujours beaucoup de temps pour écrire quelque-chose de valable, encore plus de temps pour en faire la relecture, la reformulation, etc. Alors, publier en ligne rapidement ! On ne le fait jamais au final. Sans compter l'aspect sécurité et maintenance du truc. Encore une fausse bonne idée !