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


Ich habe verschiedene Konfigurationsbeispiele zum Umgang mit Dual-Stack IPv4 und IPv6 virtuellen 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ürdest du das erstere benutzen? Der einzige Grund, an den ich denken kann, ist, wenn Sie zusätzliche Parameter benötigen, die für jedes Protokoll spezifisch sind, zum Beispiel, wenn Sie nur festlegen wollten deferred auf IPv4.


60
2017-10-20 16:26


Ursprung


Als IP-Stack-Version ist es eine TCP-Option. - Xavier Lucas
Sicher, aber du hast es eingestellt listen Anweisungen, und die Optionen werden pro Host angewendet: Port-Paar. - Synchro
Hum Ich kann mir wirklich keinen Fall vorstellen, in dem du das willst. Ich denke, der einzige Grund ist historisch und Michael Hampton hat es genagelt. - Xavier Lucas


Antworten:


Das wahrscheinlich ist über den einzigen Grund, warum Sie das ehemalige Konstrukt heutzutage benutzen würden.

Der Grund, warum Sie das sehen, ist wahrscheinlich dass der Standardwert von ipv6only geändert in nginx 1.3.4. Zuvor war es voreingenommen off; In neueren Versionen ist es standardmäßig on.

Dies passiert unter Linux mit der IPV6_V6ONLY-Socket-Option und ähnlichen Optionen auf anderen Betriebssystemen, deren Standardeinstellungen nicht unbedingt vorhersehbar sind. Daher wurde das vorherige Konstrukt vor 1.3.4 benötigt, um sicherzustellen, dass Sie tatsächlich nach Verbindungen auf IPv4 und IPv6 lauschten.

Die Änderung des Nginx-Standardwerts für ipv6only stellt sicher, dass das Betriebssystem für Dual-Stack-Sockets keine Rolle spielt. Jetzt bindet nginx entweder explizit an IPv4, IPv6 oder beides, wobei es vom Betriebssystem abhängig ist, dass standardmäßig ein Dual-Stack-Socket erstellt wird.

Tatsächlich haben meine Standard-nginx-Konfigurationen für pre-1.3.4 die erste Konfiguration und post-1.3.4 alle die zweite Konfiguration.

Obwohl das Binden eines Dual-Stack-Sockets nur Linux ist, sehen meine derzeitigen Konfigurationen jetzt eher wie das erste Beispiel aus, aber ohne ipv6only gesetzt, mit:

listen [::]:80;
listen 80;

37
2017-10-20 16:32



Einige Betriebssysteme tun überhaupt keine doppelten ipv4- und ipv6-Sockets, wie OpenBSD, deshalb musst du zweimal zuhören. - Justin Cormack
@JustinCormack Ja, du hast Recht, und das habe ich schon länger berücksichtigt. Ich habe diesen Beitrag bis jetzt nicht aktualisiert. - Michael Hampton♦
listen localhost:8080; scheint auf beide zu hören (1.12.2) und zu verwenden proxy_pass http://localhost:8080 würde Balance zwischen :: 1 und 127.0.0.1 laden - ich musste eine Zeile für ipv6 hinzufügen, um echte IP in Logs zu bekommen set_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For; - Antony Gibbs


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 Eigenart, in der du nur die ipv6only Parameter einmal für jeden Port, oder es wird nicht gestartet. Das bedeutet, dass Sie sie nicht für jeden vhost-Domänenserverblock angeben können.

Wie Michael erwähnt, beginnend mit Nginx 1.3.4, der ipv6only Parameter ist standardmäßig auf 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 listen-Anweisungen verwenden:

listen 80;
listen [::]:80; 

Zusätzlich, wie Sander erwähnt, Verwendung ipv6only=off hat den Nachteil, dass IPv4-Adressen in IPv6 übersetzt werden. Dies kann zu Problemen führen, wenn Ihre App eine IP-Prüfung gegen schwarze Listen wie Akismet oder StopForumSpam durchführt. Wenn Sie keine umgekehrte Übersetzungsebene erstellen, überprüft Ihre App die IPv6-Umsetzung der IPv4-Adresse des Spammers, die keiner der IPv4-Adressen entspricht die schwarze Liste.


54
2018-04-24 10:10



Ja, das ist das gleiche wie ich erwähnt habe deferredund andere Per-Protocol-Direktiven. Es wäre nützlich, wenn sie aus dem Grund, den Sie sagen, getrennt von der listen-Richtlinie aufgeführt werden könnten. - Synchro
Und der Kern der Angelegenheit ist, müssen Sie listen Direktive für jede Domäne getrennt angeben. Sonst was würde passieren? Seite würde gut über ipv4 funktionieren und über ipv6 würde es die nginx Willkommensseite zeigen. rofl - Silver Moon
Danke für die gründliche Erklärung! Ich habe einen verwirrenden Fehler bekommen, als ich angegeben habe ipv6only=off für den gleichen Port zweimal. Ihre Antwort hat das Problem gelöst! - Bruno Sutic
Auch wenn Sie 2 Vhosts verwenden wollen, hören Sie 443: listen 443; listen [::]:443; . Verwenden listen [::]:80 ipv6only=off; wirft einen Nginx-Fehler, dass der Port bereits verwendet wird - luke_aus
Sehr nützlich, danke. - Basil A


Mit dem ipv6only=off Konfigurations-Stil die IPv4-Adressen werden möglicherweise als IPv6-Adressen mit der (nur Software) angezeigt IPv4-zugeordnete IPv6-Adressen zum Beispiel Protokolldateien, Umgebungsvariablen (REMOTE_ADDR) usw.


12
2017-10-20 17:08



Ja, sie werden auf diese Weise gezeigt. - Michael Hampton♦


Zu meinem Verständnis (und entsprechend den Dokumenten bei http://nginx.org/en/docs/http/ngx_http_core_module.html#listen), mit nur

listen 80;

... ist ausreichend, wenn Sie sowohl den IPv4- als auch den IPv6-Verkehr am selben Port channeln möchten.


1
2018-03-09 06:38



Das wurde bereits festgestellt und in der Frage erwähnt. Bitte beachten Sie die anderen Antworten für den Unterschied. - Synchro
Es war nicht für mich, ich brauchte beides. wget und curl sind fehlgeschlagen, wenn ipv6 benutzt wurde, bis ich die Zeile "listen [::]: 80 ipv6only = on;" - Basil A