Apache : mutualisation, inclusion et ordre
Par Nicolas Steinmetz. mardi 19 mai 2009, 17:36. Intégration apache bonnes pratiques configuration include mutualisation | Lien permanent.
Ordre
Une des fonctionnalités intéressante d'apache d'un point de vue administration est de pouvoir déposer des fichiers de configuration complémentaires sans avoir à toucher au fichier de configuration de base, et ce dans le répertoire /etc/httpd/conf.d/ ou /etc/apache/conf.d suivant la distribution utilisée.
Il faut néanmoins faire attention à un point, les fichiers sont chargés dans l'ordre alphabétique. Par ailleurs, dans une configuration avec une IP utilisant les virtualhost (qui ose ne pas les utiliser ?) il faut que le premier virtualhost chargé contienne la directive NameVirtualHost xxx.xxx.xxx.xxx:xx
Il vous faut donc adopter l'ordre suivant :
- Fichiers chargeant les modules apache requis pour le(s) site(s)
- Fichier chargeant le vhost avec la directive NameVirtualHost xxx.xxx.xxx.xxx:xx
- Reste des fichiers de configuration des virtualhosts
- Autres fichiers
Cela vous évitera de perdre comme moi 2h la semaine dernière à tenter de comprendre pourquoi l'authentification NTLM ne fonctionnait plus sur une url mais bien sur une autre. L'ordre alphabétique des fichiers faisait que j'avais inversé le point 1 et 2. Par contre, pour l'url d'un site situé en 3, comme le module avait été chargé en phase 2, alors l'authentification était fonctionnelle pour ce site...
Inclusion
Le module "core" d'apache fournit la directive Include très utile dans la cas où il faut reproduire une configuration identique pour plusieurs virtualhosts. Prenons le cas de deux sites réalisés avec le même outil et accessibles sous deux urls différentes (monsite.fr et monsite.com par ex). Ces deux sites possèdent le même jeu de réécriture d'url (ie celles fournit par le produit).
Une première et mauvaise façon de faire serait de créer 2 fichiers de configuration contenant à chaque fois l'ensemble de la configuration. En cas de modification d'une règle, il vous faut faire la modification à deux endroits.
Cela vous donnerait un fichier du type /etc/httpd/conf.d/www.monsite.fr.conf :
<VirtualHost *>
ServerName www.monsite.fr
DocumentRoot /var/www/monsite
<Directory /var/www/monsite/>
...
Ensemble d'instructions
...
</Directory>
...
[Jeu d'instrusctions de réécriture]
...
ErrorLog ...
AccessLog ...
</VirtualHost>
Idem pour monsite.com (/etc/httpd/conf.d/www.monsite.com.conf)
La bonne façon de faire est la suivante : /etc/httpd/conf.d/www.monsite.fr.conf
<VirtualHost *>
ServerName www.monsite.fr
Include /etc/httpd/application/directory.txt
Include /etc/httpd/application/rewrite_rule.txt
ErrorLog ...
AccessLog ...
</Virtualhost>
et /etc/httpd/conf.d/www.monsite.com.conf
<VirtualHost *>
ServerName www.monsite.com
Include /etc/httpd/application/directory.txt
Include /etc/httpd/application/rewrite_rule.txt
ErrorLog ...
AccessLog ...
</Virtualhost>
Avec /etc/httpd/application/directory.txt :
DocumentRoot /var/www/monsite
<Directory /var/www/monsite/>
...
Ensemble d'instructions
...
</Directory>
et /etc/httpd/application/rewrite_rule.txt :
[Jeu d'instrusctions de réécriture]
Ainsi, on peut mutualiser au maximum au niveau de la configuration d'apache, sans se priver de pouvoir rajouter des directives propres à un virtual host en incluant des fichiers supplémentaires.
Ex si on a une couche SSO pour un site et une version anonyme :
/etc/httpd/conf.d/intranet.monsite.fr.conf
<VirtualHost *>
ServerName intranet.monsite.fr
Include /etc/httpd/application/directory.txt
Include /etc/httpd/application/rewrite_rule.txt
Include /etc/httpd/application/authentification_SSO.txt
ErrorLog ...
AccessLog ...
</Virtualhost>
et /etc/httpd/conf.d/intranet.monsite.com.conf
<VirtualHost *>
ServerName intranet.monsite.com
Include /etc/httpd/application/directory.txt
Include /etc/httpd/application/rewrite_rule.txt
# Include /etc/httpd/application/authentification_SSO.txt
ErrorLog ...
AccessLog ...
</Virtualhost>
Bien sur, vous pouvez mettre vos fichiers ailleurs que dans /etc/httpd/application 
Commentaires
Excellent cette mutualisation ! Je connaissais ça pour Nginx mais pas pour Apache ... que j'utilise depuis plus longtemps. Comme quoi ...
Par contre question, y'a des variables de contexte ou autre ? Ou moyen de passer des variables à des fichiers inclus ? Pour faire des directives utilisant des "Match" (DirectoryMatch entre autre) génériques pour des besoins spécifiques ?
Pour les contextes, tu peux détailler un peu ?
Si tu penses à un truc genre la gestion dynamique des sous-domaines, je vois pas pourquoi cela ne serait pas possible (ou bien via d'autres directives apache). Quand Apache lis ton fichier de conf et inclus tes fichiers .txt (si on reprend mon exemple), alors c'est comme s'il voyait un fichier complet amha. Donc ce qui était valable dans un fichier unique doit être valable de la même façon avec les include.
Après dans le contenu de tes fichiers.txt, faut voir ce qui est vraiment générique et ce qui ne l'est pas - faut pas non plus transformer le binz en usine à gaz. Je m'en sers dans le cas présent pour gérer la conf de l'intranet groupe (basé sur eZ Publish) avec un vhosts avec une authentification SSO et un vhosts anonyme en fonction du routage réseau. En dehors de cet aspect authentification, les confs apache sont identiques en tout point (même dossier pour le DocumentRoot, etc).
Pour des machines mutualisées (avec des applicatifs divers), il faut voir dans quelle mesure c'est réalisable et ça ne complexifie pas la chose... Je me dis par ex que je vais pouvoir adopter cette logique pour la gestion des Reverse Proxy des sites web vélos. Par contre, pour d'autres RP reroutant tout et n'importe quoi, je suis pas sur que cela apporte grand chose ou que cela ne complexifie plus que cela ne simplifie les choses.
Non ben je pensais à ça (gestion dynamique des sous-domaines) donc pas besoin d'en dire plus.
Je trouve ça pratique pour mutualiser les règles au travers différents projets : les règles de réécriture sont à 90% identiques sur tous mes projets symfony ... un include ira plus vite que tout retaper à chaque fois.
Versionné, ça ira encore plus vite à déployer sur de nouveaux serveurs
Tant mieux si j'ai pu répondre à ta question.
Sur l'histoire des comportement dynamiques, en y réflechissant de bon matin, je pense que c'est faisable en fait avec des directives comme SetEnvIf (comme présenté ici avec la gestion de source pour l'authentification) ou des variables prennent des valeurs en fonction de règles que tu définies... Mod_include doit aussi permettre des choses mais je n'ai jamais joué avec pour le moment.