IPv4 & IPv6

Hello,

I noticed in an article dedicated to the subject
(Fr)http://blog.pastoutafait.org/billets/activer-le-support-ipv6-de-nginxthat
to allow Nginx to listen both on IPv4 and IPv6 interfaces
simultaneously, you needed to set sysctl with the following
configuration
(otherwise Nginx listening binds conflict one with each other):

net.ipv6.bindv6only = 1

However, this has conflicting and unwanted effects on other applications
such as Java.

Is there any other way to allow Nginx ot listen on both interface types
without mandatory system configuration?

Thanks,

B. R.

Hello!

On Fri, Apr 05, 2013 at 04:17:09PM -0400, B.R. wrote:

However, this has conflicting and unwanted effects on other applications
such as Java.

Is there any other way to allow Nginx ot listen on both interface types
without mandatory system configuration?

There is “ipv6only” parameter of the “listen” directive, which
allows to listen on ipv6 and ipv4 sockets reliably and
simulteniously regardless of the system configuration.
Configuration like

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

will do the trick.

As of nginx 1.3.x, the ipv6only=on is used by default and there is
no need to specify it explicitly.

See Module ngx_http_core_module for more details.


Maxim D.
http://nginx.org/en/donation.html

On Apr 5, 2013, at 4:17 PM, “B.R.” [email protected] wrote:

Is there any other way to allow Nginx ot listen on both interface types without
mandatory system configuration?

I just have “listen *:80” in my configurations, and it works fine over
IPv4 and IPv6.

Everything you need to know:

http://nginx.org/en/docs/http/ngx_http_core_module.html#listen

Hello,

@Maxim
I tried the duplicate configuration entries:
listen 80;
listen [::]:80 ipv6only=on;

I has the following error:
nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3

@Ted
I​ tested your solution but as I expected nginx is only listening on
IPv4
interfaces after restart and not IPv6 ones anymore.​

B. R.

Hello!

On Fri, Apr 05, 2013 at 06:07:23PM -0400, B.R. wrote:

Hello,

@Maxim
I tried the duplicate configuration entries:
listen 80;
listen [::]:80 ipv6only=on;

I has the following error:
nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3

If you have multiple virtual server{}s with the same listening
sockets used, you have to specify listening options in a single listen
directive only.

That is, add “ipv6only=on” to a listen directive in first/default
server in your configuration. This will do the trick.


Maxim D.
http://nginx.org/en/donation.html

On Apr 5, 2013, at 6:07 PM, B.R. [email protected] wrote:

@Ted
I​ tested your solution but as I expected nginx is only listening on IPv4
interfaces after restart and not IPv6 ones anymore.​

Weird. I have this:

            listen 443 ssl;
            listen [::]443 ipv6only=on ssl;

But aside from that, I don’t have any references to ipv6 in the
configuration, and it is listening on [::]/80.

I have indeed several virtual servers.

I have a specific one which serves different content whether a client
connects in HTTP or HTTPS (basically the HTTP content provides
directions
for the HTTPS setup).
I also have one virtual server which I want listening on IPv4 only, not
IPv6.

That’s why I prefer managing the listen directives in virtual servers
rather than in the ‘http’ directive block.

Is there no other mean than using global ‘listen’ directives?

B. R.

Hmm…

@Maxim
I guess I haven’t understood your piece of advice, since ‘listen’ can
only
be used in ‘server’ directive…
What is it you wanted me to try, again? :oD

B. R.

Hello,

It seems I solved the problem…
It was indeed by reading a little more carefully the doc
http://wiki.nginx.org/HttpCoreModule#listen, thanks @Lukas! ;o)

The ‘*:80’ syntax is used for IPv4 listening, I don’t understand why it
works as-is for you Ted. Maybe Maxim will be of a better help on that
case.

It is said that the IPv6 syntax will make Nginx listen for the 6to4 IP
address syntax, making the websites reachable through IPv4, even if no
specific IPv4 binding exist for the listening sockets.
Using:
listen [::]:80;

I have:
$ sudo ss -lnp|grep nginx
0 128 :::80
:::* users:((“nginx”,,11),(“nginx”,,11))
0 128 :::443
:::* users:((“nginx”,,12),(“nginx”,,12))

You shall not have 2 ‘listen’ directive if you did not separate you
IPv6
and IPv4 stacks (with the sysctl net.ipv6.bindv6only directive set to
1).
I had that configuration before, but the sysctl configuration has an
impact
on the whole system and also on Java which, when listening on IPv6,
seems
not to be reachable through 6to4 syntax.

I still need to confirm my websites are accessible in the same fashion
with
IPv4 or IPv6, but I guess my trouble comes from bad IPv6 routing, not
from
the webserver.

Thanks for your input, everyone!

B. R.

Hello!

On Sat, Apr 06, 2013 at 02:25:54AM -0400, B.R. wrote:

address syntax, making the websites reachable through IPv4, even if no

You shall not have 2 ‘listen’ directive if you did not separate you IPv6
and IPv4 stacks (with the sysctl net.ipv6.bindv6only directive set to 1).

This is wrong aproach and it will no longer work for you after
1.3.x upgrade. As I already suggested, use

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

instead as a portable solution, which doesn’t depend on a system
configuration. (In 1.3.x, the “ipv6only=on” part can be removed
as it’s now the default.)


Maxim D.
http://nginx.org/en/donation.html

