Configuration d'hôtes virtuels sur Apache avec support automatique des sous-domaines, du SSL, de l'authentification et avec le support des Alias

Jean Baptiste FAVRE

février 2010

Introduction

Ce document fait suite à celui-ci: Apache: Configuration d'hôtes virtuels avec support automatique des sous-domaines, du SSL et de l'authentification sous GNU/Debian Linux. Je ne reviendrai donc pas sur les détails, mais partirai directement de la situation obtenue.

L'installation, la configuration et l'exploitation d'un serveur apache peut devenir chronophage Il faut souvent adapter la configuration lorsque l'on souhaite ajouter un hôte virtuel. Découvrez comment cela peut être automatique. Un vhost à créer ? Un répertoire. Un vhost où l'utilisation du SSL est obligatoire ? Un lien symbolique. Un vhosts où l'authentification est obligatoire ? Encore un lien symbolique.

Compliqué ? Pas tant que ça. Suivez le guide.

Limitations de la première partie

Dans l'épisode précédent, nous avions réussi à obtenir une gestion automatique (comprendre sans redémarrage d'Apache) des sous-domaines, des accès SSL et de l'authentification. Cependant, ce système comporte plusieurs limitations, et de taille:

Dans cette partie, nous allons tâcher de remédier à la première limitation.

Résumé de l'épisode précédent

Voici à quoi nous étions arrivés dans l'épisode précédent:

