Noms des serveurs
Les noms de serveur sont définis à l'aide de la directive server_name et déterminent quel bloc de serveur est utilisé pour une requête donnée. Ils peuvent être définis à l'aide de noms exacts, de noms génériques ou d'expressions régulières :
server { listen 80; server_name example.org www.example.org; ... } server { listen 80; server_name *.example.org; ... } server { listen 80; server_name mail.*; ... } server { listen 80; server_name ~^(?<user>.+)\.example\.net$; ... } |
Lors de la recherche d'un serveur virtuel par nom, si le nom correspond à plusieurs des variantes spécifiées, par exemple si le nom générique et l'expression régulière correspondent, la première variante correspondante sera choisie, dans l'ordre de priorité suivant :
- nom exact
- nom générique le plus long commençant par un astérisque, par exemple « *.example.org »
- nom générique le plus long se terminant par un astérisque, par exemple « mail.* »
- première expression régulière correspondante (dans l'ordre d'apparition dans un fichier de configuration)
Noms génériques
Un nom générique ne peut contenir un astérisque qu'au début ou à la fin du nom, et uniquement sur une bordure en pointillé. Les noms «www.*.example.org» et «w*.example.org» ne sont pas valides. Cependant, ces noms peuvent être spécifiés à l'aide d'expressions régulières, par exemple, «~^www\..+\.example\.org$» et «~^w.*\.example\.org$». Un astérisque peut correspondre à plusieurs parties du nom. Le nom «*.example.org» correspond non seulement à www.example.org mais également à www.sub.example.org.
Un nom générique spécial sous la forme «.example.org» peut être utilisé pour faire correspondre à la fois le nom exact «example.org» et le nom générique «*.example.org».
Noms d'expressions régulières
Les expressions régulières utilisées par nginx sont compatibles avec celles utilisées par le langage de programmation Perl (PCRE). Pour utiliser une expression régulière, le nom du serveur doit commencer par le caractère tilde :
server_name ~^www\d+\.example\.net$; |
sinon, il sera traité comme un nom exact, ou si l'expression contient un astérisque, comme un nom générique (et très probablement comme un nom non valide). N'oubliez pas de définir les ancres «^» et «$». Elles ne sont pas nécessaires syntaxiquement, mais logiquement. Notez également que les points des noms de domaine doivent être échappés avec une barre oblique inverse. Une expression régulière contenant les caractères « { » et « } » doit être entre guillemets :
server_name "~^(?<name>\w\d{1,3}+)\.example\.net$"; |
sinon nginx ne démarrera pas et affichera le message d'erreur :
directive "server_name" is not terminated by ";" in ... |
Une capture d'expression régulière nommée peut être utilisée ultérieurement comme variable :
server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } } |
La bibliothèque PCRE prend en charge les captures nommées à l'aide de la syntaxe suivante :
Syntaxe | Description |
---|---|
?nom | Syntaxe compatible Perl 5.10, prise en charge depuis PCRE-7.0 |
?'nom' | Syntaxe compatible Perl 5.10, prise en charge depuis PCRE-7.0 |
?Pnom | Syntaxe compatible Python, prise en charge depuis PCRE-4.0 |
Si nginx ne démarre pas et affiche le message d'erreur :
pcre_compile() failed: unrecognized character after (?< in ... |
cela signifie que la bibliothèque PCRE est ancienne et qu'il faut plutôt essayer la syntaxe «?Pnom ». Les captures peuvent également être utilisées sous forme numérique :
server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } } |
Cependant, une telle utilisation doit être limitée aux cas simples (comme ci-dessus), car les références numériques peuvent facilement être écrasées.
Noms divers
Certains noms de serveurs sont traités de manière spéciale.
S'il est nécessaire de traiter des requêtes sans le champ d'entête «Host» dans un bloc de serveur qui n'est pas celui par défaut, un nom vide doit être spécifié :
server { listen 80; server_name example.org www.example.org ""; ... } |
Si aucun nom de serveur n'est défini dans un bloc de serveur, alors nginx utilise le nom vide comme nom de serveur.
Les versions de nginx jusqu'à 0.8.48 utilisaient le nom d'hôte de la machine comme nom de serveur dans ce cas.
Si un nom de serveur est défini comme «$hostname» (0.9.4), le nom d'hôte de la machine est utilisé.
Si quelqu'un fait une demande en utilisant une adresse IP au lieu d'un nom de serveur, le champ d'entête de demande «Host» contiendra l'adresse IP et la demande peut être traitée en utilisant l'adresse IP comme nom de serveur :
server { listen 80; server_name example.org www.example.org "" 192.168.1.1 ; ... } |
Dans les exemples de serveurs fourre-tout, le nom étrange «_» peut être vu :
server { listen 80 default_server; server_name _; return 444; } |
Ce nom n'a rien de spécial, il fait simplement partie d'une myriade de noms de domaine non valides ne croisant jamais aucun nom réel. D'autres noms non valides comme «--» et «!@#» peuvent également être utilisés.
Les versions de nginx jusqu'à 0.6.25 prenaient en charge le nom spécial «*» étant interprété à tort comme un nom fourre-tout. Il n'a jamais fonctionné comme un nom de serveur fourre-tout ou générique. Au lieu de cela, il fournissait la fonctionnalité qui est maintenant fournie par la directive server_name_in_redirect. Le nom spécial «*» est désormais obsolète et la directive server_name_in_redirect doit être utilisée. Notez qu'il n'existe aucun moyen de spécifier le nom fourre-tout ou le serveur par défaut à l'aide de la directive server_name. Il s'agit d'une propriété de la directive listen et non de la directive server_name. Il est possible de définir des serveurs écoutant sur les ports *:80 et *:8080, et de spécifier que l'un sera le serveur par défaut pour le port *:8080, tandis que l'autre sera le serveur par défaut pour le port *:80 :
server { listen 80; listen 8080 default_server; server_name example.net; ... } server { listen 80 default_server; listen 8080; server_name example.org; ... } |
Noms internationalisés
Les noms de domaine internationalisés (IDN) doivent être spécifiés à l'aide d'une représentation ASCII (Punycode) dans la directive server_name :
server { listen 80; server_name xn--e1afmkfd.xn--80akhbyknj4f; # exemple.test ... } |
Sélection du serveur virtuel
Tout d'abord, une connexion est créée dans un contexte de serveur par défaut. Ensuite, le nom du serveur peut être déterminé dans les étapes de traitement de la requête suivantes, chacune impliquée dans la sélection de la configuration du serveur :
- pendant le handshake SSL, à l'avance, selon SNI
- après le traitement de la ligne de requête
- après le traitement du champ d'en-tête Host
- si le nom du serveur n'a pas été déterminé après le traitement de la ligne de requête ou à partir du champ d'en-tête Host, nginx utilisera le nom vide comme nom de serveur.
À chacune de ces étapes, différentes configurations de serveur peuvent être appliquées. Ainsi, certaines directives doivent être spécifiées avec prudence :
- dans le cas de la directive ssl_protocols, la liste des protocoles est définie par la bibliothèque OpenSSL avant que la configuration du serveur puisse être appliquée selon le nom demandé via SNI, ainsi, les protocoles ne doivent être spécifiés que pour un serveur par défaut ;
- les directives client_header_buffer_size et merge_slashes sont impliquées avant la lecture de la ligne de requête, ainsi, ces directives utilisent une configuration de serveur par défaut ou la configuration de serveur choisie par SNI ;
- dans le cas des directives ignore_invalid_headers, large_client_header_buffers et underscores_in_headers impliquées dans le traitement des champs d'en-tête de requête, cela dépend en outre si la configuration du serveur a été mise à jour en fonction de la ligne de requête ou du champ d'en-tête Host ;
- une réponse d'erreur sera gérée avec la directive error_page dans le serveur qui répond actuellement à la requête.
Optimisation
Les noms exacts, les noms génériques commençant par un astérisque et les noms génériques se terminant par un astérisque sont entreposés dans trois tables de hachage liées aux ports d'écoute. Les tailles des tables de hachage sont optimisées lors de la phase de configuration afin qu'un nom puisse être trouvé avec le moins d'échecs de cache CPU. Les détails de la configuration des tables de hachage sont fournis dans un document séparé.
La table de hachage des noms exacts est recherchée en premier. Si un nom n'est pas trouvé, la table de hachage avec les noms génériques commençant par un astérisque est recherchée. Si le nom n'est pas trouvé dans cette table, la table de hachage avec les noms génériques se terminant par un astérisque est recherchée.
La recherche dans la table de hachage des noms génériques est plus lente que la recherche dans la table de hachage des noms exacts car les noms sont recherchés par parties de domaine. Notez que la forme générique spéciale « .example.org » est stockée dans une table de hachage des noms génériques et non dans une table de hachage des noms exacts.
Les expressions régulières sont testées séquentiellement et constituent donc la méthode la plus lente et ne sont pas évolutives.
Pour ces raisons, il est préférable d'utiliser des noms exacts lorsque cela est possible. Par exemple, si les noms les plus fréquemment demandés pour un serveur sont example.org et www.example.org, il est plus efficace de les définir explicitement :
server { listen 80; server_name example.org www.example.org *.example.org; ... } |
que d'utiliser la forme simplifiée :
server { listen 80; server_name .example.org; ... } |
Si un grand nombre de noms de serveur sont définis ou si des noms de serveur inhabituellement longs sont définis, il peut s'avérer nécessaire de régler les directives server_names_hash_max_size et server_names_hash_bucket_size au niveau http. La valeur par défaut de la directive server_names_hash_bucket_size peut être égale à 32, 64 ou une autre valeur, selon la taille de la ligne de cache du processeur. Si la valeur par défaut est 32 et que le nom du serveur est défini comme «too.long.server.name.example.org», alors nginx ne parviendra pas à démarrer et affichera le message d'erreur suivant :
could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32 |
Dans ce cas, la valeur de la directive doit être augmentée à la puissance de deux suivante :
http { server_names_hash_bucket_size 64; ... |
Si un grand nombre de noms de serveurs sont définis, un autre message d'erreur apparaîtra :
could not build the server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 32 |
Dans un tel cas, essayez d'abord de définir server_names_hash_max_size sur un nombre proche du nombre de noms de serveur. Si cela ne résout pas le problème ou si le temps de démarrage de nginx est inacceptablement long, essayez d'augmenter server_names_hash_bucket_size.
Si un serveur est le seul serveur pour un port d'écoute, alors nginx ne testera pas du tout les noms de serveur (et ne construira pas les tables de hachage pour le port d'écoute). Cependant, il existe une exception. Si un nom de serveur est une expression régulière avec des captures, alors nginx doit exécuter l'expression pour obtenir les captures.
Compatibilité
- Le nom de serveur spécial «$hostname» est pris en charge depuis la version 0.9.4.
- Une valeur de nom de serveur par défaut est un nom vide « » depuis la version 0.8.48.
- Les captures de noms de serveur à expression régulière nommée sont prises en charge depuis la version 0.8.25.
- Les captures de noms de serveur à expression régulière sont prises en charge depuis la version 0.7.40.
- Un nom de serveur vide « » est pris en charge depuis la version 0.7.12.
- Un nom de serveur générique ou une expression régulière est pris en charge pour être utilisé comme premier nom de serveur depuis la version 0.6.25.
- Les noms de serveur à expression régulière sont pris en charge depuis la version 0.6.7.
- La forme générique example.* est prise en charge depuis la version 0.6.0.
- La forme spéciale .example.org est prise en charge depuis la version 0.3.18.
- La forme générique *.example.org est prise en charge depuis la version 0.1.13.