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.
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.
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
( |
❷ | Changement de configuration et redémarrage d'Apache. |
❸ | En-tête renvoyé par Apache avec la configuration
|
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
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 »).
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.
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.
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.
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:~#
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).
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). |
❹ | 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. |
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
Correspondance | Résultat pour Allow,Deny | Résultat pour Deny,Allow |
---|---|---|
Allow correspond | Requète autorisée | Requète autorisée |
Deny correspond | Requète refusée | Requète refusée |
Aucune corrrespondance | Defaut sur la 2ème directive: Refusé | Defaut sur la 2ème directive: Autorisé |
Allow et Deny correspondent | La dernière correspondance décide : Refusée | La 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>
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 :)