4.5. Configuration

Apache a vu ses fichiers de configuration complètement remaniés entre les versions 1.x et les versions 2.x. Les anciennes configuration étaient très monolithiques par défault. Il y avait généralement un seul fichier de configuration (/etc/httpd/httpd.conf), accompagné parfois de quelques inclusions correspondant à des virtualhosts. Dans sa version 2.x, c'est une toute autre histoire... En voulant faire plus « modulaire », les développeurs n'ont pas forcément fait plus simple. Chacun appréciera.

4.5.1. Fichiers de configuration

La totalité de la configuration d'Apache 2.x se trouve dans une arborescence sous /etc/apache2. Plusieurs sous-répertoires à cet emplacement ont des vocations particulières.

  • conf.d : contient des « morceaux » de configuration générale non inclus dans le fichier principal. Cela permet, lors de l'installation de modules, d'ajouter des morceaux de configuration qui leur sont propres sans avoir à modifier le fichier de configuration principal.

  • mods-available : fichiers de chargement de tous les modules Apache disponibles sur le système.

  • mods-enabled : liens vers les fichiers de chargement requis

  • sites-available : fichiers de configuration de tous les sites web sur le système.

  • sites-enabled : liens vers les fichiers de configuration des sites web activés pour le serveur.

Le fichier ports.conf, aussi dans ce répertoire, contient les numéros de ports sur lesquels apache doit écouter. Enfin, la configuration générale du serveur se trouve dans le fichier apache2.conf de ce même répertoire.

4.5.2. Configuration générale

La configuration générale définit les grands paramètres régissant le fonctionnement du serveur. La section mpm_*_module par exemple, définira les paramètres appliqués au MPM en vigueur.

Pour le MPM pre-fork, on peut par exemple définir combien de processus Apache doit initialement lancer pour traiter les requètes (StartServers). Apache pourra lancer d'autres processus (à concurence de MaxClients) si les processus sont tous occupés. Apache fera en sorte d'avoir toujours MinSpareServers libre d'avance, et commencera à supprimer des processus lorsque plus de MaxSpareServers seront au repos. Accessoirement, apache peut décider de supprimer un processus lorsqu'il a traité MaxRequestsPerChild.

Le nombre de requètes servies en keep-alive évoqué plus haut est défini par le paramètre MaxKeepAliveRequests, tandis que la durée maximum d'une connexion est définie dans KeepAliveTimeout. Les paramètres permettent de conserver une seule connexion ouverte et d'y faire transiter plusieurs requètes. Cela permet de réduire le nombre d'établissement de connexions, voire de mettre en oeuvre du pipelining HTTP.

Mais l'utilisation de cette fonctionnalité (elle est activée par défaut grâce à KeepAlive On) a une conséquence : elle mobilise les processus plus longtemps que nécessaire. En effet, si le client HTTP demande de conserver la connexion ouverte, elle le restera jusqu'a l'expiration de KeepAliveTimeout secondes (ou après que MaxKeepAliveRequests aient été satisfaites, ce qui a peu de chances de se produire avec la valeur par défaut et en conditions normales). La valeur configurée par défaut étant de 15 secondes, cela implique que chaque client en keep-alive va mobiliser un processus pendant 1/4 de seconde. Il est donc recommandé de réduire fortement la valeur de KeepAliveTimeout pour la passer à 5 secondes maximum. Il faudra peut être augmenter la valeur de MaxClients si le serveur est chargé, afin de compenser l'effet du keep-alive.

Les séries de directives Limit* et RLimit* permettent respectivement de régler finement un certain nombre de paramètres HTTP et système d'Apache. Dans la plupart des cas, on pourra laisser les valeurs à leur défaut. LimitRequestBody, qui limite la taille d'une requète HTTP et n'a aucune valeur par défaut pourra être positionné à une valeur proche de celle définie pour la taille maximale d'un POST PHP (voir post_max_size, Section 5.2.2, « Limites »).

Deux autres paramètres doivent être modifiés par rapport à la configuration par défaut. ServerTokens permet de modifier les informations renvoyées par le serveur dans les en-têtes réponse HTTP. Il est préférable de mettre sa valeur à Prod, qui se contente de repondre Apache dans les en-tête.

alice@linus:~$ telnet 192.168.17.139 80
Trying 192.168.17.139...
Connected to 192.168.17.139.
Escape character is '^]'.
HEAD / HTTP/1.0

HTTP/1.1 200 OK
Date: Sun, 10 Jun 2007 15:18:13 GMT
Server: Apache/2.2.3 (Ubuntu) ❶

Connection: close
Content-Type: text/html; charset=UTF-8

