Disable IPv6 in nginx proxy_pass
My server doesn't have IPv6 adresses.
However, when I use Nginx proxy_pass to upstream with IPv4 and IPv6, sometimes it tries to send outgoing requests using IPv6:
2013/07/30 00:25:06 [error] 1930#0: *1482670 connect() to [AAAA:BBBB:C:DDD:E:F:GGG:HHH]:443 failed (101: Network is unreachable) while connecting to upstream, client: AA.BB.CC.DD, server: example.com, request: "GET /download/file HTTP/1.0", upstream: "https://[AAAA:BBBB:C:DDD:E:F:GGG:HHH]:443/download/file", host: "example.com"
How can I disable IPv6 for outgoing requests in proxy_pass?
nginx.conf:
upstream download {
server download.example.com:443;
keepalive 8;
}
location /download {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
proxy_ignore_headers X-Accel-Redirect;
proxy_http_version 1.1;
resolver 8.8.8.8;
resolver_timeout 5s;
proxy_pass https://download;
}
nginx -V:
nginx version: nginx/1.4.2
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-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 --with-ipv6
OS: Debian Wheezy
Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 6c:62:6d:7a:ea:af brd ff:ff:ff:ff:ff:ff
inet XXX.XXX.XXX.XXX/27 brd XXX.XXX.XXX.XXX scope global eth0
Looks like there are a solution since nginx >= 1.5.8:
resolver 8.8.8.8 ipv6=off;
You can find more here: http://nginx.org/en/docs/http/ngx_http_core_module.html
Nginx is doing DNS resolution at startup by default.
Include (an empty) variable in the hostname to force Nginx to do resolution at runtime with the specified resolver directive.
location / {
resolver 1.1.1.1 ipv6=off valid=30s;
set $empty "";
proxy_pass https://example.com$empty;
}
Using the resolver
did not work for me when using proxy_pass
to a https url. I had to modify the sysctl.
- Add the following lines in
/etc/sysctl.conf
.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 net.ipv6.conf.eth1.disable_ipv6 = 1 net.ipv6.conf.eth2.disable_ipv6 = 1 net.ipv6.conf.eth3.disable_ipv6 = 1
- Reboot system with
sysctl -p
. - Reboot nginx with
sudo nginx -s reload
.