IPv6上基于Nginx名称的虚拟主机


44

我有一台Nginx服务器,可提供将近六个不同的网站。它在刚刚获得IPv6本机支持的Linode(达拉斯数据中心)上运行,我正在尝试将我的大多数站点配置为双堆栈操作。我使用第一个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上使用基于名称的虚拟主机?还是我错过了一个解决方案,该解决方案将使我的配置在两个堆栈上保持一致?

我希望在世界IPv6日之前及时将我的站点完全放置在 IPv6堆栈上,但是除非我能迅速解决此问题,否则我可能还没有准备好。从任何实际角度来看都没什么大不了的-从我的想象力来看,我的网站都没有资格成为“主要组织”-但请帮我保存我的极客信誉!

编辑添加:

感谢@kolbyjack的回答,现在我有了一个功能齐全的双栈Web服务器。为了清楚起见,我正在编辑他给我的解决方案,以便每个人都可以清楚地看到答案是什么。

我的默认catchall虚拟主机具有以下listen指令:

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

我不知道命令是否重要,但确实存在。然后,每个其他虚拟主机具有以下listen指令:

listen 80;
listen [::]:80;

(或者8080代表在该端口上侦听的端口。)这里的重要部分似乎是,除了默认的vhost listen指令之外,所有其他参数都完全缺少任何其他参数-即,没有重复ipv6only=on

再次感谢@kolbyjack提供的解决方案!


使用nginx 1.2.1时,我不必指定ipv6only=on。但是,其他所有内容都保持不变,谢谢!
BeepDog 2014年

Answers:


46

您只需要在一个套接字声明中使用侦听选项。通常,您会将它们放在还包含default_server标志的声明中,但是对于某些选项,我认为您可以将它们设置在任何一个listen指令上。只需从所有监听中删除ipv6only = on即可。


2
等等,我很困惑。我认为每个服务器声明至少需要一个listen指令-否则Nginx怎么知道哪个服务器块打算在哪个端口上响应?我上面没有提到它,是因为我认为它不相关,但是我在8080上有一台服务器,其余的在80上,并且我打算在解决这一问题后立即为一对夫妇提供443。然后给我自己一个SSL证书。
Kromey 2011年

好的,再次查看文档,端口80上的站点看起来根本不需要监听指令,只是在我的catch虚拟机上带有default_server标志的站点。但是,这对于我在8080上的服务器仍然失败,我也为此使用了默认的catchall(catchall的编写只是为了忽略对我在另一个vhost中未明确配置的主机名的任何请求)。
Kromey 2011年

1
我并不是说要删除所有的监听指令。只需从其中一个中删除ipv6only = on标志即可。在每台服务器中都没有listen指令的情况下,它们默认将仅监听80。其中可能包含或不包含ipv6。我认为正确的方法是在每个服务器中都包含两个listen指令,但只能将ipv6only = on放在其中一个服务器中。
kolbyjack 2011年

4
啊,我明白了你的意思。我原本误读了您的帖子。这对我有用:ipv6only=on仅在默认的虚拟主机(以及default_server)中列出(我监听的每个端口);然后,每个虚拟主机只需指定listen 80;并且listen [::]:80(根本没有其他参数)即可在IPv4和IPv6上运行。现在,我要做的就是为我的双堆栈域添加AAAA记录,我应该很高兴来到这里。谢谢!
Kromey 2011年

1
同样为我工作,但我不明白为什么我nginx可以在ipv4上侦听多个块,但不能在ipv6上侦听。。你可以解释吗 ?
Adeerlike
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.