Loading... 在最近几年里,我写了很多有关 HTTPS 和 HTTP/2 的文章,涵盖了证书申请、Nginx 编译及配置、性能优化等方方面面。在这些文章的评论中,不少读者提出了各种各样的问题,我的邮箱也经常收到类似的邮件。本文用来罗列其中有代表性、且我知道解决方案的问题。<!--more--> 为了控制篇幅,本文尽量只给出结论和引用链接,不展开讨论,如有疑问或不同意见,欢迎留言讨论。本文会持续更新,欢迎大家贡献自己遇到的问题和解决方案。 > 实际上,遇到任何有关部署 HTTPS 或 HTTP/2 的问题,都推荐先用 [Qualys SSL Labs's SSL Server Test](https://www.ssllabs.com/ssltest/index.html) 跑个测试,大部分问题都能被诊断出来。 ### 申请 Let's Encrypt 证书时,一直无法验证通过 这类问题一般是因为 Let's Encrypt 无法访问你的服务器,推荐尝试 [acme.sh](https://github.com/Neilpang/acme.sh) 的 [DNS 验证模式](https://github.com/Neilpang/acme.sh#7-use-dns-mode),一般都能解决。 ### 网站无法访问,提示 ERR_CERTIFICATE_TRANSPARENCY_REQUIRED 使用 Chrome 53 访问使用 Symantec 证书的网站,很可能会出现这个错误提示。这个问题由 Chrome 的某个 Bug 引起,目前最好的解决方案是升级到 Chrome 最新版。相关链接: * [Out of date Chrome results in ERR_CERTIFICATE_TRANSPARENCY_REQUIRED for Symantec operated sites](https://bugs.chromium.org/p/chromium/issues/detail?id=664177); * [Warning | Certificate Transparency error with Chrome 53](https://knowledge.symantec.com/support/ssl-certificates-support/index?page=content&id=ALERT2160); ### 浏览器提示证书有错误 #### 检查证书链是否完整 首先确保网站使用的是合法 CA 签发的有效证书,其次检查 Web Server 配置中证书的完整性(一定要包含站点证书及所有中间证书)。如果缺失了中间证书,部分浏览器能够自动获取但严重影响 TLS 握手性能;部分浏览器直接报证书错误。 > [What's My Chain Cert?](https://whatsmychaincert.com/) 这个网站可以用来检查证书链是否完整,它还可以用来生成正确的证书链。 #### 检查浏览器是否支持 SNI 如果只有老旧浏览器(例如 IE8 on Windows XP)提示这个错误,多半是因为你的服务器同时部署了使用不同证书的多个 HTTPS 站点,这样,不支持 SNI(Server Name Indication)的浏览器通常会获得错误的证书,从而无法访问。 要解决浏览器不支持 SNI 带来的问题,可以将使用不同证书的 HTTPS 站点部署在不同服务器上;还可以利用 SAN(Subject Alternative Name)机制将多个域名放入同一张证书;当然你也可以直接无视这些老旧浏览器。特别地,使用不支持 SNI 的浏览器访问商业 HTTPS CDN,基本都会因为证书错误而无法使用。 > 有关 SNI 的更多说明,请看「[关于启用 HTTPS 的一些经验分享(二)](https://imququ.com/post/sth-about-switch-to-https-2.html#toc-2)」。 #### 检查系统时间 如果用户电脑时间不对,也会导致浏览器提示证书有问题,这时浏览器一般都会有明确的提示,例如 Chrome 的 ERR_CERT_DATE_INVALID。 ### 启用 HTTP/2 后网站无法访问,提示 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY 这个问题一般是由于 CipherSuite 配置有误造成的。建议对照「[Mozilla 的推荐配置](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations)、[CloudFlare 使用的配置](https://github.com/cloudflare/sslconfig/blob/master/conf)」等权威配置修改 Nginx 的 `ssl_ciphers` 配置项。 > 有关这个问题的具体原因,请看「[从启用 HTTP/2 导致网站无法访问说起](https://imququ.com/post/why-tls-handshake-failed-with-http2-enabled.html)」。 ### 网站无法访问,提示 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 出现这种错误,通常都是配置了不安全的 SSL 版本或者 CipherSuite —— 例如服务器只支持 SSLv3,或者 CipherSuite 只配置了 RC4 系列,使用 Chrome 访问就会得到这个提示。解决方案跟上一节一样。 还有一种情况会出现这种错误 —— 使用不支持 ECC 的浏览器访问只提供 ECC 证书的网站。例如在 Windows XP 中,使用 ECC 证书的网站只有 Firefox 能访问(Firefox 的 TLS 自己实现,不依赖操作系统);Android 平台中,也需要 Android 4+ 才支持 ECC 证书。 > 针对不支持 ECC 证书的浏览器,有一个完美的解决方案,请看「[开始使用 ECC 证书](https://imququ.com/post/ecc-certificate.html)」。 ### 在 Nginx 启用 HTTP/2 后,浏览器依然使用 HTTP/1.1 Chrome 51+ 移除了对 NPN 的支持,只支持 ALPN,而浏览器和服务端都支持 NPN 或 ALPN,是用上 HTTP/2 的大前提。换句话说,如果服务端不支持 ALPN,Chrome 51+ 无法使用 HTTP/2。 OpenSSL 1.0.2 才开始支持 ALPN —— 很多主流服务器系统自带的 OpenSSL 都低于这个版本,所以推荐在编译 Web Server 时自己指定 OpenSSL 的位置。 > 详见「[为什么我们应该尽快支持 ALPN](https://imququ.com/post/enable-alpn-asap.html)」。 ### 升级到 HTTPS 后,网站部分资源不加载或提示不安全 记住一个原则:HTTPS 网站的所有外链资源(CSS、JS、图片、音频、字体文件、异步接口、表单 action 地址等等)都需要升级为 HTTPS,就不会遇到这个问题了。 > 详见「[关于启用 HTTPS 的一些经验分享(三)](https://imququ.com/post/sth-about-switch-to-https-3.html)」。 ### 仅 Safari、iOS 各种浏览器无法访问 如果你的 HTTPS 网站用 PC Chrome 和 Firefox 访问一切正常,但 macOS Safari 和 iOS 各种浏览器无法访问,有可能是 Certificate Transparency 配置有误。当然,如果你之前没有通过 TLS 扩展启用 Certificate Transparency,请跳过本小节。 具体症状是:通过 Wireshark 抓包分析,通常能看到名为 Illegal Parameter 的 Alert 信息;通过 `curl -v` 排查,一般能看到 Unknown SSL protocol error in connection 错误提示。 这时候,请进入 Nginx `ssl_ct_static_scts` 配置指定的目录,检查 SCT 文件大小是否正常,尤其要关注是否存在空文件。 > 需要注意的是:根据[官方公告](https://groups.google.com/a/chromium.org/forum/#!msg/ct-policy/u87C79AY-E8/VM4K1v8qCgAJ),从 2016 年 12 月 1 日开始,Google 的 Aviator CT log 服务将不再接受新的证书请求。用 [ct-submit](https://github.com/grahamedgecombe/ct-submit) 等工具手动获取 SCT 文件时,不要再使用 Aviator 服务,否则就会得到空文件。 > 更新:nginx-ct 的作者已经发布了 [v1.3.2](https://github.com/grahamedgecombe/nginx-ct/releases),针对零字节的 SCT 文件做了处理,不再发送。 ### 将 OpenSSL 升级到 1.1.0+,IE8 无法访问 造成这个问题的根本原因是 OpenSSL 1.1.0+ 默认禁用了 3DES 系列的 Cipher Suites: > For the 1.1.0 release, which we expect to release tomorrow, we will treat triple-DES just like we are treating RC4. It is not compiled by default; you have to use “enable-weak-ssl-ciphers” as a config option. [via](https://www.openssl.org/blog/blog/2016/08/24/sweet32/) 升级到 OpenSSL 1.1.0+ 之后,要么选择不支持 Windows XP + IE8;要么在编译时加上 `enable-weak-ssl-ciphers` 参数。例如这是我的 Nginx 编译参数: ```shell ./configure --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.2 --with-openssl=../openssl --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module ``` 最后修改:2018 年 11 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