你需要在nginx中单独的IPv4和IPv6监听指令吗?

我已经看到了在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=offconfiguration样式,IPv4地址可能会显示为IPv6地址,例如使用(纯软件) IPv4映射的IPv6地址 ,例如日志文件,环境variables(REMOTE_ADDR)等。

    根据我的理解(根据http://nginx.org/en/docs/http/ngx_http_core_module.html#listen上的文档),仅仅使用

     listen 80; 

    如果您希望在同一个端口上同时传输IPv4和IPv6stream量,就足够了。