Opened 6 years ago

Closed 6 years ago

#552 closed defect (invalid)

Nginx doesn't honor net.ipv6.conf.all.disable_ipv6

Reported by: openid.yandex.ru/loft1712 Owned by:
Priority: major Milestone:
Component: nginx-core Version:
Keywords: nginx, ipv6 Cc:
uname -a: Linux example.com 3.2.0-4-amd64 #1 SMP Debian 3.2.57-3 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.6.0
built by gcc 4.7.2 (Debian 4.7.2-5)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_spdy_module --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed' --with-ipv6

Description

Changeset http://hg.nginx.org/nginx/rev/ec8594b9bf11 should disable IPv6 requests to the backend in case of net.ipv6.conf.all.disable_ipv6=1

IPv6 is disabled on our system, however nginx still tries to send requests using IPv6:

$ sysctl -a | fgrep disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1

error.log:

2014/04/30 07:07:00 [error] 3013#0: *705888 connect() to [2a00:bdc0:2:c:2::1b61]:80 failed (101: Network is unreachable) while connecting to upstream, client: 111.222.333.444, server: example.com, request: "GET / HTTP/1.1", upstream: "http://[2a00:bdc0:2:c:2::1b61]:80/", host: "example.com", referrer: "http://example.com/"

Could you fix this issue or suggest quick workaround?

Change History (8)

comment:1 by Ruslan Ermilov, 6 years ago

The changeset you mention only affects whether getaddrinfo() will return IPv6 addresses when resolving host names during the configuration parsing. But from the error.log snippet you provided it looks like you have IPv6 literal [2a00:bdc0:2:c:2::1b61] specified in your nginx configuration file.

comment:2 by openid.yandex.ru/loft1712, 6 years ago

We use the following configuration, which doesn't contain any IPv6 literals.

  location ~ ^/([\w-]*)/(.*) {
    proxy_set_header      X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_ignore_headers  X-Accel-Redirect;
    resolver              8.8.8.8;
    resolver_timeout      5s;
    proxy_pass            http://$1.example.org/$2;
  }

comment:3 by openid.yandex.ru/loft1712, 6 years ago

I performed some testing.
The easiest way to reproduce this issue is by using the following config:

  location ~ ^/nginx/(\w+)/(.*) {
    proxy_set_header      X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_ignore_headers  X-Accel-Redirect;
    resolver              8.8.8.8;
    resolver_timeout      5s;
    proxy_pass            http://$1.nginx.org/$2;
  }

Then requests to http://example.com/nginx/forum/templates/emerald/images/logo.png will lead to errors:

2014/04/30 10:29:23 [error] 16097#0: *1 connect() to [2001:470:c:156::7]:80 failed (101: Network is unreachable) while connecting to upstream, client: 111.222.333.444, server: example.com, request: "GET /nginx/forum/templates/emerald/images/logo.png HTTP/1.1", upstream: "http://[2001:470:c:156::7]:80/templates/emerald/images/logo.png", host: "example.com"

I was able to reproduce this issue only when I was using regexp captured groups in proxy_pass destination.

comment:4 by Ruslan Ermilov, 6 years ago

By using variables in "proxy_pass" you requested resolution of hostnames at run time. This is done by a built-in resolver. The built-in resolver can't use getaddrinfo() which may block the calling process which is unacceptable.

The net.ipv6.conf.all.disable_ipv6 Linux sysctl support is implicit in nginx when it uses getaddrinfo() to resolve hostnames which it only does at configuration time. At run time, the built-in resolver is used which doesn't use getaddrinfo() and thus doesn't support Linux-specific sysctl.

comment:5 by openid.yandex.ru/loft1712, 6 years ago

Thank you for the explanation.

Could you add a configuration option to disable IPv6 requests?

comment:6 by Ruslan Ermilov, 6 years ago

You can disable IPv6 support in nginx completely by configuring it without the --with-ipv6 configuration option.

comment:7 by Ruslan Ermilov, 6 years ago

"resolver ... ipv6=off"

comment:8 by Maxim Dounin, 6 years ago

Resolution: invalid
Status: newclosed

Closing this.

Note: See TracTickets for help on using tickets.