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

Kro*_*mey 45 nginx ipv6 virtualhost

我有一个 nginx 服务器,为近六个不同的网站提供服务。它运行在刚刚获得 IPv6 本机支持(达拉斯数据中心)的 Linode 上,我正在尝试将我的大部分站点配置为双栈操作。我使用 IPv6-only 子域启动并运行了第一个,如下所示:

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
}
Run Code Online (Sandbox Code Playgroud)

这很有效——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
Run Code Online (Sandbox Code Playgroud)

似乎 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;
Run Code Online (Sandbox Code Playgroud)

我不知道订单是否重要,但确实如此。然后,每个额外的 vhost 都有以下listen指令:

listen 80;
listen [::]:80;
Run Code Online (Sandbox Code Playgroud)

(或者 8080 用于侦听该端口的那个。)这里的重要部分似乎是除了默认的 vhostlisten指令之外的所有其他参数都完全没有任何附加参数——即没有重复ipv6only=on.

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

kol*_*ack 47

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

  • 啊,我现在明白你的意思了。我最初误读了您的帖子。这对我有用:`ipv6only=on` 仅在我的默认虚拟主机中列出(对于我监听的每个端口)(与 `default_server` 一起);然后每个虚拟主机简单地指定 `listen 80;` 和 `listen [::]:80`(根本没有额外的参数)来在 IPv4 和 IPv6 上运行。现在我所要做的就是为我的双栈域添加 AAAA 记录,我应该很高兴去这里。谢谢! (4认同)
  • 等等,我糊涂了。我认为每个服务器声明至少需要一个监听指令——否则 nginx 怎么知道哪个服务器块打算响应哪个端口?我没有在上面提到它,因为我认为它不相关,但是我在 8080 上有一台服务器,其余在 80 上,我打算在解决这个问题后立即为一对夫妇提供 443 和然后给自己一个 SSL 证书。 (2认同)
  • 也为我工作,但我不明白为什么我的 nginx 可以在 ipv4 上监听多个块,但不能在 ipv6 上监听。. 你可以解释吗 ? (2认同)