Apache et le DNS

### Apache HTTP Server

# Apache et le DNS

Cette page aurait pu être résumée par la phrase : ne demandez pas à Apache d'utiliser le DNS pour la lecture des fichiers de configuration. Si Apache doit utiliser le DNS pour récupérer ses fichiers de configuration, alors votre serveur peut être sujet à des problèmes de fiabilité (il peut tout simplement ne pas démarrer), ou s'ouvrir à des attaques et des vols d'information (y compris des utilisateurs qui pourraient "voler" des hits d'autres utilisateurs).

### Un exemple simple

Considérez ce court extrait de code de configuration :

>         <VirtualHost www.abc.dom>
>         ServerAdmin webgirl@abc.dom
>         DocumentRoot /www/abc
>         </VirtualHost>

Pour qu'Apache fonctionne correctement, il a absolument besoin d'au moins deux informations pour chaque hôte virtuel : le `ServerName` et au moins une adresse IP à laquelle ce serveur doit répondre. Cet exemple ne fait pas apparaître d'adresse IP ; Apache doit donc utiliser le DNS pour trouver l'adresse correspondant à `www.abc.dom`. Si pour telle ou telle raison, le service de noms de domaines n'est pas accessible au moment ou le serveur interprète ses fichiers de configuration, alors cet hôte virtuel ne pourra pas être configuré. Il ne pourra donc pas répondre aux requêtes émises vers cet hôte virtuel (les versions d'Apache antérieures à la 1.2 n'auraient même pas pu démarrer).

Supposons que le doamine `www.abc.dom` ait pour adresse 10.0.0.1. Considérez alors ce nouvel extrait de code de configuration :

>         <VirtualHost 10.0.0.1>
>         ServerAdmin webgirl@abc.dom
>         DocumentRoot /www/abc
>         </VirtualHost>

Apache doit alors effectuer une résolution DNS inverse pour trouver le nom `ServerName` pour cet hôte virtuel. Si cette résolution échoue, alors il devra partiellement désactiver cet hôte virtuel (les versions d'Apache antérieures à la 1.2 n'auraient même pas démarré). Si l'hôte virtuel est basé sur un nom de domaine alors il sera totalement inhibé, si par contre il se base sur une adresse IP, alors il tournera probablement. Cependant, si Apache devait générer une URL complète pour ce serveur, incluant le nom de domaine, l'URL produite ne pourrait être correctement constituée.

Voici un extrait qui élimine ces deux problèmes.

>         <VirtualHost 10.0.0.1>
>         ServerName www.abc.dom
>         ServerAdmin webgirl@abc.dom
>         DocumentRoot /www/abc
>         </VirtualHost>

### Refus de service

Il existe (au moins) deux situations où Apache refuse de fournir le service. Si vous exécutez une version antérieure à la version 1.2 d'Apache, votre serveur ne démarrera même pas si l'une des deux résolutions DNS mentionnées ci-avant échoue pour au moins un hôte virtuel. Dans certains cas, cette résolution peut ne même pas être sous votre contrôle. Par exemple, si `abc.dom` est l'un de vos clients, lequel contrôle son propre serveur DNS, ce dernier peut forcer votre serveur Apache (en version antérieure à 1.2) à s'arrêter au démarrage en supprimant simplement l'enregistrement du nom `www.abc.dom`.

Une autre situation est beaucoup plus pernicieuse. Considérez cet extrait de code de configuration :

>         <VirtualHost www.abc.dom>
>         ServerAdmin webgirl@abc.dom
>         DocumentRoot /www/abc
>         </VirtualHost>

>         <VirtualHost www.def.dom>
>         ServerAdmin webguy@def.dom
>         DocumentRoot /www/def
>         </VirtualHost>

Supposez que vous avez assigné 10.0.0.1 au domaine `www.abc.dom` et 10.0.0.2 au domaine `www.def.dom`. De plus, supposez que `def.com` contrôle son propre service DNS. Avec la précédente configuration, vous permettez à `def.com` de "voler" tout le trafic destiné à `abc.com`. Tout ce qu'ils auraient à faire pour y parvenir est d'assigner `www.def.dom` à l'adresse 10.0.0.1. Dans la mesure où ils contrôlent leur propre DNS, vous ne pouvez les empêcher de piéger leur enregistrement de `www.def.com`.

