IPv6 enabled Nginx default bind port

Hi.
Прежде всего, болшое спасибо дла Nginx.

We are currently very much moving forward with IPv6 and I had a small
problem with Nginx and I would like to give a suggestion. The problem
was, that if we did not specify listen [::]:80 to every server
declaration, nginx would fail to start. Naturally, because one listen
declaration would open and AF_INET6 and another one would try to open
AF_INET by default. As correct dualstack OS, AF_INET6 would also listen
on AF_INET thus causing “98: Address already in use”.

As the solution is simple - add listern declaration to all server
declarations - it can be unpractical in case of many server
declarations. What I would suggest is, if Nginx is compiled --with-ipv6
that it listens by default on AF_INET6. Another thing speaking for this
is that this is how ipv6 enabled programs should work. Operate on ipv6,
and let OS handle ipv4 to ipv6 mapping.

Thanks again for your great work.
Best regards,
-Zobo

Posted at Nginx Forum:

On Sun, Sep 06, 2009 at 03:39:12AM -0400, zobo wrote:

Hi.
ðÒÅÖÄÅ ×ÓÅÇÏ, ÂÏÌÛÏÅ ÓÐÁÓÉÂÏ ÄÌÁ Nginx.

We are currently very much moving forward with IPv6 and I had a small problem with Nginx and I would like to give a suggestion. The problem was, that if we did not specify listen [::]:80 to every server declaration, nginx would fail to start. Naturally, because one listen declaration would open and AF_INET6 and another one would try to open AF_INET by default. As correct dualstack OS, AF_INET6 would also listen on AF_INET thus causing “98: Address already in use”.

As the solution is simple - add listern declaration to all server declarations - it can be unpractical in case of many server declarations. What I would suggest is, if Nginx is compiled --with-ipv6 that it listens by default on AF_INET6. Another thing speaking for this is that this is how ipv6 enabled programs should work. Operate on ipv6, and let OS handle ipv4 to ipv6 mapping.

I do not understand your problem, but have you tried to

listen [::]:80 default ipv6only;

?

On Sun, Sep 06, 2009 at 11:53:48AM +0400, Igor S. wrote:

listen [::]:80 default ipv6only;

Sorry,

  • listen [::]:80 default ipv6only;
  • listen [::]:80 default ipv6only=on;

Hi.
Many thanks for your reply.

I do not want it to be ipv6only - I did however find the option in ru
docs and source. I want it to be 6 and 4. As it is in case I put listen
[::]:80. What I am suggesting is that if nginx is compiled --with-ipv6
that listen is by default [::]:80 instead of 80.

To be even more descriptive: If I have an ipv6 enabled nginx and put
this in configuration

server {
root /var/www;
}

This will listen on IPv4 port 80 and it will not be accessible over
ipv6. I have to put:

server {
listen [::]:80;
root /var/www;
}

If I then add another server declaration and forget to add listen
[::]:80, nginx will fail to start up.

I’m just saying, if ipv6 is enabled, it is desired, and default listen
should be [::]:80 instead od 80.

Hope I was able to explain better what I meant now.

Best regards,
-Zobo

Posted at Nginx Forum:

Igor S. Wrote:

compiled --with-ipv6 that listen is by default
be accessible over ipv6. I have to put:

I’m just saying, if ipv6 is enabled, it is
package built --with-ipv6,

Igor S.
Igor Sysoev

I understand. Did not think about other OS that much.
I will still patch nginx for my use.

Thanks for your time.

Best regards,
-Zobo

Posted at Nginx Forum:

The opposite situation is also true. I tried out IPv6, but my first
server definition did only use IPv4, making the later IPv6 enabled
server definition fail to bind.

2009/09/27 09:12:41 30088#0: bind() to [::]:80 failed (98: Address
already in use)
2009/09/27 09:12:41 30088#0: try again to bind() after 500ms

Now after reading this posting, realizing I must enable it for all
vhosts, but I really think this is an issue in need of at least
documentation. Maybe I should add it to the English wiki.

Thank you for an excellent software Igor.
– Kuisma

Posted at Nginx Forum:

On Sun, Sep 27, 2009 at 03:33:15AM -0400, kuisma wrote:

The opposite situation is also true. I tried out IPv6, but my first server definition did only use IPv4, making the later IPv6 enabled server definition fail to bind.

2009/09/27 09:12:41 30088#0: bind() to [::]:80 failed (98: Address already in use)
2009/09/27 09:12:41 30088#0: try again to bind() after 500ms

Now after reading this posting, realizing I must enable it for all vhosts, but I really think this is an issue in need of at least documentation. Maybe I should add it to the English wiki.

No, you just need to set:

 listen [::]:80  default ipv6only=on;

because Linux bind()s to both ipv4 and ipv6 by default.

On Sun, Sep 06, 2009 at 04:24:31AM -0400, zobo wrote:

Hope I was able to explain better what I meant now.

Well, I understand your point.
I think that now IPv6 is still used occasionally and many people may
built nginx --with-ipv6 just in store or may use a package built
–with-ipv6,
i.e. they do not really want ipv6.

And if nginx will bind() to “[::]:80” by default, ulimate result will
depend on OS IPv6ONLY settings: on FreeBSD nginx will bind to “[::]:80”
only
while on Linux nginx will bind to both “*:80” and “[::]:80”.

On Sun, Sep 27, 2009 at 05:26:05AM -0400, kuisma wrote:

I found the most intuitive solution was binding to explicit addresses, not using the wild card [::], this way no conflicts occurred, trying to bind an IPv4 address when IPv6 asked.

The default ipv6only=yes worked as well, but a bit contra-intuitive. It might give the impression the entire server block is only to listen to IPv6, not only this listen directive exclusively. Also, the default keyword itself might be somewhat confusing; a local server block parameter affecting the global listen/bind parameters affecting all other server definitions. I’m actually not sure I understand it myself correctly.

I’ll try to write something clarifying this in the wiki.

I agree that “default” keyword may confuse. Probably, it should be
renamed
to the “default_server” to indicate that this “server” block will handle
requests to given address:port if no matching virtual host is found.

Igor S. Wrote:

No, you just need to set:

 listen [::]:80  default ipv6only=on;

because Linux bind()s to both ipv4 and ipv6 by default.

Oh, how embarrassing, this is basically what you already said above …
Sorry 'bout that.

I found the most intuitive solution was binding to explicit addresses,
not using the wild card [::], this way no conflicts occurred, trying to
bind an IPv4 address when IPv6 asked.

The default ipv6only=yes worked as well, but a bit contra-intuitive. It
might give the impression the entire server block is only to listen to
IPv6, not only this listen directive exclusively. Also, the default
keyword itself might be somewhat confusing; a local server block
parameter affecting the global listen/bind parameters affecting all
other server definitions. I’m actually not sure I understand it myself
correctly.

I’ll try to write something clarifying this in the wiki.

Thank you,
– Kuisma

Posted at Nginx Forum: