IPv6上のnginx名前ベースの仮想ホスト


44

私はnginxサーバーを使用して、ほぼ半ダースの異なるWebサイトにサービスを提供しています。IPv6ネイティブサポートを取得したLinode(Dallasデータセンター)で実行されており、ほとんどのサイトをデュアルスタック操作用に構成しようとしています。私は最初の1つを立ち上げて、次のようなIPv6のみのサブドメインを使用して実行しました:

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

    server_name example.com ipv6.example.com;

    root /var/www/example.com/htdocs;

    #More stuff, including PHP, WordPress
}

これはうまく機能します-example.comはIPv4専用(今のところ)であり、ipv6.example.comはIPv6専用です(主にテスト目的であります)。汗をかくことなくping6 ipv6.example.com、できますwget ipv6.example.com-これは楽に痛みがありませんでした(nginxが仮想ホストをバインドする方法で「落とし穴」を見つけた後、ipv6only=on引数とデュアルlistenディレクティブが必要です)。

ただし、現在はstatic.example.comから始めて、これを拡張して他のドメインをサポートしようとしています。ただし、上記と同じアプローチ(引数listenを含むデュアルディレクティブipv6only=on)を使用すると、nginxの再起動時に次のエラーが発生します。

* Starting Nginx Server...
nginx: [emerg] a duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/example.com.conf:3

おそらく、nginxのIPv6のバインド方法では、名前ベースの仮想ホストが許可されていないようです。ホストから追加のIPv6アドレスを取得し(問題はありません)、IPv6でIPベースの仮想ホストを使用し、IPv4を介した名前ベースの仮想ホストを使用する必要がありますか?または、両方のスタックで構成の一貫性を維持できるソリューションがありませんか?

私はWorld IPv6 Dayに間に合うようにサイトをIPv6スタックに完全に載せることを望んでいましたが、これをすぐにクリアできない限り、準備ができていない可能性があります。実用的な観点からは大したことではありません-私のサイトはどれも、想像力の広がりによって「主要な組織」とはみなされませんが、オタクの信用を救うのに役立ちます!

追加して編集:

@kolbyjackからの回答のおかげで、私は完全に機能するデュアルスタックWebサーバーを手に入れました。わかりやすくするために、私は彼が提供したソリューションを編集しているので、誰もが答えを明確に見ることができます。

デフォルトのcatchall vhostには次のlistenディレクティブがあります。

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

順序が重要かどうかはわかりませんが、問題はあります。次に、追加の各vhostには次のlistenディレクティブがあります。

listen 80;
listen [::]:80;

(またはそのポートでリッスンするポートの場合は8080)。ここでの重要な部分は、デフォルトのvhostのlistenディレクティブ以外のすべての追加引数がないことですipv6only=on。つまり、の繰り返しはありません。

繰り返しになりますが、このソリューションの@kolbyjackに感謝します!


nginx 1.2.1では、を指定する必要はありませんでしたipv6only=on。ただし、これに感謝します!
BeepDog

回答:


46

ソケットの1つの宣言でlistenオプションのみが必要です。通常、default_serverフラグも含む宣言にそれらを配置しますが、一部のオプションでは、1つのlistenディレクティブに設定するだけでよいと思います。1つを除くすべてのリッスンからipv6only = onを削除するだけです。


2
待って、私は混乱しています。サーバー宣言ごとに少なくとも1つのリッスンディレクティブが必要だと思いました-さもなければ、nginxはどのサーバーブロックがどのポートで応答するかをどのように知るのでしょうか?私はそれが関連しているとは思わなかったので、私はそれを言及しませんでしたが、私は8080に1つのサーバーを持ち、残りは80にあります。次に、SSL証明書を取得します。
クローミー

さて、ドキュメントをもう一度見ると、ポート80にあるサイトは実際にはlistenディレクティブをまったく必要としないように見えます。キャッチオールvhostのdefault_serverフラグが1つだけです。ただし、8080のサーバーではこれでも失敗します。デフォルトキャッチオールも使用します(キャッチオールは、別のvhostで明示的に設定していないホスト名に対する要求を単に無視するように記述されています)。
クローミー

1
すべてのリッスンディレクティブを削除するつもりはありません。それらの1つを除くすべてからipv6only = onフラグを削除するだけです。各サーバーにリッスンディレクティブがない場合、デフォルトでは80だけをリッスンします。ipv6を含む場合と含まない場合があります。正しいアプローチは、両方のリッスンディレクティブを各サーバーに含めることですが、ipv6only = onをサーバーの1つだけに配置することだと思います。
kolbyjack

4
ああ、私は今あなたが何を意味するのか見ます。私は元々あなたの投稿を読み違えました。これは私にとってはうまくipv6only=onいきました:デフォルトのvhostに(と一緒にdefault_server)リストされているのは(リッスンする各ポートについて)だけです; 各バーチャルホストは、単に指定しないlisten 80;listen [::]:80、IPv4とIPv6の両方で機能する(全く追加パラメータ)。デュアルスタックドメインのAAAAレコードの追加を完了するだけで、ここに行くことができます。ありがとう!
クローミー

1
私のためにも働いたが、なぜ私はnginxがipv6ではなく複数のブロックのipv4でリッスンできるのか理解していない。。説明できる ?
アデリーライク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.