Nginx – default server
Comment configurer le serveur par défaut sous nginx surtout dans un environnement de « virtual host » ? Généralement, on attend de son serveur web le comportement suivant :
- toutes les requêtes mal formatées sont récupérées par le serveur www.domaine.com
- ces dernières sont alors ré-écrites en www.domaine.com (au lieu de 192.168.1.102 par ex.)
A partir de là, on voit fleurir sur internet l’usage du paramètre default_serveur, ou pire tous les domaines possibles dans le server_name
, le tout suivi d’une série de if et de rewrites ce qui pose plusieurs problèmes
- if is evil : if est assez incontrôlable et inefficace
- nginx va être forcé de tester avec « if » chaque requête http
- on risque probablement d’oublier de filtrer certaines requêtes
La méthode propre, recommandée et contre-intuitive consiste à ne pas utiliser le paramètre default_serveur
avec son serveur par défaut ! Si si. L’idée est de plûtot créer un serveur par défaut qui va récupérer toutes les requêtes qui ne correspondent à rien et les reformater :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | server { listen 192.168.1.102:80 default_server; server_name _; # ce n est pas un catch-all return 301 $scheme://www.domaine.com$request_uri; } server { listen 192.168.1.102:80; server_name www.domaine.com; root /var/www/domaine.com; [...] } |
- Ligne 2 : ce serveur devient le défaut et récupère toutes les requêtes non « matchées » par un autre serveur
- Ligne 3 : le _ assure qu’aucune requête http ne « match » ce serveur (évite les boulettes)
- Ligne 4 : la requête est ré-écrite dans le navigateur. Un http://192.168.1.102/loc/ devient http://www.domaine.com/loc/
On évite aussi les server_name
à rallonge qui posent des problèmes d’optimisation et de tables de hash.
Et si un autre domaine est géré par nginx ?
Bien sûr, on ne peut pas avoir deux domaines par défaut sur le même serveur Nginx. Par contre, il est tout à fait possible de rajouter un « catch-all » pour domaine2.com par exemple :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | server { listen 192.168.1.102:80; server_name *.domaine2.com; return 301 $scheme://www.domaine2.com$request_uri; } server { listen 192.168.1.102:80; server_name www.domaine2.com; root /var/www/domaine2.com; [...] } |
Nginx est assez bien fait, il choisira de servir en premier, le « match » exact :
- www.domaine2.com sera servi par le www
- tout les requêtes pour *.domaine2.com sauf www seront réécrites en www.domaine2.com