fragen stichworte

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

Ich habe verschiedene Konfigurationsbeispiele für die Handhabung von 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, wird damit genau dasselbe erreicht wie:

listen [::]:80 ipv6only=off;

Warum sollten Sie die erstere verwenden? Der einzige Grund, den ich mir vorstellen kann, ist, wenn Sie zusätzliche Parameter benötigen, die für jedes Protokoll spezifisch sind, zum Beispiel, wenn Sie nur deferred auf IPv4 einstellen wollten.

antworten

Wenn Sie mehrere vhost-Domänen mit einer einzigen Nginx-Instanz hosten, können Sie nicht die einzige kombinierte Listenanweisung

verwenden
listen [::]:80 ipv6only=off;

für jeden von ihnen. Nginx hat eine seltsame Eigenheit, bei der Sie den Parameter ipv6only nur einmal für jeden Port angeben können. Andernfalls wird er nicht gestartet. Das bedeutet, dass Sie es nicht für jeden vhost-Domänenserverblock angeben können.

Wie von Michael erwähnt, wird der Parameter ipv6only ab Nginx 1.3.4 standardmäßig auf on gesetzt.

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

listen 80;
listen [::]:80; 

Außerdem hat die Verwendung von ipv6only=off, wie Sander erwähnt hat, den Nachteil, dass IPv4-Adressen in IPv6 übersetzt werden. Dies kann zu Problemen führen, wenn Ihre App eine IP-Prüfung gegen Blacklists wie Akismet oder StopForumSpam durchführt, da Ihre App die IPv6-Übersetzung der IPv4-Adresse des Spammers überprüft, sofern Sie keine umgekehrte Übersetzungsebene erstellen die schwarze Liste.

Wahrscheinlich handelt es sich bei um den einzigen Grund, warum Sie heutzutage das vorherige Konstrukt verwenden würden.

Der Grund dafür ist wahrscheinlich, dass sich die Standardeinstellung von ipv6only in nginx 1.3.4 geändert hat. Vorher war der Standardwert off. In neueren Versionen ist der Standardwert on.

Dies interagiert mit der Socket-Option IPV6_V6ONLY unter Linux und ähnlichen Optionen auf anderen Betriebssystemen, deren Standardwerte nicht unbedingt vorhersehbar sind. Daher war das frühere Konstrukt vor Version 1.3.4 erforderlich, um sicherzustellen, dass Sie tatsächlich Verbindungen auf IPv4 und IPv6 abhören.

Durch die Änderung des Nginx-Standardwerts für ipv6only wird sichergestellt, dass der Betriebssystemstandardwert für Dual-Stack-Sockets nicht relevant ist. Nun bindet nginx entweder explizit an IPv4, IPv6 oder beides, wobei es je nach Betriebssystem keine Rolle spielt, um standardmäßig einen Dual-Stack-Socket zu erstellen.

Tatsächlich haben meine Standard-Nginx-Konfigurationen für die Version vor 1.3.4 die erste Konfiguration und nach 1.3.4 alle die zweite Konfiguration.

Obwohl das Binden eines Dual-Stack-Sockets nur für Linux gilt, sehen meine aktuellen Konfigurationen jetzt eher aus wie das erste Beispiel, jedoch ohne ipv6only, dh

listen [::]:80;
listen 80;

Mit dem Konfigurationstyp ipv6only=off werden die IPv4-Adressen möglicherweise als IPv6-Adressen mit den (nur Software) IPv4-zugeordneten IPv6-Adressen z. B. in Protokolldateien, Umgebungsvariablen (REMOTE_ADDR) usw. angezeigt.

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

listen 80;

... reicht aus, wenn Sie sowohl IPv4 als auch IPv6-Verkehr am selben Port.