Connection closed by foreign host.

...  ❷

alice@linus:~$ telnet 192.168.17.139 80
Trying 192.168.17.139...
Connected to 192.168.17.139.
Escape character is '^]'.
HEAD / HTTP/1.0

HTTP/1.1 200 OK
Date: Sun, 10 Jun 2007 15:18:56 GMT
Server: Apache ❸
Connection: close
Content-Type: text/html; charset=UTF-8

Connection closed by foreign host.
alice@michel:~$

En-tête renvoyé par Apache avec la configuration par défaut (ServerTokens Full).

Changement de configuration et redémarrage d'Apache.

En-tête renvoyé par Apache avec la configuration ServerTokens Prod.

Afin d'être complet sur le masquage de version, il faudra aussi modifier la valeur par défaut de ServerSignature en la passant à Off. Cette variable détermine l'affichage du nom du serveur et de sa version sur les pages générées automatiquement par le serveur (erreurs, listings de répertoires, etc...).

Le fichier principal contient ensuite des directives pour quelques modules nécessitant une configuration globale :

  • mod_alias : lien entre une URL spécifique et un répertoire

  • mod_autoindex : generation d'index de répertoire automatique

  • mod_mime : gestion et surcharge des types mime du système

  • mod_negotiation : négotiation de la priorité de la langue

  • mod_setenvif : changement de « variables d'environnement » en fonction de paramètres

  • mod_status : état du dæmon et de l'occupation des différents threads/processus

  • mod_info : informations sur la configuration

4.5.3. Site par défaut et VirtualHosts

Dans sa version 1.1, le protocole HTTP transmet l'en-tête Host: dans les requètes. Cela permet d'héberger des serveurs Web « virtuels » avec des noms différents (www.exemple.com, www2.exemple.com, www.autreexemple.com, ...) sur une seule machine physique ayant une seule adresse IP. Sans cet en-tête, impossible de savoir à quel serveur « virtuel » (virtualhost) le client désire accéder. Dans ce cas, c'est le serveur par défaut qui répond.

Les paramères du serveur par défaut sont définis dans /etc/apache2/sites-available/default. Ce fichier est principalement constitué des directives :

NameVirtualHost *
<VirtualHost *>
...
</VirtualHost>

NameVirtualHost permet d'indiquer à Apache que nous allons configurer des serveurs virtuels par nom (en analysant l'en-tête client Host:), et ce, sur n'importe quelle adresse IP de la machine (« * »).

Tous les paramètes inclus en suite entre les balises <VirtualHost *> et </VirtualHost> définissent les paramètres du serveur par défaut (représenté par « * » la aussi). Ce serveur sera utilisé lorsque l'en-tête « Host: » reçu par un client ne correspondra à aucun hôte virtuel défini. Par exemple, si les hôtes virtuels www.exemple.com et www.autreexemple.com sont définis et qu'une requète HTTP est reçue avec l'en-tête Host: www.serveur.net, c'est le serveur par défaut qui sera utilisé.

Le serveur par défaut est défini dans un serveur virtuel, mais ce n'est pas une obligation. Ses directives de configuration auraient très bien pu apparaître dans le contexte général (hors <VirtualHost *> ... </VirtualHost> ).

Si des serveurs additionels virtuels doivent être définis, il faudra créer d'autres entrées <VirtualHost *>. Par exemple :

<VirtualHost www.exemple.com>
...
</VirtualHost>

Il est préférable de mettre chaque configuration d'hôte virtuel dans un fichier propre sous /etc/apache2/sites-available puis d'indiquer à Apache que ce site doit être activé avec a2ensite (Cf. Section 4.5.4.3, « Exemple »).

4.5.4. Création d'un VirtualHost

Quelques paramètres suffisent à mettre en œuvre un serveur virtuel basique. Les différents paramètres utilisés dans l'hôte virtuel « default » sont décrits ici.

4.5.4.1. Balises

  • Les balises <Directory> et </Directory> encadrent des paramètres de configuration qui vont s'appliquer au répertoire du système de fichiers donné en paramètre, ainsi qu'a tous ses sous répertoires. Par exemple, ce qui est inclus dans la section ci-dessous sera appliqué à la totalité du système de fichiers, sauf si une autre directive plus précise est appliquée par la suite.

    <Directory />
      Options FollowSymLinks
      AllowOverride None
    </Directory>

  • Les balises <Location> et </Location> sont quasiment identiques à Directory à la différence qu'elles représentent un chemin de l'URL demandée par le client. <Location /> n'est donc pas la même chose que <Directory /> : dans le premier cas nous appliquons des directives à la racine du stie, dans l'autre cas à la racine du filesystem !

  • Les balises <Files> et </Files> permettent de restreindre l'application de directives à certains fichiers. On pourra utiliser des expressions régulières dans la spécification du nom de fichier en ajoutant « ~ » dans la balise (<Files ~ ...>). Un exemple est donné dans le chapitre consacré à PHP (Section 5.2.2, « Limites »). Pour plus de clarté, on péfèrera probablement la directive <FilesMatch>, traitant exclusivement des expressions régulières.

