nginxでIPv4とIPv6の個別のlistenディレクティブが必要ですか?


72

nginxでデュアルスタックIPv4およびIPv6仮想ホストを処理するためのさまざまな設定例を見てきました。多くの人がこのパターンを提案しています:

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

私が見る限り、これはまったく同じことを達成します:

listen [::]:80 ipv6only=off;

前者を使用する理由は何ですか?私が考えることができる唯一の理由は、各プロトコルに固有の追加のパラメーターが必要な場合、たとえば、deferredIPv4 のみを設定したい場合です。


IPスタックバージョンとは無関係であると判断されたのは、TCPオプションです。
ザビエルルーカス14年

1
確かに、listenディレクティブで設定すると、オプションはhost:portのペアごとに適用されます。
シンクロ14年

ええと、あなたがそれをしたいと思う場合は本当に想像できません。唯一の理由は歴史的なものだと思います。
ザビエルルーカス14年

回答:


48

それはおそらくです、あなたはかつての構文を使用する唯一の理由については、これらの日。

これが表示される理由は、おそらくipv6only nginx 1.3.4でデフォルトが変更されたためです。それ以前は、デフォルトはoff;でした。新しいバージョンでは、デフォルトでになりonます。

これは、LinuxのIPV6_V6ONLYソケットオプション、およびデフォルトが必ずしも予測可能でない他のオペレーティングシステムの同様のオプションとやり取りする場合があります。したがって、前の構成は、実際にIPv4とIPv6の両方で接続をリッスンしていることを確認するために1.3.4より前に必要でした。

nginxのデフォルトの変更ipv6onlyにより、デュアルスタックソケットのオペレーティングシステムのデフォルトは無関係になります。現在、nginxは、デフォルトでデュアルスタックソケットを作成するためにOSに依存することなく、明示的にIPv4、IPv6、またはその両方にバインドします。

実際、1.3.4以前の標準のnginx構成には最初の構成があり、-1.3.4以降にはすべて2番目の構成があります。

ただし、デュアルスタックソケットのバインドはLinux専用なので、現在の構成は最初の例のように見えますが、ipv6only設定はしていません。

listen [::]:80;
listen 80;

4
OpenBSDのように、一部のオペレーティングシステムはデュアルipv4およびipv6ソケットをまったく実行しないため、2回リッスンする必要があります。
ジャスティンコル

@JustinCormackはい、あなたは正しいです、そして私はしばらくの間それを考慮しました。今までこの投稿を更新していませんでした。
マイケルハンプトン

1
listen localhost:8080;(1.12.2)の両方に耳を傾けているようだし、使ってproxy_pass http://localhost:8080:: 1と127.0.0.1との間のバランスをロードします-私は、ログに実際のIPを取得するために、IPv6の行を追加する必要がありましたset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
アントニーギブス

65

単一のNginxインスタンスで複数の仮想ホストドメインをホストする場合、単一の結合されたリッスンディレクティブは使用できません。

listen [::]:80 ipv6only=off;

それらのそれぞれに対して。Nginxには奇妙な癖がありipv6only、各ポートにパラメーターを1回しか指定できないと、起動に失敗します。つまり、vhostドメインサーバーブロックごとに指定することはできません。

Michaelが述べたように、Nginx 1.3.4以降、ipv6onlyパラメーターのデフォルトはonです。

したがって、単一のNginxサーバーを使用してIPv4とIPv6の両方で複数のドメインをホストする場合、各ドメインサーバーブロックに対して2つのリッスンディレクティブを使用する必要があります。

listen 80;
listen [::]:80; 

さらに、Sanderが述べたように、使用にipv6only=offはIPv4アドレスがIPv6に変換されるという欠点があります。これは、アプリがAkismetやStopForumSpamなどのブラックリストに対してIPチェックを行う場合、問題を引き起こす可能性があります。逆変換レイヤーを構築しない限り、アプリは、ブラックリスト。


2
はい、それは私がdeferred他のプロトコルごとのディレクティブについて述べたのと同じです。あなたが言う理由でlistenディレクティブとは別に指定できると便利です。
シンクロ

1
そして問題の核心は、各ドメインに個別にlistenディレクティブを指定する必要があるということです。さもなければ何が起こるでしょうか?サイトはipv4を介して正常に動作し、ipv6を介してnginxのウェルカムページが表示されます。ROFL
シルバー・ムーン

2
徹底的な説明をありがとう!ipv6only=off同じポートを2回指定すると、紛らわしいエラーが発生しました。あなたの答えは問題を解決しました!

1
また、両方を443でリッスンする2つの仮想ホストを使用する場合:listen 443; listen [::]:443;。使用するlisten [::]:80 ipv6only=off;ポートが既に使用中であることをnginxのエラーがスローされます
lukeaus


2

私の理解(およびhttp://nginx.org/en/docs/http/ngx_http_core_module.html#listenのドキュメントによれば)

listen 80;

...同じポートでIPv4とIPv6の両方のトラフィックをチャネル化する場合は十分です。


1
それはすでに確立されており、質問で言及されています。違いについては、他の回答をご覧ください。
シンクロ

3
それは私のためではなく、私は両方が必要でした。「listen [::]:80 ipv6only = on;」という行を追加するまでipv6を使用すると失敗するwgetとcurl
バジルA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.