But as I noticed earlier, these configuration directives conflict with
each
other across multiple virtual servers…
That’s a huge step backwards.

H
​aving to specify them only once across every configuration file is
counter-intuitive.
Why isn’t nginx able to ​summarize all the needs for listening sockets
across configuraiton files before attempting to open them?
Having to define those listening directives in a ‘generic default
server’
is awkward and looks ugly.


B. R.

server {
listen 80;
listen [::]:80 ipv6only=on;
server_name one;

}

server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name one;

}


Igor S.

Add-on:

Besides, as I explained earlier, having generic ‘listen’ directives
implies
some difficulties.

For example, I am using 2 virtual servers to serve content for the same
server_name, one listening on port 80, the other on port 443, allowing
me
to serve cotnent for HTTP and HTTPS in different fashions.
Using generic ‘listen’ directive breaks that system and I’m stuck.

What would be an acceptable solution?
Thanks,

B. R.

That’s exactly what I tried first, and if there are multiple servers
listening to same ports, I get the following error:
nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3
See follow-up messages or (through the forum archive on this subject):

I have the feeling we entered a loop back to the top of the subject…

Let me summarize :
Attempt #1
listen 80;
listen [::]:80 ipv6only=on;

Only works if a single server contains those directives.
Produces error ‘nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3’ if several servers use them to listen to
the
same ports.

Attempt #2
listen [::]:80;

‘Wrong approach’ said Maxim, since it won’t work in 1.4 stable due to
changes in the 1.3 dev branch.
However, in 1.2, that’s the only working way I have to decide on
per-server
level which protocol and ports they need to listen to.

I’m stuck.

B. R.

Hello!

On Sat, Apr 06, 2013 at 04:05:22PM -0400, B.R. wrote:

That’s exactly what I tried first, and if there are multiple servers
listening to same ports, I get the following error:
nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3

You’ve already been told to only specify listen options once.
That is, you should write

server {
    listen [::]:80 ipv6only=on;
    ...
}

server {
    listen [::]:80;
    ...
}

instead of

server {
    listen [::]:80 ipv6only=on;
    ...
}

server {
    listen [::]:80 ipv6only=on;
    ...
}

in your config.


Maxim D.
http://nginx.org/en/donation.html

Thanks Maxim !

There was a misunderstanding there, I thought I shouldn’t use the whole
directive, I didn’t get that only the ‘ipv6only=on’ part was not to be
repeated amongst servers.

Works great (‘of course it does!’ ;o)).
Thanks for the help again,

B. R.

On 4/6/13 4:05 PM, B.R. wrote:

That’s exactly what I tried first, and if there are multiple servers
listening to same ports, I get the following error:
nginx: [emerg] duplicate listen options for [::]:80 in
/etc/nginx/conf.d/***.conf:3
See follow-up messages or (through the forum archive on this subject):
Re: IPv4 & IPv6

Please do not top post just because that’s where the insertion point is
in your email client. It makes following, and, more importantly, later
searching through a thread, rather difficult. Think of it this way - you
don’t shit in your pants just because that’s where your asshole is. It’s
annoying enough that you use HTML mail. Plain text is preferable.

/etc/nginx/conf.d/***.conf:3’ if several servers use them to listen to
I’m stuck.
Why not try to use specific IPv6 addresses in your vhost config files?
This may be a band-aid for your system. It also works because it’s what
we do.

Most hosts allocate a large block of IPv6 addresses at a time. We get a
/48 or a /64 at a time, depending on the provider. That’s hundreds of
thousands of addresses. So we give each vhost a unique IPv6, even if
we’re not using SSL.

For instance, I host the nginx forum. The first few lines of the config
file are:

server {
listen [2001:49f0:1018::5]:80;
listen 80;
server_name forum.nginx.org;

}

For a vhost with both standard and ssl ports, we use something like
this:

server {
listen 80;
listen ip.v4.add.ress:443 ssl;
listen [2001:49f0:1018::a]:80;
listen [2001:49f0:1018::a]:443 ssl;
server_name domain.tld;

}

This way there is no competition for what is listening on IPv6 addresses
and you should not see that error. I’ve been doing it this way for at
least a couple of years now, certainly before 1.0.x series came out. It
may not be the “recommended” approach but it’s what I had to do to get
it back then. One caveat - I am using FreeBSD and IPv6 may be
implemented differently in GNU/Linux.

     server_name  one;
    Why isn't nginx able to ​summarize all the needs for listening

        >
        > Using:
        separate you IPv6
        system
        configuration.  (In 1.3.x, the "ipv6only=on" part can be
        removed
        as it's now the default.)

        --
        Maxim D.
        http://nginx.org/en/donation.html


Jim O.

On Apr 7, 2013, at 0:44 , Jim O. wrote:

This way there is no competition for what is listening on IPv6 addresses
and you should not see that error. I’ve been doing it this way for at
least a couple of years now, certainly before 1.0.x series came out. It
may not be the “recommended” approach but it’s what I had to do to get
it back then. One caveat - I am using FreeBSD and IPv6 may be
implemented differently in GNU/Linux.

On FreeBSD dual stack sockets are disabled by default:

sysctl net.inet6.ip6.v6only
net.inet6.ip6.v6only: 1

while on Linux they are enabled:

cat /proc/sys/net/ipv6/bindv6only
0


Igor S.