4.5.4.2. Directives

  • ServerAdmin permet de définir l'email du webmaster du site. Lors de l'affichage d'une page d'erreur, cette adresse email sera affichée (en fonction du paramètre utilisé pour ServerSignature, voir Section 4.5.2, « Configuration générale »).

  • DocumentRoot indique l'emplacement de la racine du site Web sur le système de fichier. Lorsqu'un client demandera http://www.exemple.com/page.html, Apache essayera de lire le ficher page.html dans le répertoire pointé par DocumentRoot.

  • ScriptAlias indique à Apache l'emplacement du répertoire cgi-bin, dans lequel on autorisera l'exécution de scripts. Les directives placées dans la balise <Directory "/usr/lib/cgi-bin"> permettent de préciser la configuration du répertoire contenant les scripts.

  • ErrorLog indique à Apache le chemin du fichier contenant les logs d'erreur pour cet hôte virtuel. Le niveau de sensibilité est paramétré par LogLevel.

  • CustomLog permet lui d'utiliser un log personalisé (défini dans le fichier de configuration principal) afin de logguer les requètes client.

  • Alias est un directive qui est gérée par mod_alias. Elle permet de faire correspondre le chemin de la page dans l'URL à un emplacement physique sur le serveur. Ainsi, dans la configuration par defaut, l'accès à l'URL http://serveur/doc/ renverra le contenu du répertoire /usr/share/doc/.

Au sein de chaque section des paramètres permettent de configurer le comportement d'Apache.

  • La directive Options indique les fonctionnalités disponibles dans un répertoire particulier. FollowSymLinks indique à Apache qu'il peut suivre les liens symboliques; Indexes qu'il peut générer un index du répertoire si aucun fichier index.html n'est présent. D'autres options moins importantes existent et sont détaillées dans le manuel d'Apache.

  • AllowOverride indique quels sont les paramètres que l'on peut surcharger en plaçant un fichier .htaccess dans un répertoire. Cette fonctionnalité permet de laisser le contrôle sur certains paramètres à des utilisateurs n'ayant pas accès à la configuration Apache.

    Il conviendra de désactiver cette possibilité de surcharge (avec AllowOverride none) sauf si elle est vraiment requise. En effet, si on autorise la surcharge, Apache va devoir vérifier dans chaque sous répertoire si un fichier .htaccess est présent. Par exemple, si un navigateur demande un objet situé dans le répertoire /var/www/documents/apache/documentation/2/2/3/francais/ etc qu'AllowOverride est positionné à une autre valeur que none pour le répertoire /, Apache va devoir chercher un fichier .htaccess dans chacun des répertoires du chemin et appliquer les éventuelles directives trouvées au passage.

4.5.4.3. Exemple

alice@ubuntu:~$ mkdir /home/alice/{monsiteouebe,meslogs}
alice@ubuntu:~$ echo "<html><head><title>hello</title></head><body> \
<h1>En construction</h1></html>" >  /home/alice/monsiteouebe/index.html
alice@ubuntu:~$ sudo -i
Password:
root@ubuntu:~# cat /etc/apache2/sites-available/site_alice
<VirtualHost *>
  ServerAdmin alice@exemple.org
  ServerName alice.exemple.org
  DocumentRoot /home/alice/monsiteouebe/

  <Directory /var/www/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
  </Directory>

  ErrorLog /home/alice/meslogs/error.log

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel info

  CustomLog /home/alice/meslogs/access.log combined
  ServerSignature Off
</VirtualHost>
root@ubuntu:~# echo 192.168.17.139 alice.exemple.org >> /etc/hosts
root@ubuntu:~# a2ensite site_alice
Site site_alice installed; run /etc/init.d/apache2 reload to enable.
root@ubuntu:~#  /etc/init.d/apache2 reload
 * Reloading web server config...                                    [OK]
root@ubuntu:~#

4.5.5. Contrôle d'accès

Apache permet de paramètrer finement l'accès aux ressources hébergées. La grande diversité de modules permet d'utiliser des types d'authentification variés : fichier de mots de passe, base de données, LDAP, radius, certificats, ... Le serveur possède aussi des fonctionnalités de filtrage afin de restreindre l'accès aux ressources à certaines IP autorisées. Ces possibilités sont combinables entre-elles (authentification et filtrage).

