<UPDATE> : ce document a été mis à jour. Vous pouvez (et devriez) le lire, mais la configuration finale est décrite là: Configuration d'hôtes virtuels sur NGinx avec support automatique des sous-domaines, du SSL et de l'authentification.</UPDATE>
English version is available here: NGinx automatic vhosts configuration with subdomains, SSL and authentication support.
Introduction
L'installation, la configuration et l'exploitation d'un serveur web 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 pour lequel 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.
Hôtes virtuels, principes
Le serveur web NGinx est capable de gérer des hôtes virtuels, c'est-à-dire que l'on peut héberger plusieurs domaines différents sur la même IP. Le choix s'effectue en fonction du contenu de la requète HTTP. Le champ Host détermine l'hôte virtuel qui devra traiter la requète.
Ceci est très facile, sauf lorsque l'on souhaite travailler en SSL. En effet, dans le cas de SSL, la négotiation de la clef de chiffrement intervient avant tout envoi de requète HTTP. Ce qui est logique d'un point de vue confidentialité de l'information pose néanmoins un problème: à moins d'avoir un certificat SSL contenant tous les nom de domaines gérés par le serveur, il devient impossible d'héberger plusieurs noms de domaine sur la même adresse IP. Il existe bien quelques exceptions (on obtient ainsi un certificat "wildcard" pour *.mondomaine.tld), mais celles-ci sont généralement limitées aux sous-domaines d'un domaine particulier (ici mondomaine.tld). Si vous souhaitez ajouter mondomaine.fr au même certificat par exemple, et bien sachez qu'aucun marchand de certificat ne vous le propose.
Vous pouvez bien sûr générer votre propre certificat (c'est ce que j'ai fait), mais vos visiteurs auront alors un avertissement car soit votre certificat est auto-signé, soit, plus rare, vous avez votre propre CA qui n'est évidemment pas intégrée dans les navigateurs.
En attendant, nous partirons du principe que 1 IP = 1 domaine SSL.
Préparation de l'environnement
Naturellement, l'automatisation demande un minimum d'organisation. Personnellement, j'ai choisi l'organisation suivante:
Comme vous l'aurez deviné, le rôle des répertoires est le suivant:
- config
- Contiendra toute la configuration "magique":
- auth
- Les liens symboliques vers les sous-domaines (subdir*) nécessitant une authentification.
- ssl
- Les liens symboliques vers les sous-domaines (subdir*) nécessitant un accès SSL.
- logs
- Ici, nous aurons les logs d'accès ainsi que les logs d'erreur pour le domaine concerné
- www
- La racine de l'arborescence web où se trouveront nos pages et scripts éventuels et les sous-domaines (subdir*).
Maintenant que nous avons notre structure de répertoires, prenons quelques instants pour définir comment notre système devra se comporter.
Installation et configuration de NGinx
La configuration de NGinx ci-dessous est une configuration de tests. Elle ne tiendra certainement pas la charge et ne correspondra vraisemblablement pas à vos besoins. Mais sa simplicité permet de mieux comprendre ce qui se passe.
Vous noterez l'apparition de la directive log_format: je suis parti de la référence combined et y ai ajouté $host afin d'avoir le champ HTTP Host dans le fichier de log. C'est important car chaque domaine (et tous les sous-domaines associés) n'aura qu'un seul fichier de logs.
Configuration du domaine mondomaine.com
Passons à la configuration du domaine mondomaine.com. Ajoutez les 2 configurations suivantes dans le fichier /etc/nginx/sites-available/mondomaine.com
Là encore, j'ai adapté la directive access_log afin de lui faire prendre en compte le format défini dans le fichier global.
Je laisse volontairement de côté la génération du certificat SSL. Ceci fera l'objet d'une autre publication.
Cas du vhost par défaut
Selon que vous montez un hébergement mutualisé ou dédié, la solution diffèrera. L'objectif, en tout cas, est de gérer le cas, pas si improbable que cela, où vous recevez une requète à destination d'un domaine que vous n'hébergez pas. Il est enfantin de forger une requète HTTP de toute pièce et vous devez le prendre en compte.
Pour cela, il faut définir un vhost par défaut. Il sera utilisé par défaut, car il sera défini en premier.
Créez un fichier /etc/nginx/site-available/0000-default et ajoutez-y la configuration suivante:
Ici, je considère que nous sommes sur un serveur dédié. Il est donc envisageable de rediriger tout le traffic vers notre "vrai" domaine.
Par exemple, toute requète vers http://ip_du_serveur sera traitée par ce vhost et le visiteur redirigé vers http://www.mondomaine.com/
Enfin, il faut activer le vhost
Règles de comportement
Maintenant que nous avons une configuration fonctionnelle, il est temps de s'intéresser au comportement que nous attendons de notre serveur web.
Nous souhaitons héberger le domaine mondomaine.com.
- Nous devons rediriger mondomaine.com vers www.mondomaine.com.
- Nous voulons pouvoir obtenir, le plus simplement possible, différents sous-domaines. Par exemple:
- blog.domaine.com doit être accessible en HTTP ou en SSL. L'authentification est gérée par l'application elle-même.
- webmail.domaine.com doit être obligatoirement en SSL. L'authentification est gérée par l'application elle-même.
- protected.domaine.com ne sera accessible qu'après authentification, mais l'accès n'est pas forcé en SSL.
- maitredumonde.domaine.com ne sera accessible qu'après authentification, mais l'accès est en plus forcé en SSL.
- Comme nous avons également loué le domaine mondomaine.fr, il faut que les 2 pointent sur le même espace d'hébergement.
En ce qui concerne les alias de domaines (différentes extensions tld), il est nécessaire de modifier la configuration du vhost en ajoutant les directives ServerAlias. En effet, les domaines n'appazraissant ni en ServerName, ni en ServerAlias seront traités par le vhost par défaut.
Règles de ré-écriture
Maintenant que nous avons défini nos règles de comportement, il est temps de préparer nos rewrite Rules. C'est en effet grâce à cette fonctionnalité de NGinx que nous pourrons parvenir à nos fins. Naturellement, nous ne nous arrêtrons pas aux quelques sous-domaines que nous avons identifié. Il faut faire des règles qui puissent être le plus générique possible.
- Toute requète au domaine http://mondomaine.com est redirigée vers http://www.mondomaine.com
Ceci permet d'éviter les
duplicate contentset d'optimiser un peu le référencement Google.- Toute requète au domaine http://sslsubdir.mondomaine.com est redirigée vers https://sslsubdir.mondomaine.com
Il suffit que le répertoire
/var/www/mondomaine.com/www/sslsubdirexiste et que le lien symboliquesslsubdirsoit détecté dans le répertoire/var/www/mondomaine.com/config/ssl/.- Toute requète au domaine http://www.mondomaine.com/subdir est redirigée vers http://subdir.mondomaine.com
Là encore, il est question d'éviter la duplication de contenu. Il suffit que le répertoire
/var/www/mondomaine.com/www/subdirexiste.- Toute requète au domaine http://subdir.mondomaine.com est ré-écrite en
/var/www/mondomaine.com/www/subdir. Il suffit que le répertoire
/var/www/mondomaine.com/www/subdirexiste.
Vous aurez remarqué qu'il n'y a pas de règle n°4. C'est normal, il s'agit de la règle qui va gérer l'authentification. Nous l'ajouterons plus tard.
Configuration de l'authentification
Il est temps maintenant de protéger nos répertoires sensibles. Pour cela, il faut tout d'abord créer le fichier qui contiendra les couples nom d'utilisateur et mot de passe. Pour ce faire, nous allons tout simplement créer le premier utilisateur:
Ensuite, pour les utilisateurs suivants, il faudra faire:
Notez bien la suppression de l'option -c. Si vous la laissez, htpasswd va commencer par vider le fichier password. Vous perdrez alors vos utilisateurs précédents.
Enfin, il ne nous reste plus qu'à configurer l'authentification d'une part, et à prévoir la nouvelle règle de ré-écriture d'autre part:
Ordre des règles de ré-écriture
Vous aurez compris que l'ordre des règles de ré-écriture est particulièrement important. En effet, il faut d'abord commencer par rediriger les sites SSL, puis gérer l'authentification avant de pouvoir pointer sur le bon fichier.
Un mauvais ordre des règles et voilà votre sous-domaine protected.mondomaine.com exposé. Pas cool. Attention donc si vous décidez de modifier/ajouter des règles de ré-écriture.
Mise en place des sous-domaines
Il est temps maintenant de mettre en place les sous-domaines. Pour mémoire:
- blog.domaine.com doit être accessible en HTTP ou en SSL. L'authentification est gérée par l'application elle-même.
- webmail.domaine.com doit être obligatoirement en SSL. L'authentification est gérée par l'application elle-même.
- protected.domaine.com ne sera accessible qu'après authentification, mais l'accès n'est pas forcé en SSL.
- maitredumonde.domaine.com ne sera accessible qu'après authentification, mais l'accès est en plus forcé en SSL.
Là encore, pour des questions de simplicités, je laisse volontrairement de côté les problématiques liées, notamment, aux permissions du système de fichier.
Configuration finale du domaine mondomaine.com
Voici à quoi ressemble maintenant notre structure de fichiers:
Bien entendu, dans la définition du vhost SSL, la règle numéro 3 a disparu. C'est normal, puisque c'est celle qui est chargée de la ré-écriture d'URL en HTTPS. Si nous sommes déjà en HTTPS, pas besoin de rediriger la requète.
Conclusion
Bien entendu, ce système n'est pas "ultime". Par exemple, vous devrez redémarrer NGinx à chaque fois que vous voudrez ajouter un domaine. Dans le même esprit, vous devrez modifier les règles de ré-écriture à 2 endroits différents à chaque fois. Vous pouvez toutefois condenser ces règles dans un fichier particulier et l'inclure dans la déclaration de vos vhosts.
Mais ceci ouvre des perspectives intéressantes, que je vous laisse creuser. Par exemple: est-il possible de placer un nginx avec cette configuration en frontal d'un Apache ? De cette manière, on peut effectuer une séparation de trafic statique / dynamique.
