Nginx Fails to connect when Upstream resolves to IPv6

Viewed 6468

I have configurations in nginx that perform proxy_pass to google-analytics.com. But as you know google-analytics same times resolves to ipv4 and at times to ipv6 when it does resolve to ipv6 nginx fails with this error.

connect() to [2a00:xxx:xxx:809::xxx]:443 failed (101: Network is unreachable) while connecting to upstream. ( I just obfuscated the real ip of the upstream)

upstream server temporarily disabled while connecting to upstream

Why does nginx faile with upstream in proxy_pass resolves to ipv6?

server {
     server_name upstream.nmmapper.com;
     location /.well-known/acme-challenge/ {
        allow all;
        root /var/www/letsencrypt;
        try_files $uri =404;
        break;
     }
}
location = /analytics.js {
        proxy_set_header Accept-Encoding "";
        proxy_pass https://www.google-analytics.com/analytics.js;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
    }
2 Answers

Try adding ipv6 listen [::]:80 directive:

server {
  listen 80;
  listen [::]:80; 
  server_name upstream.nmmapper.com;
  ...
}

For ssl:

listen 443 ssl;
listen [::]:443 ssl;

To always connect over IPv4 you need to add a resolver with ipv6=off.

However, 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;
}

Source: https://serverfault.com/a/1006465/242991.

In your case this should work:

location = /analytics.js {
    resolver 1.1.1.1 ipv6=off valid=30s;
    set $empty "";
    proxy_set_header Accept-Encoding "";
    proxy_pass https://www.google-analytics.com/analytics.js$empty;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
}
Related