Benötigen Sie separate IPv4- und IPv6-Listen-Anweisungen in nginx?

72

Ich habe verschiedene Konfigurationsbeispiele für den Umgang mit virtuellen Dual-Stack-IPv4- und IPv6-Hosts auf nginx gesehen. Viele schlagen dieses Muster vor:

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

Soweit ich sehen kann, erreicht dies genau das Gleiche wie:

listen [::]:80 ipv6only=off;

Warum würden Sie die erstere verwenden? Der einzige Grund, den ich mir vorstellen kann, besteht darin, dass Sie zusätzliche Parameter benötigen, die für jedes Protokoll spezifisch sind, zum Beispiel, wenn Sie nur deferredIPv4 aktivieren möchten .

Synchro
quelle
Als nichts mit der IP-Stack-Version zu tun, ist es eine TCP-Option.
Xavier Lucas
1
Sicher, aber Sie setzen es in listenDirektiven und die Optionen werden pro Host: Port-Paar angewendet.
Synchro
Hum Ich kann mir wirklich keinen Fall vorstellen, in dem Sie das tun würden. Ich denke, der einzige Grund ist historisch und Michael Hampton hat es geschafft.
Xavier Lucas

Antworten:

48

Das wahrscheinlich ist so ziemlich der einzige Grund , warum Sie das ehemalige Konstrukt verwenden würde, in diesen Tagen.

Der Grund, warum Sie dies sehen, ist wahrscheinlich, dass sich die Standardeinstellung ipv6onlyin nginx 1.3.4 geändert hat. Zuvor war standardmäßig Folgendes eingestellt off: In neueren Versionen ist der Standardwert on.

Dies geschieht mit der Socket-Option IPV6_V6ONLY unter Linux und ähnlichen Optionen unter anderen Betriebssystemen, deren Standardeinstellungen nicht unbedingt vorhersehbar sind. Daher war das vorherige Konstrukt vor 1.3.4 erforderlich, um sicherzustellen, dass Sie tatsächlich auf IPv4- und IPv6-Verbindungen warteten.

Die Änderung der Nginx-Standardeinstellung für ipv6onlystellt sicher, dass die Betriebssystem-Standardeinstellung für Dual-Stack-Sockets irrelevant ist. Nun bindet nginx entweder explizit an IPv4, IPv6 oder beides, je nach Betriebssystem jedoch nie, um standardmäßig einen Dual-Stack-Socket zu erstellen.

In der Tat haben meine Standard-Nginx-Konfigurationen vor 1.3.4 die erste Konfiguration und nach 1.3.4 alle die zweite Konfiguration.

Da das Binden eines Dual-Stack-Sockets nur unter Linux möglich ist, sehen meine aktuellen Konfigurationen jetzt eher wie das erste Beispiel aus, jedoch ohne ipv6onlySatz:

listen [::]:80;
listen 80;
Michael Hampton
quelle
4
Einige Betriebssysteme, wie OpenBSD, bieten keine dualen IPv4- und IPv6-Sockets an, so dass Sie zweimal zuhören müssen.
Justin Cormack
@JustinCormack Ja, Sie haben Recht, und das habe ich seit einiger Zeit berücksichtigt. Hatte diesen Beitrag bisher nur nicht aktualisiert.
Michael Hampton
1
listen localhost:8080;scheint auf beide zu hören (1.12.2) und proxy_pass http://localhost:8080würde mit Load Balance zwischen :: 1 und 127.0.0.1 - Ich musste eine Zeile für ipv6 hinzufügen, um echte IP in Protokollen zu erhaltenset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
Antony Gibbs
65

Wenn Sie mehrere vhost-Domänen mit einer einzelnen Nginx-Instanz hosten, können Sie die einzelne kombinierte Listen-Direktive nicht verwenden

listen [::]:80 ipv6only=off;

für jeden von ihnen. Nginx hat eine seltsame Eigenheit, bei der Sie den ipv6onlyParameter nur einmal für jeden Port angeben können, da er sonst nicht gestartet werden kann. Das heißt, Sie können es nicht für jeden vhost-Domänenserverblock angeben.

Wie Michael bereits erwähnt hat, ist der ipv6onlyParameter ab Nginx 1.3.4 standardmäßig on.

Wenn Sie mehrere Domänen sowohl auf IPv4 als auch auf IPv6 mit einem einzigen Nginx-Server hosten möchten, müssen Sie daher für jeden Domänenserverblock zwei Empfangsanweisungen verwenden:

listen 80;
listen [::]:80; 

Wie Sander bereits erwähnte, ipv6only=offhat die Verwendung außerdem den Nachteil, dass IPv4-Adressen in IPv6 übersetzt werden. Dies kann zu Problemen führen, wenn Ihre App die IP-Überprüfung anhand von Blacklists wie Akismet oder StopForumSpam durchführt. Wenn Sie keine Reverse-Translation-Schicht einbauen, überprüft Ihre App die IPv6-Übersetzung der IPv4-Adresse des Spammers, die keiner der IPv4-Adressen in entspricht die schwarze Liste.

Jeff Widman
quelle
2
Ja, das ist das Gleiche, wie ich es erwähnt habe deferred, und andere Pro-Protokoll-Richtlinien. Es wäre nützlich, wenn sie aus dem von Ihnen angegebenen Grund getrennt von der Listen-Direktive angegeben werden könnten.
Synchro
1
Und der Kern der Sache ist, dass Sie die Listen-Direktive für jede Domain separat angeben müssen. Was würde sonst passieren? Die Seite würde über IPv4 funktionieren und über IPv6 würde die Nginx-Begrüßungsseite angezeigt. ROFL
Silver Moon
2
Vielen Dank für die ausführliche Erklärung! Beim ipv6only=offzweimaligen Festlegen desselben Anschlusses trat ein verwirrender Fehler auf . Ihre Antwort hat das Problem gelöst!
1
Auch wenn Sie möchten 2 vhosts verwenden beide hören 443: listen 443; listen [::]:443;. Unter Verwendung listen [::]:80 ipv6only=off;wird ein nginx Fehler aus , dass der Port bereits verwendet
lukeaus
16

Mit dem ipv6only=offKonfigurationsstil können die IPv4-Adressen als IPv6-Adressen unter Verwendung der (nur durch Software) IPv4-zugeordneten IPv6-Adressen in beispielsweise Protokolldateien, Umgebungsvariablen (REMOTE_ADDR) usw. angezeigt werden.

Sander Steffann
quelle
3
Ja, sie werden so dargestellt.
Michael Hampton
2

Soweit ich weiß (und gemäß den Dokumenten unter http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), verwenden Sie einfach

listen 80;

... ist ausreichend, wenn Sie sowohl IPv4- als auch IPv6-Datenverkehr auf demselben Port kanalisieren möchten.

Fevangelou
quelle
1
Das wurde bereits festgestellt und in der Frage erwähnt. Bitte beachten Sie die anderen Antworten für den Unterschied.
Synchro
3
Es war nicht für mich, ich brauchte beides. wget and curl schlug bei der Verwendung von ipv6 fehl, bis ich die Zeile "listen [::]: 80 ipv6only = on;" hinzufügte
Basil A