将非 SNI 浏览器重定向到 nginx 中的仅 HTTP 警告页面
Redirecting non-SNI browsers to HTTP-only warning page in nginx
使用仅 SNI 证书(Let's Encrypt,CloudFlare 免费)时,使用 Windows XP 和 Chrome 或 IE 的用户是 not able to connect to your site。 XP 上的 Firefox 运行良好。
我想测试用户代理是 XP 上的 Chrome 还是 XP 上的 IE(或 XP 上不是 Firefox 的任何东西),并将它们重定向到一个 HTTP 警告页面,告诉他们使用XP 上的 Firefox。
在 nginx 下你会怎么做?
目前,我正在使用此块将所有 http 链接重定向到 https。
if ($http_cf_visitor ~ '{"scheme":"http"}') {
return 301 https://$server_name$request_uri;
}
如何将上述用户代理检测合并到此块中,以便将非 SNI 用户重定向到仅 HTTP 警告页面?
您可以使用 nginx 用户代理映射来检测和重定向非 SNI 客户端(IE 和 Chrome XP 上的浏览器)。只需将其放入站点配置文件(服务器块外部):
map $http_user_agent $is_xp {
default 0;
"~Windows NT 5.1" 1;
}
map $http_user_agent $whitelist_browser {
default 0;
"~Firefox" 1;
}
map $is_xp$whitelist_browser $no_sni {
default 0;
"10" 1;
}
第一个映射在用户代理字符串 (=Windows XP) 中检查 Winhdows NT 5.1,但是因为 Firefox 不依赖 XP 的 SSL 实现并且有自己的支持 SNI 的库,我们最好将其列入白名单浏览器甚至在 XP 上,这就是第二张地图所做的。第三张地图只是将这两个条件结合在一起。
所以现在我们可以在服务器块中使用它来做我们想做的事了:
if ($no_sni = 1) {
# do whatever (redirect...???)
}
但是!!! 此解决方案仅适用于直接在地址栏中输入 URL 的访问者(浏览器默认为 HTTP)。想象一下 Google(或任何人)抓取您的网站,将其检测为 HTTPS(机器人的用户代理既不是 XP 也不是 IE)并且当然 将其索引为 HTTPS 的情况,它会在搜索结果页面上显示为 HTTPS!因此,使用非 SNI 客户端的用户将从搜索中直接重定向到 HTTPS,你又遇到麻烦了。
唯一的解决方法 是从 CA (letsencrypt, ...) 请求一个大证书,将您服务器上托管的所有域列为 SAN,并将此证书用作默认 SSL证书。因此,如果任何非 sni 客户端访问您的服务器,它将获得包含所有域的通用证书,一切都会正常。
使用仅 SNI 证书(Let's Encrypt,CloudFlare 免费)时,使用 Windows XP 和 Chrome 或 IE 的用户是 not able to connect to your site。 XP 上的 Firefox 运行良好。
我想测试用户代理是 XP 上的 Chrome 还是 XP 上的 IE(或 XP 上不是 Firefox 的任何东西),并将它们重定向到一个 HTTP 警告页面,告诉他们使用XP 上的 Firefox。
在 nginx 下你会怎么做?
目前,我正在使用此块将所有 http 链接重定向到 https。
if ($http_cf_visitor ~ '{"scheme":"http"}') {
return 301 https://$server_name$request_uri;
}
如何将上述用户代理检测合并到此块中,以便将非 SNI 用户重定向到仅 HTTP 警告页面?
您可以使用 nginx 用户代理映射来检测和重定向非 SNI 客户端(IE 和 Chrome XP 上的浏览器)。只需将其放入站点配置文件(服务器块外部):
map $http_user_agent $is_xp {
default 0;
"~Windows NT 5.1" 1;
}
map $http_user_agent $whitelist_browser {
default 0;
"~Firefox" 1;
}
map $is_xp$whitelist_browser $no_sni {
default 0;
"10" 1;
}
第一个映射在用户代理字符串 (=Windows XP) 中检查 Winhdows NT 5.1,但是因为 Firefox 不依赖 XP 的 SSL 实现并且有自己的支持 SNI 的库,我们最好将其列入白名单浏览器甚至在 XP 上,这就是第二张地图所做的。第三张地图只是将这两个条件结合在一起。
所以现在我们可以在服务器块中使用它来做我们想做的事了:
if ($no_sni = 1) {
# do whatever (redirect...???)
}
但是!!! 此解决方案仅适用于直接在地址栏中输入 URL 的访问者(浏览器默认为 HTTP)。想象一下 Google(或任何人)抓取您的网站,将其检测为 HTTPS(机器人的用户代理既不是 XP 也不是 IE)并且当然 将其索引为 HTTPS 的情况,它会在搜索结果页面上显示为 HTTPS!因此,使用非 SNI 客户端的用户将从搜索中直接重定向到 HTTPS,你又遇到麻烦了。
唯一的解决方法 是从 CA (letsencrypt, ...) 请求一个大证书,将您服务器上托管的所有域列为 SAN,并将此证书用作默认 SSL证书。因此,如果任何非 sni 客户端访问您的服务器,它将获得包含所有域的通用证书,一切都会正常。