我已经看到了在nginx上处理双栈IPv4和IPv6虚拟主机的各种configuration示例。 许多人认为这种模式:
listen 80; listen [::]:80 ipv6only=on;
据我所知,这实现了完全一样的事情:
listen [::]:80 ipv6only=off;
你为什么要用前者? 我能想到的唯一原因是,如果您需要每个协议特定的附加参数,例如,如果您只想在IPv4上设置deferred
。
这可能是你现在使用前一个构造的唯一原因。
你看到这个的原因可能是nginx 1.3.4中ipv6only
的默认值改变了。 在此之前,它默认off
; 在新版本中,默认为on
。
这恰好与Linux上的IPV6_V6ONLY套接字选项交互,而其他操作系统上的类似选项的默认值不一定是可预测的。 因此,1.3.4之前的构造需要确保您实际上正在侦听IPv4和IPv6的连接。
对ipv6only
的nginx默认值进行的更改将确保双栈套接字的操作系统默认值不相关。 现在,nginx可以显式绑定到IPv4,IPv6或者两者,从不依赖操作系统来默认创build双栈套接字。
事实上,我的1.3.4之前的标准nginxconfiguration有第一个configuration,而1.3.4之后都有第二个configuration。
虽然,绑定一个双栈套接字是一个Linux的东西,我现在的configuration现在看起来更像是第一个例子,但没有ipv6only
设置,
listen [::]:80; listen 80;
如果您使用单个Nginx实例托pipe多个vhost域,则不能使用单个组合的listen指令
listen [::]:80 ipv6only=off;
为他们每个人。 Nginx有一个奇怪的怪癖,你只能为每个端口指定ipv6only
参数一次,否则将无法启动。 这意味着您不能为每个虚拟主机域服务器块指定它。
正如Michael所说,从Nginx 1.3.4开始, ipv6only
参数默认为on
。
因此,如果您想使用单个Nginx服务器在IPv4和IPv6上承载多个域,则必须为每个域服务器块使用两个listen指令:
listen 80; listen [::]:80;
此外,正如桑德提到的,使用ipv6only=off
有IPv4地址转换为IPv6的缺点。 如果您的应用程序对像Akismet或StopForumSpam这样的黑名单进行IP检查,这可能会导致问题,因为除非您build立在反向翻译层,否则您的应用程序将检查垃圾邮件发送者的IPv4地址的IPv6转换,这将不会匹配任何IPv4地址黑名单。
使用ipv6only=off
configuration样式,IPv4地址可能会显示为IPv6地址,例如使用(纯软件) IPv4映射的IPv6地址 ,例如日志文件,环境variables(REMOTE_ADDR)等。
根据我的理解(根据http://nginx.org/en/docs/http/ngx_http_core_module.html#listen上的文档),仅仅使用
listen 80;
如果您希望在同一个端口上同时传输IPv4和IPv6stream量,就足够了。