120 votes

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

J'ai vu différents exemples de configuration pour gérer des hôtes virtuels IPv4 et IPv6 en double pile sur nginx. Beaucoup suggèrent ce schéma :

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

Autant que je puisse le voir, cela réalise exactement la même chose que :

listen [::]:80 ipv6only=off;

Pourquoi utiliser le premier ? La seule raison à laquelle je peux penser est si vous avez besoin de paramètres supplémentaires spécifiques à chaque protocole, par exemple si vous vouliez définir deferred uniquement sur IPv4.

0 votes

Deffered n'a rien à voir avec la version de la pile IP, c'est une option TCP.

1 votes

Bien sûr, mais vous le définissez dans les directives listen, et les options sont appliquées par paire hôte:port.

0 votes

I- Je ne peux vraiment pas imaginer un cas où vous voudriez faire cela. Je pense que la seule raison est historique et Michael Hampton l'a cloué.

95voto

Jeff Widman Points 2175

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 particularité étrange où vous ne pouvez spécifier le paramètre ipv6only qu'une seule fois pour chaque port, sinon il ne démarrera pas. Cela signifie que vous ne pouvez pas le spécifier pour chaque bloc serveur de domaine vhost.

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

Par conséquent, si vous souhaitez héberger plusieurs domaines à la fois en IPv4 et IPv6 avec un seul serveur Nginx, vous êtes obligé d'utiliser deux directives listen pour chaque bloc serveur de domaine :

listen 80;
listen [::]:80; 

De plus, comme l'a mentionné Sander, l'utilisation de ipv6only=off a l'inconvénient de traduire les adresses IPv4 en IPv6. Cela peut poser des problèmes si votre application effectue des vérifications IP contre des listes noires comme Akismet ou StopForumSpam car à moins de mettre en place une couche de traduction inverse, votre application vérifiera la traduction IPv6 de l'adresse IPv4 du spammeur, qui ne correspondra à aucune des adresses IPv4 de la liste noire.

2 votes

Oui, c'est la même chose que j'ai mentionné à propos de deferred, et d'autres directives par protocole. Il serait utile qu'ils puissent être spécifiés séparément de la directive listen pour la raison que vous mentionnez.

1 votes

Et le cœur du problème est que vous devez spécifier une directive d'écoute pour chaque domaine séparément. Sinon, que se passerait-il ? Le site fonctionnerait correctement via l'ipv4 et via l'ipv6 il afficherait la page d'accueil de nginx. LOL

2 votes

Merci pour l'explication détaillée! J'obtenais une erreur confuse lorsque j'ai spécifié ipv6only=off pour le même port deux fois. Votre réponse a résolu le problème!

80voto

Michael Hampton Points 232226

C'est probablement la seule raison pour laquelle vous utiliseriez la première construction, de nos jours.

La raison pour laquelle vous voyez cela est probablement que la valeur par défaut de ipv6only a changé dans nginx 1.3.4. Avant cela, elle était par défaut à off; dans les nouvelles versions, elle est par défaut à on.

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

Le changement de la valeur par défaut de nginx pour ipv6only fait en sorte que la valeur par défaut du système d'exploitation pour les sockets double pile est sans importance. Maintenant, nginx se lie explicitement à 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 standard de nginx pour les versions antérieures à 1.3.4 ont la première configuration, et pour les versions postérieures à 1.3.4, elles ont toutes la deuxième configuration.

Cependant, puisque la liaison d'un socket double pile est spécifique à Linux, mes configurations actuelles ressemblent plus à la première exemple, mais sans l'option ipv6only définie, à savoir:

listen [::]:80;
listen 80;

8 votes

Certains systèmes d'exploitation ne supportent pas du tout les sockets dual ipv4 et ipv6, comme OpenBSD, donc pour cela vous devrez écouter deux fois.

0 votes

@JustinCormack Oui, tu as raison, et j'ai pris cela en compte depuis un certain temps. Je n'avais tout simplement pas mis à jour ce message jusqu'à présent.

1 votes

écouter localhost:8080; semble écouter à la fois (1.12.2) et en utilisant proxy_pass http://localhost:8080 équilibrerait la charge entre ::1 et 127.0.0.1 - J'ai dû ajouter une ligne pour ipv6 pour obtenir une véritable adresse IP dans les journaux set_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;

18voto

Sander Steffann Points 7432

Avec le style de configuration ipv6only=off, les adresses IPv4 peuvent être affichées en tant qu'adresses IPv6 en utilisant les adresses IPv6 mappées IPv4 (uniquement logiciel) dans par exemple les fichiers journaux, les variables d'environnement (REMOTE_ADDR) etc.

3 votes

Oui, ils sont affichés de cette manière.

10voto

fevangelou Points 161

À ma compréhension (et selon la documentation à http://nginx.org/en/docs/http/ngx_http_core_module.html#listen), l'utilisation de listen 80; est suffisante si vous souhaitez canaliser à la fois le trafic IPv4 et IPv6 sur le même port.

Réponse révisée en date de Novembre 2021

À partir de Novembre 2021 avec la dernière version de Nginx (à partir du dépôt officiel) par exemple sur Ubuntu 18.04 ou 20.04, je peux confirmer que pour les vhosts Nginx réguliers (=non par défaut), voici ce qui fonctionne pour à la fois le trafic IPv4 & IPv6:

listen [::]:80;

...et si vous utilisez un bloc séparé pour le trafic HTTPS:

listen [::]:443 ssl http2;

Le drapeau ipv6only=off ne devrait être référencé QU'UNE seule fois et dans le vhost "par défaut" dans Nginx (celui utilisé par Nginx lorsque aucun domaine ne peut être associé à un vhost).

Par exemple:

server {
    listen [::]:80 default_server ipv6only=off;

    # le reste de la configuration de votre vhost Nginx va ici...
}

server {
    listen [::]:443 default_server ssl http2 ipv6only=off;

    # le reste de la configuration de votre vhost Nginx va ici...
}

Évidemment, si votre configuration de Nginx utilise un seul vhost alors vous avez seulement besoin de la dernière configuration.

1 votes

Cela a déjà été établi et mentionné dans la question. Veuillez consulter les autres réponses pour voir la différence.

4 votes

Il ne fonctionnait pas pour moi, j'avais besoin des deux. wget et curl échouaient lors de l'utilisation d'ipv6 jusqu'à ce que j'ajoute la ligne "listen [::]:80 ipv6only=on;".

0 votes

Cela ne fonctionne pas pour moi, et je ne trouve pas où dans la documentation il est indiqué que cela fonctionnerait.

0voto

Alex Rodrigues Points 679

Un problème gênant que j'ai rencontré en ajoutant le support IPv6 à un site avec le snippet listen [::]:80 ipv6only=off; était lorsque je l'ai ajouté à un hôte virtuel (vhost) et que le default_server était déjà configuré pour écouter à la fois sur 80 et [::]:80.

nginx a refusé de démarrer, se plaignant que l'adresse était déjà utilisée!

Remplacer la magie listen [::]:80 ipv6only=off; par les deux lignes traditionnelles de listen permet à nginx de démarrer correctement.

Aussi pratique que listen [::]:80 ipv6only=off; puisse être dans une configuration manuelle, elle peut causer de sérieux problèmes lorsqu'elle est utilisée dans des systèmes de configuration automatisés.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X