Globally setting ipv6only=off

Solution 1:

I just went through this with an upgrade from 1.0 to 1.4.

Since only a single listener is actually bound to any given port, it's sufficient to specify ipv6only=off in any one of your listen directives.

So, in my default server blocks, I have:

    listen [::]:80 ipv6only=off default_server;

and

    listen [::]:443 ipv6only=off default_server;

All of the other server blocks merely specify the original listen directives. And it works; any virtual host is reachable via either IPv4 or IPv6.

You could also add it to all of them, but that's not really required. Adding it to any one of them is sufficient.

However, because the ipv6only= flag is Linux-only, I do not use this construct anymore. My current directives specify both IPv4 and IPv6 explicitly, such as:

listen [::]:80 default_server;
listen 80 default_server;

Solution 2:

An alternative to @Michael Hampton's answer (but you have to touch all files) is to insert

listen 80;      # listen for IPv4
listen [::]:80; # listen for IPv6

for all servers.


Strange is, that inserting listen [::]:80 ipv6only=off for more than one server results in

nginx: [emerg] duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/default.conf:3

And a mix of listen 80; and ipv6only=off (in different servers) results in

nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()