I’ve seen various config examples for handling dual-stack IPv4 and IPv6 virtual hosts on nginx. Many suggest this pattern:
listen 80; listen [::]:80 ipv6only=on;
As far as I can see, this achieves exactly the same thing as:
listen [::]:80 ipv6only=off;
Why would you use the former? The only reason I can think of is if you need additional params that are specific to each protocol, for example if you only wanted to set
deferred on IPv4.
That probably is about the only reason you would use the former construct, these days.
The reason you’re seeing this is probably that the default of
ipv6only changed in nginx 1.3.4. Prior to that, it defaulted to
off; in newer versions it defaults to
This happens to interact with the IPV6_V6ONLY socket option on Linux, and similar options on other operating systems, whose defaults aren’t necessarily predictable. Thus the former construct was required pre-1.3.4 to ensure that you were actually listening for connections on both IPv4 and IPv6.
The change to the nginx default for
ipv6only ensures that the operating system default for dual stack sockets is irrelevant. Now, nginx either explicitly binds to IPv4, IPv6, or both, never depending on the OS to create a dual stack socket by default.
Indeed, my standard nginx configs for pre-1.3.4 have the first configuration, and post-1.3.4 all have the second configuration.
Though, since binding a dual stack socket is a Linux-only thing, my current configurations now look more like the first example, but without
ipv6only set, to wit:
listen [::]:80; listen 80;
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.