Personnaliser le listage des dossiers dans Apache

Apache httpd est un super serveur Web qui propose un tas de modules pour faire ce dont on a besoin. En général sur les distributions Linux populaires il est préconfiguré pour afficher la liste des fichiers présents si on accède à un répertoire qui ne contient pas de fichier index.html ou index.php. Nous allons voir ici comment personnaliser cet affichage pour le rendre plus pratique et plus beau.

Je pars d'une distribution Debian, la configuration par défaut est différente sur d'autres systèmes comme par exemple FreeBSD.

Capture d'écran d'une liste de fichiers générée Apache
Le listage par défaut de Apache

Processus d'affichage de l'index

Lorsqu'on demande l'accès à un chemin, le serveur va d'abord essayer de trouver un fichier d'index. S'il n'en trouve pas, il va déclencher le listage du dossier. Cet aiguillage se fait via le module mod_dir activé par défaut.

Dans le fichier /etc/apache2/mods-enabled/dir.conf on peut voir le contenu suivant :

<IfModule mod_dir.c>
        DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

C'est ici que sont définis les différents noms de fichiers pouvant être considérés comme index. Si un dossier contient plusieurs fichiers candidats comme par exemple index.html et index.php alors ce sera le premier de la liste qui sera affiché.

Ainsi si aucun fichier d'index n'est présent alors la génération de la page de listage va se faire par le module mod_autoindex mais à la condition que l'option Indexes soit activée pour le dossier.

Dans le fichier /etc/apache2/apache2.conf on trouve entre autres :

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

Ici l'option est activée pour le répertoire par défaut /var/www/ et ses sous-dossiers.

Le module de listage

Les inconvénients de la configuration par défaut

Tout se passe dans le fichier /etc/apache2/mods-enabled/autoindex.conf qui contient par défaut un certain nombre de choses pour améliorer déjà pas mal l'aspect de la page, comme l'option FancyIndexing et HTMLTable qui créent un affichage enrichi et mis en forme dans un tableau HTML avec des colonnes de tri.

Sans ces options, mon dossier ressemble à cela :

Capture d'écran d'un listage Apache minimaliste

Je suis satisfaite de l'affichage fancy mais je voudrais faire certains changements :

Retrait des colonnes superflues

Le retrait de la colonne de description se fait très simplement en rajoutant l'option SuppressDescription à la directive IndexOptions située en début de fichier.

Pour gagner de la place et parce que les dates de fichiers sont rarement les bonnes, j'ai décidé de supprimer aussi la colonne Last modified avec SuppressLastModified.

L'entête et le pied de page

En ce qui concerne ces éléments, le module est réglé pour aller chercher des fichiers HEADER.html et README.html différents pour chaque dossier affiché. Moi je veux des fichiers uniques pour tout le domaine donc je configure les deux directives suivantes comme ceci :

ReadmeName /.footer.html
HeaderName /.header.html

Le / permet de réutiliser les mêmes fichiers partout dans l'arborescence. J'ai fait des fichiers cachés (ils commencent par un point) pour éviter leur apparition dans la liste.

Pour le moment mon entête contient seulement un bloc <h1> et mon pied de page un <a>.

Capture d'écran d'un listage Apache plus joli

Le mélange entre l'affichage d'une liste de ressources et un contenu directement sur la page me fait beaucoup penser au protocole Gopher des années 90 et son équivalent moderne Gemini.

Affichage mobile, favicon et titre d'onglet

Pour l'affichage mobile il faut rajouter une ligne dans le <head> et je vais en profiter pour ajouter un titre d'onglet et mettre un favicon.

Par défaut le serveur rajoute l'entête HTML suivant :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /</title>
 </head>
 <body>

Pour désactiver cet entête automatique il faut rajouter l'option SuppressHTMLPreamble à IndexOptions. Ensuite on est libre de mettre le notre. À noter que du coup il faut rajouter les balises fermantes dans l'autre fichier, même si leur absence ne pose jamais problème dans la réalité.

Mon fichier .header.html ressemble maintenant à ça :

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/png" href="https://example.com/assets/favicon.png">
  <title>data.example.com</title>
 </head>
 <body>

L'encodage est par défaut en UTF-8 donc je ne fais que l'expliciter. C'est la propriété de viewport qui permet de corriger l'affichage.

Il existe une directive IndexStyleSheet pour spécifier une feuille de style CSS mais elle ne fonctionne pas avec SuppressHTMLPreamble, la solution est de spécifier un fichier CSS dans l'entête ou d'incorporer un bloc <style>.

Capture d'écran d'un listage Apache joli

Voilà le résultat final pour le moment. On ne peut pas tout personnaliser, par exemple pas possible de changer la langue des labels. En fouillant un peu on s'aperçoit que les labels sont codés en dur dans le fichier source mod_autoindex.c, par exemple pour les titres de colonnes à partir de la ligne 1584.

Le principal intérêt c'est d'utiliser un module par défaut qui génère des pages HTML, ce qui m'évite de devoir passer par des navigateurs de fichiers en PHP plus lourds et peut-être moins sécurisés.