我已经看到了在 nginx 上处理双栈 IPv4 和 IPv6 虚拟主机的各种配置示例。许多人建议这种模式:
listen 80;
listen [::]:80 ipv6only=on;
据我所知,这实现了完全相同的事情:
listen [::]:80 ipv6only=off;
为什么要使用前者?我能想到的唯一原因是您是否需要特定于每个协议的附加参数,例如,如果您只想deferred
在 IPv4 上设置。
我已经看到了在 nginx 上处理双栈 IPv4 和 IPv6 虚拟主机的各种配置示例。许多人建议这种模式:
listen 80;
listen [::]:80 ipv6only=on;
据我所知,这实现了完全相同的事情:
listen [::]:80 ipv6only=off;
为什么要使用前者?我能想到的唯一原因是您是否需要特定于每个协议的附加参数,例如,如果您只想deferred
在 IPv4 上设置。
如果您使用单个 Nginx 实例托管多个虚拟主机域,则不能使用单个组合监听指令
对于他们每个人。Nginx 有一个奇怪的怪癖,您只能
ipv6only
为每个端口指定一次参数,否则将无法启动。这意味着您不能为每个虚拟主机域服务器块指定它。正如 Michael 提到的,从 Nginx 1.3.4 开始,
ipv6only
参数默认为on
.因此,如果您想使用单个 Nginx 服务器在 IPv4 和 IPv6 上托管多个域,则必须对每个域服务器块使用两个侦听指令:
此外,正如 Sander 所提到的,使用
ipv6only=off
IPv4 地址被转换为 IPv6 的缺点。如果您的应用针对 Akismet 或 StopForumSpam 等黑名单进行 IP 检查,这可能会导致问题,因为除非您构建反向转换层,否则您的应用将检查垃圾邮件发送者 IPv4 地址的 IPv6 转换,该地址与黑名单。如今,这可能是您使用前一种构造的唯一原因。
您看到这种情况的原因可能是 nginx 1.3.4中的默认值已
ipv6only
更改。在此之前,它默认为off
; 在较新的版本中,它默认为on
.这恰好与 Linux 上的 IPV6_V6ONLY 套接字选项以及其他操作系统上的类似选项交互,其默认值不一定是可预测的。因此,在 1.3.4 之前需要前一种构造,以确保您实际上正在侦听 IPv4 和 IPv6 上的连接。
对 nginx 默认值的更改可
ipv6only
确保双栈套接字的操作系统默认值无关紧要。现在,nginx 要么显式绑定到 IPv4、IPv6 或两者,默认情况下从不依赖操作系统来创建双栈套接字。事实上,我的 1.3.4 之前的标准 nginx 配置具有第一个配置,而 1.3.4 之后的都有第二个配置。
虽然,由于绑定双栈套接字是仅限 Linux 的事情,我当前的配置现在看起来更像第一个示例,但没有
ipv6only
设置,即:使用
ipv6only=off
配置样式,IPv4 地址可能会显示为 IPv6 地址,例如在日志文件、环境变量 (REMOTE_ADDR) 等中使用(仅软件) IPv4 映射的 IPv6 地址。据我了解(并根据http://nginx.org/en/docs/http/ngx_http_core_module.html#listenlisten 80;
上的文档),如果您希望在同一端口同时传输 IPv4 和 IPv6 流量,则使用 just就足够了。截至 2021 年 11 月的修订答案
截至 2021 年 11 月,Nginx 最新(来自官方仓库),例如在 Ubuntu 18.04 或 20.04 上,我可以确认对于常规(=非默认)Nginx 虚拟主机,这适用于 IPv4 和 IPv6 流量:
listen [::]:80;
...如果您对 HTTPS 流量使用单独的块:
listen [::]:443 ssl http2;
该
ipv6only=off
标志只能在 Nginx 的“默认”虚拟主机中引用一次(当没有域可以映射到虚拟主机时 Nginx 使用的虚拟主机)。例如:
显然,如果您的 Nginx 设置使用单个 vhost,那么您只需要后一个配置。
在将 IPv6 支持添加到带有代码段的站点时遇到的一个讨厌的问题
listen [::]:80 ipv6only=off;
是,当我将它添加到 vhost 并且 default_server 已经配置为同时侦听80
和[::]:80
.nginx
拒绝启动,抱怨地址已被使用!listen [::]:80 ipv6only=off;
用两条传统listen
线替换魔法可以让nginx
开始就好了。尽管
listen [::]:80 ipv6only=off;
在手动配置中可能很方便,但在自动配置系统中使用时可能会引起讨厌的麻烦。