tree /var/www/
mondomain.com/
|-- config
|   |-- htpasswd
|   |-- auth
|   |   `-- maitredumonde -> ../../www/maitredumonde
|   `-- ssl
|       |-- maitredumonde -> ../../www/maitredumonde
|       `-- webmail -> ../../www/webmail
|-- logs
`-- www
    |-- blog
    |-- maitredumonde
    |-- protected
    `-- webmail
Règles de ré-écriture pour le vhost mondomaine.com
########## Rewrite rules ##########
        RewriteEngine on

    ########## Rewrite rules 1 ##########
        RewriteCond %{HTTP_HOST} ^mondomaine.com
        RewriteRule ^/(.*) //www.mondomaine.com/$1 [L,R=301]

    ########## Rewrite rules 2 ##########
        RewriteCond %{HTTP_HOST} ^www.mondomaine.com
        RewriteCond %{REQUEST_URI} /([^/]+)(.*)
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^.* //%1.mondomaine.com%2 [L]

    ########## Rewrite rules 3 ##########
	RewriteCond %{HTTPS} ^off$
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com$
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/ssl/%1 -l
        RewriteRule ^/(.*) https://%1.mondomaine.com/$1 [L,R=301]

    ########## Rewrite rules 4 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/auth/%1 -l
        RewriteRule ^(.*) /var/www/mondomaine.com/config/auth/%1$1 [L]

    ########## Rewrite rules 5 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) /var/www/mondomaine.com/www/%1$1 [L]

Support des alias

Le fait que les règles obtenues comportent toutes le flag [L] indique qu'Apache doit arrêter toute tentative de ré-écriture d'URL. Entre autre effet de bord, ceci a pour effet de désactiver le support des Alias. Pourtant, ceux-ci sont parfois bien utiles, par exemple pour partager du code applicatif (blog en PHP) entre plusieurs vhosts.

Il faudrait donc pouvoir poursuivre la ré-écriture. Est-ce faisable/souhaitable dans tous les cas ? Non, notamment dans le cas des redirections d'URL (Règles 1 à 3). Celles-ci devront donc conserver le flag [L]. Quant aux autres, nous allons essayer de les modifier pour qu'Apache soit capable d'y détecter les alias.

Première étape, là où nous transformons des URL en chemin absolus, il faudrait pouvoir conserver des URL et utiliser la directive DocumentRoot. En fait, tout cela va être transparent pour vous: c'est Apache qui va d'abord considérer la ré-écriture comme un chemin absolu, puis comme un suffixe à DocumentRoot.

Je laisse pour l'instant de côté le bloc 4 (authentification) dans la mesure où nous aurons besoin des Alias pour le faire fonctionner correctement.

Le bloc 5 devient donc:

RewriteRules modifiés
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) %1$1

Malheureusement, ça ne marche toujours pas. Une lecture de la documentation apache consacrée à la ré-écriture d'URL plus tard, nous avons une piste: il faut utiliser le flag PT (passthrough), qui, comme l'indique la documentation est utilisé justement pour les directives Alias (entre autre). Notre bloc devient alors:

RewriteRules modifiés
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) %1$1 [PT]

Las, rien n'y fait. Si vous activez les logs (directive RewriteLog et RewriteLogLevel), vous constaterez que nos règles sont parcourues à nouveau. Argll !! Pas vraiment ce que l'on cherchait. Mais, toujours dans les logs, vous constaterez que le contexte change: la première fois, nous sommes dans le contexte initial, et nous passons ensuite dans le contexte subreq ou sous-requète. Et si nous cherchons subreq dans la documentation Apache (même page qu'au dessus), nous tombons sur un autre flag: NS pour nosubrequest.

Victoire ? Voyons donc ce que cela donne. Il faut maintenant indiquer quelles règles doivent être ou non prises en compte dans le contexte subreq. Il faut donc modifier toutes nos règles.

RewriteRules modifiés
    ########## Rewrite rules 1 ##########
        RewriteCond %{HTTP_HOST} ^mondomaine.com
        RewriteRule ^/(.*) //www.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 2 ##########
        RewriteCond %{HTTP_HOST} ^www.mondomaine.com
        RewriteCond %{REQUEST_URI} /([^/]+)(.*)
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^.* //%1.mondomaine.com%2 [NS,QSA,L,R=301]

    ########## Rewrite rules 3 ##########
	RewriteCond %{HTTPS} ^off$
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com$
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/ssl/%1 -l
        RewriteRule ^/(.*) https://%1.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 4 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/auth/%1 -l
        RewriteRule ^(.*) /auth/%1$1 [NS,QSA,PT]

    ########## Rewrite rules 5 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) /%1$1 [NS,QSA,PT]

Le flag QSA, dont je n'ai pas parlé, est là pour rajouter les éventuels querystring à l'URL ré-écrite.

Et là, ça marche ! Si vous avez défini un Alias dans la configuration d'apache, celui-ci est maintenant pris en compte. Elle est pas belle la vie ?

Cas particulier de l'authentification

Voici venu le moment de résoudre le problème de l'authentification. Nous avons vu que les Alias sont maintenant supportés. Les plus observateurs (attentifs ?) d'entre vous ont constaté que l'URL nécessitant l'authentification est préfixée par /auth (bloc n°4 pour les étourdis). Mais nous avons un tout petit problème: le répertoire n'existe pas. C'est là qu'interviennent les Alias. Nous allons "bêtement" définir un Alias auth qui pointera sur /var/www/mondomaine.com/config/auth/:

Définition de l'Alias auth
Alias /auth /var/www/mondomaine.com/config/auth

Configuration finale

Voici ce que donne la définition de notre vhost. Au passage, j'ai commenté le bloc n°3 dans le vhost SSL, ça évitera une boucle infinie :-/

/etc/apache2/sites-available/mondomaine.com
<VirtualHost *:80>
        ServerName mondomaine.com
        ServerAlias *.mondomaine.com
        ServerAlias *.mondomaine.net
        ServerAlias *.mondomaine.fr
        ServerAlias *.mondomaine.eu
        ServerAlias *.mondomaine.info

        ServerAdmin webmaster@mondomaine.com

        DocumentRoot /var/www/mondomaine.com/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/mondomaine.com/www/>
                Options FollowSymLinks
                AllowOverride none
                Order allow,deny
                allow from all
        </Directory>
        <Directory /var/www/mondomaine.com/config/auth/>
                AuthType Basic
                AuthName "Restricted Files"
                AuthUserFile /var/www/mondomaine.com/config/htpasswd
                Require user user1
        </Directory>

########## Log Directives
        ErrorLog /var/www/mondomaine.com/logs/error.log
        CustomLog /var/www/mondomaine.com/logs/access.log vhost_combined

########## Alias définition
        Alias /auth /var/www/mondomaine.com/config/auth

    ########## Rewrite rules 1 ##########
        RewriteCond %{HTTP_HOST} ^mondomaine.com
        RewriteRule ^/(.*) //www.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 2 ##########
        RewriteCond %{HTTP_HOST} ^www.mondomaine.com
        RewriteCond %{REQUEST_URI} /([^/]+)(.*)
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^.* //%1.mondomaine.com%2 [NS,QSA,L,R=301]

    ########## Rewrite rules 3 ##########
	RewriteCond %{HTTPS} ^off$
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com$
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/ssl/%1 -l
        RewriteRule ^/(.*) https://%1.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 4 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/auth/%1 -l
        RewriteRule ^(.*) /auth/%1$1 [NS,QSA,PT]

    ########## Rewrite rules 5 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) /%1$1 [NS,QSA,PT]

</VirtualHost>

<VirtualHost *:443>
        ServerName mondomaine.com
        ServerAlias *.mondomaine.com
        ServerAlias *.mondomaine.net
        ServerAlias *.mondomaine.fr
        ServerAlias *.mondomaine.eu
        ServerAlias *.mondomaine.info

        ServerAdmin webmaster@mondomaine.com

        DocumentRoot /var/www/mondomaine.com/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/mondomaine.com/www/>
                Options FollowSymLinks
                AllowOverride none
                Order allow,deny
                allow from all
        </Directory>
        <Directory /var/www/mondomaine.com/config/auth/>
                AuthType Basic
                AuthName "Restricted Files"
                AuthUserFile /var/www/mondomaine.com/config/htpasswd
                Require user user1
        </Directory>

########## Log Directives
        ErrorLog /var/www/mondomaine.com/logs/error.log
        CustomLog /var/www/mondomaine.com/logs/access.log vhost_combined

########## SSL Directives
        SSLEngine on
        SSLCertificateFile /var/www/mondomaine.com/config/mondomaine.com.pem
        SSLCertificateKeyFile /var/www/mondomaine.com/config/mondomaine.com.pem
        SSLCACertificateFile /var/www/mondomaine.com/config/ca.crt

########## Alias définition
        Alias /auth /var/www/mondomaine.com/config/auth

    ########## Rewrite rules 1 ##########
        RewriteCond %{HTTP_HOST} ^mondomaine.com
        RewriteRule ^/(.*) //www.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 2 ##########
        RewriteCond %{HTTP_HOST} ^www.mondomaine.com
        RewriteCond %{REQUEST_URI} /([^/]+)(.*)
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^.* //%1.mondomaine.com%2 [NS,QSA,L,R=301]

    ########## Rewrite rules 3 ##########
	RewriteCond %{HTTPS} ^off$
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com$
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/ssl/%1 -l
        RewriteRule ^/(.*) https://%1.mondomaine.com/$1 [NS,QSA,L,R=301]

    ########## Rewrite rules 4 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteCond /var/www/mondomaine.com/config/auth/%1 -l
        RewriteRule ^(.*) /auth/%1$1 [NS,QSA,PT]

    ########## Rewrite rules 5 ##########
        RewriteCond %{HTTP_HOST} ^([^.]+).mondomaine.com
        RewriteCond %{HTTP_HOST} !^www.mondomaine.com$
        RewriteCond /var/www/mondomaine.com/www/%1 -d
        RewriteRule ^(.*) /%1$1 [NS,QSA,PT]

</VirtualHost>

Conclusion

Voilà un des problèmes identifiés au début résolu. Prochaine étape, éviter d'avoir à copier les règles dans chaque vhost. Impossible ? À voir. Une piste que je vous laisse creuser. Quelques indices qui pourraient vous aider:

Format

Ce document est disponible aux formats suivants:

À propos de Jean Baptiste FAVRE

Je suis responsable d'exploitation dans le domaine de l'hébergement. Je travaille, entre autres, sur la virtualisation et l'amélioration des performances web. De temps en temps, j'arrive à décrocher de mon clavier pour lire un bon bouquin en écoutant de la musique.

License

Creative Commons License Cette publication est publiée sous contrat Creative Common by-nc-sa

Valid XHTML 1.0 Strict |  Valid CSS |  contrat Creative Common by-nc-sa

Table des matières

  1. Introduction
  2. Limitations de la première partie
  3. Résumé de l'épisode précédent
  4. Support des alias
  5. Cas particulier de l'authentification
  6. Configuration finale
  7. Conclusion
  8. Format
  9. À propos ...
  10. License