Les requêtes arrivant pour 10.0.0.1 (y compris toutes celles où les utilisateurs auront tapé une URL de la forme `http://www.abc.dom/qqchose`) seront toutes servies par l'hôte virtuel `def.com`. Mieux comprendre comment cela est possible demande une discussion plus détaillée sur la manière dont Apache traite des requêtes arrivant pour des hôtes virtuels. Un premier document descrivant ceci est disponible.

### L'adresse du "serveur principal"

L'addition du support d'hôtes virtuels basés sur les noms dans Apache 1.1 nécessite qu'Apache connaisse les adresses IP de l'hôte sur lequel est exécuté httpd. Pour obtenir cette adresse, il utilise soit le `ServerName` global (si défini) ou appelle la fonction C `gethostname` (qui renvoie une information similaire à celle donnée par la commande interactive "hostname"). Puis il procède à une résolution DNS pour cette adresse. Jusqu'à présent, il n'y a aucun moyen d'éviter cette résolution.

Si vous craignez que cette résolution échoue parceque votre serveur DNS est arrêté, alors vous popuvez ajouter le nom d'hôte dans le fichier `/etc/hosts` (où il devrait normalement déjà figurer, ne serait-ce que pour assurer un démarrage correct de la machine). Vous devrez en outre vous assurer que votre machine est configurée pour exploiter le fichier `/etc/hosts` en cas d'échec d'une résolution dynamique. Suivant l'OS que vous utilisez, ceci peut être fait en éditant le code `/etc/resolv.conf`, ou peut être `/etc/nsswitch.conf`.

Si votre machine n'a pas de résolution DNS à effectuer pour toute autre raison (par exemple parce qu'elle est isolée), alors vous pourrez néanmoins faire tourner Apache en initialisant la variable d'environnement `HOSTRESORDER` à "local". Tout ceci dépend de l'OS et des librairies de résolveur que vous utilisez. Les CGI sont également affectés sauf si vous utilisez la fonctionnalité `mod_env` pour contrôler l'environnement. Il est prudent de consulter les pages de manuel ou les FAQ spécifiques à votre OS.

### Astuces pour éviter ces problèmes

- utilisez des adresses IP dans les sections `<VirtualHost>`
- utilisez des adresses IP dans la clause `Listen`
- utilisez des adresses IP dans la clause `BindAddress`
- assurez vous que tous les hôtes virtuels on un `ServerName`
- créez un serveur `<VirtualHost _default_:*>` qui ne sert aucune page.

### Annexe: Directions futures

Cette situation vis-à-vis du DNS est largement insatisfaisante. Pour Apache 1.2, nous avons travaillé pour que le serveur puisse continuer à démarrer dans le cas de l'échec d'une résolution DNS, mais il est possible que nous puissions en faire plus. Toute écriture nécessitant l'usage d'adresses IP explicites dans le fichier de configuration n'est pas souhaitable dans le contexte Internet actuel où la rotation d'adresses est une nécessité.

Une parade au vol de service serait d'effectuer une résolution DNS inverse sur l'adresse IP renvoyée par la résolution directe, et comparer les deux noms. En cas de non concordance, cet hôte virtuel serait désactivé. Ceci impliquerait que la résolution DNS inverse soit correctement configurée (ce qui reste assez connu des administrateurs du fait de l'usage commun de la résolution inverse double par les serveurs FTP et les transposeurs TCP).

Dans tous les cas, il ne semble pas possible de garantir la fiabilité du démarrage d'un serveur web gérant des hôtes virtuels lorsque la résolution DNS a échoué, sauf si la définition de ces hôtes utilise des adresses IP explicites. Une solution partielle consistant à ignorer certaines portions du fichier de configuration serait encore pire que ne pas démarrer du tout, dans certains cas d'exploitation.

Par l'extension de l'usage de HTTP/1.1, les navigateurs et proxies fournissent de plus en plus souvent l'en-tête `Host`, et il deviendra possible d'éviter totalement la définition d'hôtes virtuels basés sur des adresses IP. Dans ce cas, un serveur Web n'aura plus de résolution DNS à effectuer pendant la configuration. Mais à la date de Mars 1997, ces fonctionnalités n'ont pas été suffisament largement déployées pour pouvoir être exploitées par des serveurs en situation critique.

### Apache HTTP Server