我有一个 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 vhost 具有以下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 提供的解决方案!
答案1
您只需要在一个套接字声明上设置监听选项。通常,您会将它们放在也包含 default_server 标志的声明上,但对于某些选项,我认为您可以在任何一个监听指令上设置它们。只需从除一个之外的所有监听中删除 ipv6only=on 即可。