Avez-vous besoin de directives d’écoute distinctes IPv4 et IPv6 dans nginx?

72

J'ai vu divers exemples de configuration pour la gestion des hôtes virtuels IPv4 et IPv6 à double pile sur nginx. Beaucoup suggèrent ce modèle:

listen 80;
listen [::]:80 ipv6only=on;

Autant que je sache, cela donne exactement la même chose que:

listen [::]:80 ipv6only=off;

Pourquoi utiliseriez-vous l'ancien? La seule raison pour laquelle je peux penser est si vous avez besoin de paramètres supplémentaires spécifiques à chaque protocole, par exemple si vous ne souhaitez définir que deferredsur IPv4.

Synchro
la source
Considéré comme n'ayant rien à voir avec la version de pile IP, il s'agit d'une option TCP.
Xavier Lucas
1
Bien sûr, mais vous le définissez dans des listendirectives et les options sont appliquées par paire hôte / port.
Synchro
Hum je ne peux vraiment pas imaginer un cas dans lequel vous voudriez faire cela. Je pense que la seule raison est historique et Michael Hampton l'a cloué.
Xavier Lucas

Réponses:

48

Ce probablement est la seule raison pour laquelle vous utilisez l'ancienne construction, ces jours -ci .

La raison pour laquelle vous voyez ceci est probablement que la valeur par défaut de ipv6onlymodifiée dans nginx 1.3.4. Avant cela, il était par défaut à off; dans les versions plus récentes, la valeur par défaut est on.

Ceci interagit avec l'option de socket IPV6_V6ONLY sous Linux et avec des options similaires sur d'autres systèmes d'exploitation, dont les valeurs par défaut ne sont pas nécessairement prévisibles. Ainsi, l'ancienne construction était requise avant la version 1.3.4 pour garantir que vous écoutiez bien les connexions IPv4 et IPv6.

La modification de la valeur par défaut de nginx for ipv6onlygarantit que la valeur par défaut du système d’exploitation pour les sockets à double pile n’est pas pertinente. Maintenant, nginx soit explicitement lié à IPv4, IPv6 ou les deux, sans jamais dépendre du système d'exploitation pour créer un socket double pile par défaut.

En effet, mes configurations nginx standard pour les versions antérieures à la version 1.3.4 ont la première configuration et les versions ultérieures à la version 1.3.4 ont toutes la deuxième configuration.

Cependant, comme relier un socket double pile est une chose uniquement sous Linux, mes configurations actuelles ressemblent davantage au premier exemple, mais sans ipv6onlyensemble, à savoir:

listen [::]:80;
listen 80;
Michael Hampton
la source
4
Certains systèmes d'exploitation ne font pas du tout de sockets doubles ipv4 et ipv6, comme OpenBSD, vous devrez donc écouter deux fois.
Justin Cormack
@JustinCormack Oui, vous avez raison, et j'ai pris cela en compte pendant un certain temps. Juste n'avait pas mis à jour ce post jusqu'à maintenant.
Michael Hampton
1
listen localhost:8080;semble écouter les deux (1.12.2) et utiliser proxy_pass http://localhost:8080un équilibre de charge entre :: 1 et 127.0.0.1 - Je devais ajouter une ligne pour ipv6 afin d'obtenir une adresse IP réelle dans les journauxset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
Antony Gibbs Le
65

Si vous hébergez plusieurs domaines vhost avec une seule instance Nginx, vous ne pouvez pas utiliser la directive d'écoute combinée unique.

listen [::]:80 ipv6only=off;

pour chacun d'eux. Nginx a une bizarrerie bizarre où vous ne pouvez spécifier le ipv6onlyparamètre qu'une seule fois pour chaque port, sinon le démarrage échouera. Cela signifie que vous ne pouvez pas le spécifier pour chaque bloc de serveur de domaine vhost.

Comme Michael l'a mentionné, à partir de Nginx 1.3.4, le ipv6onlyparamètre par défaut est on.

Par conséquent, si vous souhaitez héberger plusieurs domaines sur IPv4 et IPv6 avec un seul serveur Nginx, vous devez obligatoirement utiliser deux directives d'écoute pour chaque bloc de serveur de domaine:

listen 80;
listen [::]:80; 

En outre, comme l'a mentionné Sander, l'utilisation ipv6only=offprésente l'inconvénient que les adresses IPv4 sont traduites en IPv6. Cela peut poser problème si votre application vérifie l'IP sur des listes noires telles qu'Akismet ou StopForumSpam car, sauf si vous créez une couche de traduction inversée, votre application vérifie la traduction IPv6 de l'adresse IPv4 du polluposteur, qui ne correspond à aucune des adresses IPv4 de la liste noire.

Jeff Widman
la source
2
Oui, c'est la même chose que j'ai mentionnée à propos d' deferredautres directives par protocole. Il serait utile de pouvoir les spécifier séparément de la directive d'écoute pour la raison que vous dites.
Synchro
1
Et le cœur du problème est que vous devez spécifier la directive d'écoute pour chaque domaine séparément. Sinon, que se passerait-il? le site fonctionnerait bien via ipv4 et via ipv6, il afficherait la page d'accueil nginx. ROFL
Silver Moon
2
Merci pour l'explication approfondie! Je recevais une erreur déroutante quand j'ai spécifié ipv6only=offpour le même port deux fois. Votre réponse a résolu le problème!
1
Aussi , si vous souhaitez utiliser 2 vhosts les écouter 443: listen 443; listen [::]:443;. L' listen [::]:80 ipv6only=off;utilisation
génère
16

Avec le ipv6only=offstyle de configuration, les adresses IPv4 peuvent être affichées en tant qu'adresses IPv6 à l'aide des adresses IPv6 mappées IPv4 (uniquement logicielles), par exemple dans des fichiers journaux, des variables d'environnement (REMOTE_ADDR), etc.

Sander Steffann
la source
3
Oui, ils sont montrés de cette façon.
Michael Hampton
2

À ma connaissance (et selon la documentation à l’ adresse http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), en utilisant simplement

listen 80;

... est suffisant si vous souhaitez canaliser le trafic IPv4 et IPv6 sur le même port.

Fevangelou
la source
1
Cela a déjà été établi et mentionné dans la question. S'il vous plaît voir les autres réponses pour la différence.
Synchro
3
Ce n'était pas pour moi, j'avais besoin des deux. wget et curl où échouant lors de l'utilisation d'ipv6 jusqu'à ce que j'ajoute la ligne "listen [::]: 80 ipv6only = on;"
Basil A