Opened 11 years ago

Closed 11 years ago

#364 closed defect (invalid)

Listen directive broken

Reported by: Petre Rodan Owned by:
Priority: major Milestone:
Component: nginx-core Version: 1.3.x
Keywords: Cc:
uname -a: Linux notif5 3.2.43-grsec-a084 #1 SMP Sat Apr 13 21:49:18 EEST 2013 x86_64 Intel(R) Xeon(R) CPU E5620 @ 2.40GHz GenuineIntel GNU/Linux
nginx -V: nginx version: nginx/1.4.1
TLS SNI support enabled
configure arguments: --prefix=/usr --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error_log --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --with-cc-opt=-I/usr/include --with-ld-opt=-L/usr/lib --http-log-path=/var/log/nginx/access_log --http-client-body-temp-path=//var/lib/nginx/tmp/client --http-proxy-temp-path=//var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=//var/lib/nginx/tmp/fastcgi --http-scgi-temp-path=//var/lib/nginx/tmp/scgi --http-uwsgi-temp-path=//var/lib/nginx/tmp/uwsgi --with-ipv6 --with-pcre --without-http_charset_module --without-http_empty_gif_module --without-http_geo_module --without-http_map_module --without-http_memcached_module --without-http_scgi_module --without-http_ssi_module --without-http_split_clients_module --without-http_upstream_ip_hash_module --without-http_userid_module --without-http_uwsgi_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_realip_module --add-module=/local/portage/build/portage/www-servers/nginx-1.4.1-r2/work/headers-more-nginx-module-0.20 --without-http-cache --with-http_ssl_module --without-mail_imap_module --without-mail_pop3_module --without-mail_smtp_module --user=nginx --group=nginx

Description

I am maintaining a lot of servers all placed in dns round-robin. all nginx configs are the same on all servers, so I don't want to provide Listen directive followed by given ipv4/ipv6 addresses. I want nginx to bind to all v4+v6 interfaces, on port 80 and use HOST name-based selection of vhosts.

in nginx 1.2.x, simply providing
Listen [::]:80;
on all vhosts on one server worked great. all v4+v6 interfaces were bound and the correct vhost was selected based on the hostname used in requests.

in 1.4.x I tried different scenarios, as follows:

  1. providing the same configurations that work in nginx 1.2.x (Listen [::]:80;), but now only ipv6 interfaces are bound. ipv4 is ignored. bad.

this is in complete contradiction with this wiki statement :
"When you enable the address [::]:80, binding port 80 using IPv6, in the listen directive, in Linux, by default, the IPv4 port 80 is also enabled."
all my servers have

# sysctl -a | grep bindv6only
net.ipv6.bindv6only = 0
# cat /proc/sys/net/ipv6/bindv6only
0
# netstat -pant | grep LISTEN | grep 80
tcp6 0 0 :::80 :::* LISTEN 3296/nginx: master
# telnet 127.0.0.1 80
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused

  1. using as per the wiki

listen [::]:80 ipv6only=on;
listen 80;
on all vhosts on a server errors out with:
2013/05/31 10:12:37 [emerg] 17744#0: duplicate listen options for [::]:80 in /etc/nginx/vhosts/censored.com.conf:2
unusable probably because I won't change the default bindv6only kernel behaviour.

  1. using

listen 80;
on all vhosts loads the config, but no ipv6 interfaces are bound. I guess this is the intended behavior as per the wiki. but it's unusable for me since I also need all ipv6 interfaces.

to me it looks like it's a bug in scenario 1.

Change History (1)

comment:1 by Maxim Dounin, 11 years ago

Resolution: invalid
Status: newclosed

As of nginx 1.3.4+, ipv6only defaults to on, regardless of operation system settings, see CHANGES:

    *) Change: the "ipv6only" parameter is now turned on by default for
       listening IPv6 sockets.

That is, in 1.3.4+ it's enough to write

    listen 80;
    listen [::]:80;

to listen on both IPv4 and IPv6 regardless of operation system and it's settings.

The (2) will also work, but you have to write listen options (that is, "ipv6only=on") only once, not in every virtual host. That is, you have to write something like this:

server {
     listen 80;
     listen [::]:80 ipv6only=on;
     server_name default.example.com;
     ...
}
server {
     listen 80;
     listen [::]:80;
     server_name virtual.example.com;
     ...
}

See http://nginx.org/r/listen for details.

Note: See TracTickets for help on using tickets.