4.5.5.1. Authentification

L'authentification peut être mise en œuvre très simplement dans Apache à l'aide de fichiers de mots de passe. C'est tout à fait acceptable pour un petit site gérant un petit nombre d'utilisateurs qui changent peu. Pour des configurations nécessitant un plus grand nombre d'utilisateurs il vaudra mieux d'utiliser des bases de données.

Deux type d'authentifications sont possibles : l'authentification basic et digest. La première se contente d'envoyer la chaîne de caractères utilisateur:mot_de_passe encodé en Base64 ([RFC2617]) au serveur. Ce mode est peu sécurisé : n'importe quelle personne pouvant capturer la conversation client serveur pourra retrouver l'identificant et le mot de passe.

L'authentification digest en revanche fonctionne différemment : lorsque le client cherche à se connecter au serveur, le serveur lui indique qu'il faut s'authentifier et lui transmet un challenge qui servira au client, grâce à une fonction de hashage, à construire une chaîne d'authentification. Le serveur pourra vérifier sans ambiguïté cette chaîne puisqu'il possède les même informations. ([RFC2617], « 3.3 Digest Operation », p. 17). Dans ce mode, le mot de passe et l'identifiant ne circulent jamais en clair sur le réseau et un éventuel attaquant ne pourra obtenir ces informations. L'exemple d'implémentation ci-dessous force le serveur à demander une authentification pour les accès aux documents situés sous le répertoire « private » :

<Location /private/>
  AuthType Digest
  AuthName "Zone privee" ❶
  AuthDigestDomain /private/ http://www.exemple.com/private/ ❷

  AuthDigestProvider file ❸
  AuthUserFile /var/www/.users ❹
  Require valid-user ❺
</Location>

Le non du « realm » (royaume !). C'est une zone logique pour laquelle on utilise la même authentification.

Définit l'URL de base pour laquelle s'applique l'authentification

Indique que les données d'authentification sont dans un fichier (valeur par défaut). mod_auth_digest peut aussi utiliser des bases de données.

Fichier contenant la liste des utilisateurs et leurs paramètres d'authentification.

Un utilisateur valideet authentifié est obligatoire !

Il faudra créer le fichier /var/www/.users avec l'utilitaire htdigest afin de constituer le liste des utilisateurs.

root@ubuntu:/var/www# htdigest -c .users "Zone privee" alice ❶
Adding password for alice in realm zoneprivee.
New password: 
Re-type new password: 
root@ubuntu:/var/www# cat .users
alice:Zone privee:cca4760367f40dafae44b6ae98d65498
root@ubuntu:/var/www# 

« Zone privee » doit correspondre au realm défini dans la configuration.

4.5.5.2. Restrictions

Apache permet d'implémenter un « filtrage » d'accès par adresse IP avec les directives Order, Allow et Deny. Ces directives peuvent apparaître dans les sections Location ou Directory.

Order peut prendre les valeurs Deny,Allow ou Allow,Deny. La formulation de la directive Order n'est pas particulièrement intuitive. Le tableau ci-dessous aidera à y voir plus clair.

Tableau 4.1. Apache : détermination de la restriction

CorrespondanceRésultat pour Allow,DenyRésultat pour Deny,Allow
Allow correspondRequète autoriséeRequète autorisée
Deny correspondRequète refuséeRequète refusée
Aucune corrrespondanceDefaut sur la 2ème directive: RefuséDefaut sur la 2ème directive: Autorisé
Allow et Deny correspondentLa dernière correspondance décide : RefuséeLa dernière correspondance décide : Autorisée


A titre d'exemple, les règles ci-dessous demandent à Apache de ne renvoyer les objets qu'aux requètes en provenance du réseau 192.168.17.0/24. Le autres recevront une réponse 403 - Forbidden.

<Location />
  Order Deny,Allow
  Deny from all
  Allow from 192.168.17.0/24
</Location>

4.5.5.3. Modules divers

Apache, toujours grâce aux modules, peut faire beaucoup plus : réécriture d'URL (mod_rewrite), proxy HTTP (mod_proxy), détection d'attaques applicatives (mod_security), correction de fautres d'othographe dans les URL (mod_speling[9]), affichage de pages automatiquement dans la langue préférée du visiteur (mod_negotiation), etc... On se reportera à la documentation d'Apache pour la liste des modules officiels et leur directives de configuration.



[9] Orthographié correctement, il devrait s'appeler mod_spelling. On appréciera l'humour des développeurs d'Apache :)