启用 IPv6 后,nginx 虚拟主机无法工作

启用 IPv6 后,nginx 虚拟主机无法工作

我刚刚在基于 Debian Jessie 的 nginx 1.8.0 网络服务器上启用了 IPv6。为此,我编辑了我的虚拟主机配置:

server {
    listen 80;
    listen [2001:1608:10:160:34::2]:80;
    server_name dominicpratt.de www.dominicpratt.de;
    return 301 https://dominicpratt.de$request_uri;
}

server {
    listen 443;
    listen [2001:1608:10:160:34::2]:443;
    server_name dominicpratt.de www.dominicpratt.de;
    root /var/www/dominicpratt.de;

    index index.html index.htm index.php;
    access_log /var/log/nginx/dominicpratt.de_access.log;

    ssl on;
    ssl_certificate /etc/nginx/ssl/dominicpratt.de/combined.pem;
    ssl_certificate_key /etc/nginx/ssl/dominicpratt.de/wildcard.key;

    location / {
            try_files $uri $uri/ /index.php?q=$request_uri;
    }

    location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm-www.sock;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
    }

    location ~*  \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 365d;
    }

}

现在我的网站 dominicpratt.de 运行正常,但我的子域名却不行。它们重定向到 dominicpratt.de - 例如:rss.dominicpratt.de 和以下配置:

server {
    listen 80;
    listen [2001:1608:10:160:34::5]:80;
    server_name rss.dominicpratt.de;
    return 301 https://rss.dominicpratt.de$request_uri;
}

server {
    listen 443;
    listen [2001:1608:10:160:34::5]:443;
    server_name rss.dominicpratt.de;
    root /var/www/rss.dominicpratt.de;

    index index.html index.htm index.php;
    access_log /var/log/nginx/rss.dominicpratt.de_access.log;

    ssl on;
    ssl_certificate /etc/nginx/ssl/dominicpratt.de/combined.pem;
    ssl_certificate_key /etc/nginx/ssl/dominicpratt.de/wildcard.key;

    location / {
            try_files $uri $uri/ /index.php?q=$request_uri;
    }

    location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm-www.sock;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
    }
}

我无法联系https://rss.dominicpratt.de以及所有其他子域。如果我删除或注释掉服务器块中的 IPv6 监听行,它就会正常工作。

答案1

Nginx 1.8.0 有一个 bug[1](已在 1.8.1 中修复),默认情况下会启用 SPDY/h2。使用 http/2 的浏览器会尝试为每个服务器仅打开一个连接[2]。Firefox 会以非常激进的方式做到这一点[3]。即使 IPv6 地址不匹配(但 IPv4 地址匹配且证书匹配),它也会跨主机名重用 IPv6 连接。使用通配符证书可能会导致观察到的问题[4],即提供错误域的内容。

在这种情况下,浏览器试图取消分片子域名来优化速度,错误地认为不同的子域名只是为了优化 http/1 中的速度(即通过使用 stattic1.example.com 和 static2.example.com 来并行获取更多服务器连接)。

可以通过以下方法解决该问题:A)对域名使用不同的证书;B)对域名使用相同的 IPv6 地址;C)对错误请求发送 http 状态代码 421[5]。

答案2

尝试将 IPv6 地址添加ipv6only=on到您的listen指令中,如下所示:

listen [2001:1608:10:160:34::5]:80 ipv6only=on;
...
listen [2001:1608:10:160:34::5]:443 ipv6only=on;

事实上,在 listen 指令中指定 IPv6 地址并不会默认关闭 IPv4。

相关内容