我刚刚在基于 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。