关于启用,常见部署问题及解决方案

日期:2019-09-10编辑作者:澳门金莎娱乐网站

关于启用 HTTPS 的一些经验分享(二)

2015/12/24 · 基础技术 · HTTP, HTTPS

原文出处: imququ(@屈光宇)   

文章目录

  • SSL 版本选择
  • 加密套件选择
  • SNI 扩展
  • 证书选择

几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个问题应该从两方面来看:1)国内用户终端情况复杂,很多时候降低 SSL 安全配置是为了兼容更多用户;2)确实有一些大厂家的 SSL 配置很不专业,尤其是配置了一些明显不该使用的 CipherSuite。

我之前写的《关于启用 HTTPS 的一些经验分享(一)》,主要介绍 HTTPS 如何与一些新出的安全规范配合使用,面向的是现代浏览器。而今天这篇文章,更多的是介绍启用 HTTPS 过程中在老旧浏览器下可能遇到的问题,以及如何取舍。

几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个问题应该从两方面来看:

如何针对老旧浏览器设置 HTTPS 策略

几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个问题应该从两方面来看:

  1. 国内用户终端情况复杂,很多时候降低 SSL 安全配置是为了兼容更多用户;
  2. 确实有一些大厂家的 SSL 配置很不专业,尤其是配置了一些明显不该使用的 CipherSuite。

我之前写的《关于启用 HTTPS 的一些经验分享(一)》,主要介绍 HTTPS 如何与一些新出的安全规范配合使用,面向的是现代浏览器。而今天这篇文章,更多的是介绍启用 HTTPS 过程中在老旧浏览器下可能遇到的问题,以及如何取舍。

图片 1

 

在最近几年里,我写了很多有关 HTTPS 和 HTTP/2 的文章,涵盖了证书申请、Nginx 编译及配置、性能优化等方方面面。在这些文章的评论中,不少读者提出了各种各样的问题,我的邮箱也经常收到类似的邮件。本文用来罗列其中有代表性、且我知道解决方案的问题。

SSL 版本选择

TLS(Transport Layer Security,传输层安全)的前身是 SSL(Secure Sockets Layer,安全套接字层),它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。TLS 1.3 改动会比较大,目前还在草案阶段。

SSL 1.0 从未公开过,而 SSL 2.0 和 SSL 3.0 都存在安全问题,不推荐使用。Nginx 从 1.9.1 开始默认只支持 TLS 的三个版本,以下是 Nginx 官方文档中对 ssl_protocols 配置的说明:

Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
Default: ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Context: http, server
Enables the specified protocols. The TLSv1.1 and TLSv1.2 parameters work only when the OpenSSL library of version 1.0.1 or higher is used.

但不幸的是,IE 6 只支持 SSLv2 和 SSLv3(来源),也就是说 HTTPS 网站要支持 IE 6,就必须启用 SSLv3。仅这一项就会导致 SSL Labs 给出的评分降为 C。

  1. 国内用户终端情况复杂,很多时候降低 SSL 安全配置是为了兼容更多用户;
  2. 确实有一些大厂家的 SSL 配置很不专业,尤其是配置了一些明显不该使用的 CipherSuite。

SSL 版本选择

TLS(传输层安全(Transport Layer Security))的前身是 SSL(安全套接字层(Secure Sockets Layer)),它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。TLS 1.3 改动会比较大,目前还在草案阶段。

SSL 1.0 从未公开过,而 SSL 2.0 和 SSL 3.0 都存在安全问题,不推荐使用。Nginx 从 1.9.1 开始默认只支持 TLS 的三个版本,以下是 Nginx 官方文档中对 ssl_protocols 配置的说明:

Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
Default: ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Context: http, server
Enables the specified protocols. The TLSv1.1 and TLSv1.2 parameters work only when the OpenSSL library of version 1.0.1 or higher is used.

但不幸的是,IE 6 只支持 SSLv2 和 SSLv3(来源),也就是说 HTTPS 网站要支持 IE 6,就必须启用 SSLv3。仅这一项就会导致 SSL Labs 给出的评分降为 C。

 

为了控制篇幅,本文尽量只给出结论和引用链接,不展开讨论,如有疑问或不同意见,欢迎留言讨论。本文会持续更新,欢迎大家贡献自己遇到的问题和解决方案。

加密套件选择

加密套件(CipherSuite),是在 SSL 握手中需要协商的很重要的一个参数。客户端会在 Client Hello 中带上它所支持的 CipherSuite 列表,服务端会从中选定一个并通过 Server Hello 返回。如果客户端支持的 CipherSuite 列表与服务端配置的 CipherSuite 列表没有交集,会导致无法完成协商,握手失败。

CipherSuite 包含多种技术,例如认证算法(Authentication)、加密算法(Encryption)、消息认证码算法(Message Authentication Code,简称为 MAC)、密钥交换算法(Key Exchange)和密钥衍生算法(Key Derivation Function)。

SSL 的 CipherSuite 协商机制具有良好的扩展性,每个 CipherSuite 都需要在 IANA 注册,并被分配两个字节的标志。全部 CipherSuite 可以在 IANA 的 TLS Cipher Suite Registry 页面查看。

OpenSSL 库支持的全部 CipherSuite 可以通过以下命令查看:

openssl ciphers -V | column -t 0xCC,0x14 - ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=ChaCha20-Poly1305 Mac=AEAD ... ...

1
2
3
openssl ciphers -V | column -t
0xCC,0x14  -  ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2  Kx=ECDH        Au=ECDSA   Enc=ChaCha20-Poly1305  Mac=AEAD
... ...

0xCC,0x14 是 CipherSuite 的编号,在 SSL 握手中会用到。ECDHE-ECDSA-CHACHA20-POLY1305 是它的名称,之后几部分分别表示:用于 TLSv1.2,使用 ECDH 做密钥交换,使用 ECDSA 做认证,使用 ChaCha20-Poly1305 做对称加密,由于 ChaCha20-Poly1305 是一种 AEAD 模式,不需要 MAC 算法,所以 MAC 列显示为 AEAD。

要了解 CipherSuite 的更多内容,可以阅读这篇长文《TLS 协议分析 与 现代加密通信协议设计》。总之,在配置 CipherSuite 时,请务必参考权威文档,如:Mozilla 的推荐配置、CloudFlare 使用的配置。

以上 Mozilla 文档中的「Old backward compatibility」配置,以及 CloudFlare 的配置,都可以很好的兼容老旧浏览器,包括 Windows XP / IE6。

之前见到某个大厂家居然支持包含 EXPORT 的 CipherSuite,这些套件在上世纪由于美国出口限制而被弱化过,已被攻破,实在没有理由再使用。

我之前写的《关于启用 HTTPS 的一些经验分享(一)》,主要介绍 HTTPS 如何与一些新出的安全规范配合使用,面向的是现代浏览器。而今天这篇文章,更多的是介绍启用 HTTPS 过程中在老旧浏览器下可能遇到的问题,以及如何取舍。

加密套件选择

加密套件(CipherSuite),是在 SSL 握手中需要协商的很重要的一个参数。客户端会在 Client Hello 中带上它所支持的 CipherSuite 列表,服务端会从中选定一个并通过 Server Hello 返回。如果客户端支持的 CipherSuite 列表与服务端配置的 CipherSuite 列表没有交集,会导致无法完成协商,握手失败。

CipherSuite 包含多种技术,例如认证算法(Authentication)、加密算法(Encryption)、消息认证码算法(Message Authentication Code)(MAC)、密钥交换算法(Key Exchange)和密钥衍生算法(Key Derivation Function)。

SSL 的 CipherSuite 协商机制具有良好的扩展性,每个 CipherSuite 都需要在 IANA 注册,并被分配两个字节的标志。全部 CipherSuite 可以在 IANA 的 TLS Cipher Suite Registry 页面查看。

OpenSSL 库支持的全部 CipherSuite 可以通过以下命令查看:

  1. openssl ciphers -V | column -t
  2. 0xCC,0x14- ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2Kx=ECDH Au=ECDSA Enc=ChaCha20-Poly1305Mac=AEAD
  3. ......

0xCC,0x14 是 CipherSuite 的编号,在 SSL 握手中会用到。ECDHE-ECDSA-CHACHA20-POLY1305 是它的名称,之后几部分分别表示:用于 TLSv1.2,使用 ECDH 做密钥交换,使用 ECDSA 做认证,使用 ChaCha20-Poly1305 做对称加密,由于 ChaCha20-Poly1305 是一种 AEAD 模式,不需要 MAC 算法,所以 MAC 列显示为 AEAD。

要了解 CipherSuite 的更多内容,可以阅读这篇长文《TLS 协议分析 与 现代加密通信协议设计》。总之,在配置 CipherSuite 时,请务必参考权威文档,如:Mozilla 的推荐配置、CloudFlare 使用的配置。

以上 Mozilla 文档中的「Old backward compatibility」配置,以及 CloudFlare 的配置,都可以很好的兼容老旧浏览器,包括 Windows XP / IE6。

之前见到某个大厂家居然支持包含 EXPORT 的 CipherSuite,这些套件在上世纪由于美国出口限制而被弱化过,已被攻破,实在没有理由再使用。

 

实际上,遇到任何有关部署 HTTPS 或 HTTP/2 的问题,都推荐先用 Qualys SSL Labs's SSL Server Test 跑个测试,大部分问题都能被诊断出来。

SNI 扩展

我们知道,在 Nginx 中可以通过指定不同的 server_name 来配置多个站点。HTTP/1.1 协议请求头中的 Host 字段可以标识出当前请求属于哪个站点。但是对于 HTTPS 网站来说,要想发送 HTTP 数据,必须等待 SSL 握手完成,而在握手阶段服务端就必须提供网站证书。对于在同一个 IP 部署不同 HTTPS 站点,并且还使用了不同证书的情况下,服务端怎么知道该发送哪个证书?

Server Name Indication,简称为 SNI,是 TLS 的一个扩展,为解决这个问题应运而生。有了 SNI,服务端可以通过 Client Hello 中的 SNI 扩展拿到用户要访问网站的 Server Name,进而发送与之匹配的证书,顺利完成 SSL 握手。

Nginx 在很早之前就支持了 SNI,可以通过 nginx -V 来验证。以下是我的验证结果:

./nginx -V nginx version: nginx/1.9.9 built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) built with OpenSSL 1.0.2e-dev xx XXX xxxx TLS SNI support enabled configure arguments: --with-openssl=../openssl --with-http_ssl_module --with-http_v2_module

1
2
3
4
5
6
./nginx -V
nginx version: nginx/1.9.9
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
built with OpenSSL 1.0.2e-dev xx XXX xxxx
TLS SNI support enabled
configure arguments: --with-openssl=../openssl --with-http_ssl_module --with-http_v2_module

然而,并不是所有浏览器都支持 SNI,以下是常见浏览器支持 SNI 的最低版本:

浏览器 最低版本
Chrome Vista+ 全支持;XP 需要 Chrome 6+;OSX 10.5.7+ 且 Chrome 5+
Firefox 2.0+
Internet Explorer 7+ (需要 Vista+)
Safari 3+ (需要 OS X 10.5.6+)
Mobile Safari iOS 4.0+
Android Webview 3.0+

如果要避免在不支持 SNI 的浏览器中出现证书错误,只能将使用不同证书的 HTTPS 站点部署在不同 IP 上,最简单的做法是分开部署到不同机器上。

图片 2

SNI 扩展

我们知道,在 Nginx 中可以通过指定不同的 server_name 来配置多个站点。HTTP/1.1 协议请求头中的 Host 字段可以标识出当前请求属于哪个站点。但是对于 HTTPS 网站来说,要想发送 HTTP 数据,必须等待 SSL 握手完成,而在握手阶段服务端就必须提供网站证书。对于在同一个 IP 部署不同 HTTPS 站点,并且还使用了不同证书的情况下,服务端怎么知道该发送哪个证书?

Server Name Indication,简称为 SNI,是 TLS 的一个扩展,为解决这个问题应运而生。有了 SNI,服务端可以通过 Client Hello 中的 SNI 扩展拿到用户要访问网站的 Server Name,进而发送与之匹配的证书,顺利完成 SSL 握手。

Nginx 在很早之前就支持了 SNI,可以通过 nginx -V 来验证。以下是我的验证结果:

  1. ./nginx -V
  2. nginx version: nginx/1.9.9
  3. built by gcc4.8.4(Ubuntu4.8.4-2ubuntu1~14.04)
  4. built withOpenSSL1.0.2e-dev xx XXX xxxx
  5. TLS SNI support enabled
  6. configure arguments:--with-openssl=../openssl --with-http_ssl_module --with-http_v2_module

然而,并不是所有浏览器都支持 SNI,以下是常见浏览器支持 SNI 的最低版本:

浏览器 最低版本
Chrome Vista+ 全支持;XP 需要 Chrome 6+;OSX 10.5.7+ 且 Chrome 5+
Firefox 2.0+
Internet Explorer 7+ (需要 Vista+)
Safari 3+ (需要 OS X 10.5.6+)
Mobile Safari iOS 4.0+
Android Webview 3.0+

可以看到,现在还有一定用户量的 Windows XP IE6~8、Android 2.x Webview 都不支持 SNI。如果要避免在这些浏览器中出现证书错误,只能将使用不同证书的 HTTPS 站点部署在不同 IP 上,最简单的做法是分开部署到不同机器上。

 

申请 Let's Encrypt 证书时,一直无法验证通过

这类问题一般是因为 Let's Encrypt 无法访问你的服务器,推荐尝试 acme.sh 的 DNS 验证模式,一般都能解决。

证书选择

HTTPS 网站需要通过 CA 取得合法证书,证书通过数字签名技术确保第三方无法伪造。证书的简单原理如下:

  • 根据版本号、序列号、签名算法标识、发行者名称、有效期、证书主体名、证书主体公钥信息、发行商唯一标识、主体唯一标识、扩展生成 TBSCertificate(To Be Signed Certificate, 待签名证书)信息;
  • 签发数字签名:使用 HASH 函数对 TBSCertificate 计算得到消息摘要,用 CA 的私钥对消息摘要进行加密,得到签名;
  • 校验数字签名:使用相同的 HASH 函数对 TBSCertificate 计算得到消息摘要,与使用 CA 公钥解密签名得到内容相比较;

使用 SHA-1 做为 HASH 函数的证书被称之为 SHA-1 证书,由于目前已经找到 SHA-1 的碰撞条件,将证书换成使用更安全的 SHA-2 做为 HASH 函数的 SHA-2 证书被提上日程。

实际上,微软已经宣称自 2017 年 1 月 1 日起,将全面停止对 SHA-1 证书的支持。届时在最新版本的 Windows 系统中,SHA-1 证书将不被信任。

而根据 Chrome 官方博客的文章,使用 SHA-1 证书且证书有效期在 2016 年 1 月 1 号至 2016 年 12 月 31 号之间的站点会被给予「安全的,但存在漏洞」的提示,也就是地址栏的小锁不再是绿色的,并且会有一个黄色小三角。而使用 SHA-1 证书且证书有效期超过 2017 年 1 月 1 号的站点会被给予「不安全」的红色警告,小锁上直接显示一个红色的叉。

然而,并不是所有的终端都支持 SHA-2 证书,服务端不支持还好办,浏览器只能依赖于用户升级了。下面是常见浏览器支持 SHA-2 证书的最低版本:

浏览器 支持 SHA-2 证书的最低版本
Chrome 26+
Firefox 1.5+
Internet Explorer 6+ (需要 XP SP3+)
Safari 3+ (需要 OS X 10.5+)
Android Webview 2.3+

可以看到,如果要照顾没有打 XP SP3 补丁的 IE6 用户,只能继续使用 SHA-1 证书。

在我之前的文章中,还提到过 ECC 证书,这种新型的证书支持度更差,这里略过不提,有兴趣的同学可以点这里查看。

是否可以针对不同浏览器启用不同证书呢?理论上服务端可以根据客户端 Client Hello 中的 Cipher Suites 特征以及是否支持 SNI 的特征来分配不同证书,不过我没有实际验证过。

本文先写这么多,很多策略都需要根据自己网站的用户来决定,例如我的博客基本没有 IE8- 用户,理所当然可以禁用 SSLv3。如果你的产品还有很多使用老旧浏览器的用户,那就必须为这些用户做兼容方案了。一种方案是:只把主域安全级别配低,将 XP 上 IE 用户的 HTTPS 请求直接重定向到 HTTP 版本,这样其它域名可以使用高安全级别的配置,运维起来比较方便。

1 赞 1 收藏 评论

图片 3

 

证书选择

HTTPS 网站需要通过 CA 取得合法证书,证书通过数字签名技术确保第三方无法伪造。证书的简单原理如下:

  • 根据版本号、序列号、签名算法标识、发行者名称、有效期、证书主体名、证书主体公钥信息、发行商唯一标识、主体唯一标识、扩展生成 TBSCertificate( 待签名证书(To Be Signed Certificate))信息;
  • 签发数字签名:使用 HASH 函数对 TBSCertificate 计算得到消息摘要,用 CA 的私钥对消息摘要进行加密,得到签名;
  • 校验数字签名:使用相同的 HASH 函数对 TBSCertificate 计算得到消息摘要,与使用 CA 公钥解密签名得到内容相比较;

使��� SHA-1 做为 HASH 函数的证书被称之为 SHA-1 证书,由于目前已经找到 SHA-1 的碰撞条件,将证书换成使用更安全的 SHA-2 做为 HASH 函数的 SHA-2 证书被提上日程。

实际上,微软已经宣称自 2017 年 1 月 1 日起,将全面停止对 SHA-1 证书的支持。届时在最新版本的 Windows 系统中,SHA-1 证书将不被信任。

而根据 Chrome 官方博客的文章,使用 SHA-1 证书且证书有效期在 2016 年 1 月 1 号至 2016 年 12 月 31 号之间的站点会被给予「安全的,但存在漏洞」的提示,也就是地址栏的小锁不再是绿色的,并且会有一个黄色小三角。而使用 SHA-1 证书且证书有效期超过 2017 年 1 月 1 号的站点会被给予「不安全」的红色警告,小锁上直接显示一个红色的叉。

然而,并不是所有的终端都支持 SHA-2 证书,服务端不支持还好办,浏览器只能依赖于用户升级了。下面是常见浏览器支持 SHA-2 证书的最低版本:

浏览器 支持 SHA-2 证书的最低版本
Chrome 26+
Firefox 1.5+
Internet Explorer 6+ (需要 XP SP3+)
Safari 3+ (需要 OS X 10.5+)
Android Webview 2.3+

可以看到,如果要照顾没有打 XP SP3 补丁的 IE6 用户,只能继续使用 SHA-1 证书。

在我之前的文章中,还提到过 ECC 证书,这种新型的证书支持度更差,这里略过不提,有兴趣的同学可以点这里查看。

是否可以针对不同浏览器启用不同证书呢?理论上服务端可以根据客户端 Client Hello 中的 Cipher Suites 特征以及是否支持 SNI 的特征来分配不同证书,不过我没有实际验证过。

本文先写这么多,很多策略都需要根据自己网站的用户来决定,例如我的博客基本没有 IE8- 用户,理所当然可以禁用 SSLv3。如果你的产品还有很多使用老旧浏览器的用户,那就必须为这些用户做兼容方案了。一种方案是:只把主域安全级别配低,将 XP 上 IE 用户的 HTTPS 请求直接重定向到 HTTP 版本,这样其它域名可以使用高安全级别的配置,运维起来比较方便。

本文永久更新链接地址:

HTTPS 策略 几天前,一位朋友问我:都说推荐用Qualys SSL Labs这个工具测试 SSL 安全性,为什么有些安全实力很强的大...

网站无法访问,提示 ERR_CERTIFICATE_TRANSPARENCY_REQUIRED

使用 Chrome 53 访问使用 Symantec 证书的网站,很可能会出现这个错误提示。这个问题由 Chrome 的某个 Bug 引起,目前最好的解决方案是升级到 Chrome 最新版。相关链接:

  • Out of date Chrome results in ERR_CERTIFICATE_TRANSPARENCY_REQUIRED for Symantec operated sites;
  • Warning | Certificate Transparency error with Chrome 53;

SSL 版本选择

TLS(传输层安全(Transport Layer Security))的前身是 SSL(安全套接字层(Secure Sockets Layer)),它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。TLS 1.3 改动会比较大,目前还在草案阶段。

SSL 1.0 从未公开过,而 SSL 2.0 和 SSL 3.0 都存在安全问题,不推荐使用。Nginx 从 1.9.1 开始默认只支持 TLS 的三个版本,以下是 Nginx 官方文档中对 ssl_protocols 配置的说明:

Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
Default: ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Context: http, server
Enables the specified protocols. The TLSv1.1 and TLSv1.2 parameters work only when the OpenSSL library of version 1.0.1 or higher is used.

但不幸的是,IE 6 只支持 SSLv2 和 SSLv3(来源),也就是说 HTTPS 网站要支持 IE 6,就必须启用 SSLv3。仅这一项就会导致 SSL Labs 给出的评分降为 C。

 

浏览器提示证书有错误

加密套件选择

加密套件(CipherSuite),是在 SSL 握手中需要协商的很重要的一个参数。客户端会在 Client Hello 中带上它所支持的 CipherSuite 列表,服务端会从中选定一个并通过 Server Hello 返回。如果客户端支持的 CipherSuite 列表与服务端配置的 CipherSuite 列表没有交集,会导致无法完成协商,握手失败。

CipherSuite 包含多种技术,例如认证算法(Authentication)、加密算法(Encryption)、消息认证码算法(Message Authentication Code)(MAC)、密钥交换算法(Key Exchange)和密钥衍生算法(Key Derivation Function)。

SSL 的 CipherSuite 协商机制具有良好的扩展性,每个 CipherSuite 都需要在 IANA 注册,并被分配两个字节的标志。全部 CipherSuite 可以在 IANA 的 TLS Cipher Suite Registry 页面查看。

OpenSSL 库支持的全部 CipherSuite 可以通过以下命令查看:

  1. openssl ciphers -V | column -t
  2. 0xCC,0x14- ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2Kx=ECDH Au=ECDSA Enc=ChaCha20-Poly1305Mac=AEAD
  3. ......

0xCC,0x14 是 CipherSuite 的编号,在 SSL 握手中会用到。ECDHE-ECDSA-CHACHA20-POLY1305 是它的名称,之后几部分分别表示:用于 TLSv1.2,使用 ECDH 做密钥交换,使用 ECDSA 做认证,使用 ChaCha20-Poly1305 做对称加密,由于 ChaCha20-Poly1305 是一种 AEAD 模式,不需要 MAC 算法,所以 MAC 列显示为 AEAD。

要了解 CipherSuite 的更多内容,可以阅读这篇长文《TLS 协议分析 与 现代加密通信协议设计》。总之,在配置 CipherSuite 时,请务必参考权威文档,如:Mozilla 的推荐配置、CloudFlare 使用的配置。

以上 Mozilla 文档中的「Old backward compatibility」配置,以及 CloudFlare 的配置,都可以很好的兼容老旧浏览器,包括 Windows XP / IE6。

之前见到某个大厂家居然支持包含 EXPORT 的 CipherSuite,这些套件在上世纪由于美国出口限制而被弱化过,已被攻破,实在没有理由再使用。

 

检查证书链是否完整

首先确保网站使用的是合法 CA 签发的有效证书,其次检查 Web Server 配置中证书的完整性(一定要包含站点证书及所有中间证书)。如果缺失了中间证书,部分浏览器能够自动获取但严重影响 TLS 握手性能;部分浏览器直接报证书错误。

SNI 扩展

我们知道,在 Nginx 中可以通过指定不同的 server_name 来配置多个站点。HTTP/1.1 协议请求头中的 Host 字段可以标识出当前请求属于哪个站点。但是对于 HTTPS 网站来说,要想发送 HTTP 数据,必须等待 SSL 握手完成,而在握手阶段服务端就必须提供网站证书。对于在同一个 IP 部署不同 HTTPS 站点,并且还使用了不同证书的情况下,服务端怎么知道该发送哪个证书?

Server Name Indication,简称为 SNI,是 TLS 的一个扩展,为解决这个问题应运而生。有了 SNI,服务端可以通过 Client Hello 中的 SNI 扩展拿到用户要访问网站的 Server Name,进而发送与之匹配的证书,顺利完成 SSL 握手。

Nginx 在很早之前就支持了 SNI,可以通过 nginx -V 来验证。以下是我的验证结果:

  1. ./nginx -V
  2. nginx version: nginx/1.9.9
  3. built by gcc4.8.4(Ubuntu4.8.4-2ubuntu1~14.04)
  4. built withOpenSSL1.0.2e-dev xx XXX xxxx
  5. TLS SNI support enabled
  6. configure arguments:--with-openssl=../openssl --with-http_ssl_module --with-http_v2_module

然而,并不是所有浏览器都支持 SNI,以下是常见浏览器支持 SNI 的最低版本:

浏览器 最低版本
Chrome Vista+ 全支持;XP 需要 Chrome 6+;OSX 10.5.7+ 且 Chrome 5+
Firefox 2.0+
Internet Explorer 7+ (需要 Vista+)
Safari 3+ (需要 OS X 10.5.6+)
Mobile Safari iOS 4.0+
Android Webview 3.0+

可以看到,现在还有一定用户量的 Windows XP IE6~8、Android 2.x Webview 都不支持 SNI。如果要避免在这些浏览器中出现证书错误,只能将使用不同证书的 HTTPS 站点部署在不同 IP 上,最简单的做法是分开部署到不同机器上。

 

检查浏览器是否支持 SNI

如果只有老旧浏览器(例如 IE8 on Windows XP)提示这个错误,多半是因为你的服务器同时部署了使用不同证书的多个 HTTPS 站点,这样,不支持 SNI(Server Name Indication)的浏览器通常会获得错误的证书,从而无法访问。

要解决浏览器不支持 SNI 带来的问题,可以将使用不同证书的 HTTPS 站点部署在不同服务器上;还可以利用 SAN(Subject Alternative Name)机制将多个域名放入同一张证书;当然你也可以直接无视这些老旧浏览器。特别地,使用不支持 SNI 的浏览器访问商业 HTTPS CDN,基本都会因为证书错误而无法使用。

有关 SNI 的更多说明,请看「关于启用 HTTPS 的一些经验分享(二)」。

证书选择

HTTPS 网站需要通过 CA 取得合法证书,证书通过数字签名技术确保第三方无法伪造。证书的简单原理如下:

  • 根据版本号、序列号、签名算法标识、发行者名称、有效期、证书主体名、证书主体公钥信息、发行商唯一标识、主体唯一标识、扩展生成 TBSCertificate( 待签名证书(To Be Signed Certificate))信息;
  • 签发数字签名:使用 HASH 函数对 TBSCertificate 计算得到消息摘要,用 CA 的私钥对消息摘要进行加密,得到签名;
  • 校验数字签名:使用相同的 HASH 函数对 TBSCertificate 计算得到消息摘要,与使用 CA 公钥解密签名得到内容相比较;

使用 SHA-1 做为 HASH 函数的证书被称之为 SHA-1 证书,由于目前已经找到 SHA-1 的碰撞条件,将证书换成使用更安全的 SHA-2 做为 HASH 函数的 SHA-2 证书被提���日程。

实际上,微软已经宣称自 2017 年 1 月 1 日起,将全面停止对 SHA-1 证书的支持。届时在最新版本的 Windows 系统中,SHA-1 证书将不被信任。

而根据 Chrome 官方博客的文章,使用 SHA-1 证书且证书有效期在 2016 年 1 月 1 号至 2016 年 12 月 31 号之间的站点会被给予「安全的,但存在漏洞」的提示,也就是地址栏的小锁不再是绿色的,并且会有一个黄色小三角。而使用 SHA-1 证书且证书有效期超过 2017 年 1 月 1 号的站点会被给予「不安全」的红色警告,小锁上直接显示一个红色的叉。

然而,并不是所有的终端都支持 SHA-2 证书,服务端不支持还好办,浏览器只能依赖于用户升级了。下面是常见浏览器支持 SHA-2 证书的最低版本:

浏览器 支持 SHA-2 证书的最低版本
Chrome 26+
Firefox 1.5+
Internet Explorer 6+ (需要 XP SP3+)
Safari 3+ (需要 OS X 10.5+)
Android Webview 2.3+

可以看到,如果要照顾没有打 XP SP3 补丁的 IE6 用户,只能继续使用 SHA-1 证书。

在我之前的文章中,还提到过 ECC 证书,这种新型的证书支持度更差,这里略过不提,有兴趣的同学可以点这里查看。

是否可以针对不同浏览器启用不同证书呢?理论上服务端可以根据客户端 Client Hello 中的 Cipher Suites 特征以及是否支持 SNI 的特征来分配不同证书,不过我没有实际验证过。

本文先写这么多,很多策略都需要根据自己网站的用户来决定,例如我的博客基本没有 IE8- 用户,理所当然可以禁用 SSLv3。如果你的产品还有很多使用老旧浏览器的用户,那就必须为这些用户做兼容方案了。一种方案是:只把主域安全级别配低,将 XP 上 IE 用户的 HTTPS 请求直接重定向到 HTTP 版本,这样其它域名可以使用高安全级别的配置,运维起来比较方便。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-01/127503.htm

图片 4

检查系统时间

如果用户电脑时间不对,也会导致浏览器提示证书有问题,这时浏览器一般都会有明确的提示,例如 Chrome 的 ERR_CERT_DATE_INVALID。

启用 HTTP/2 后网站无法访问,提示 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY

这个问题一般是由于 CipherSuite 配置有误造成的。建议对照「Mozilla 的推荐配置、CloudFlare 使用的配置」等权威配置修改 Nginx 的ssl_ciphers 配置项。

有关这个问题的具体原因,请看「从启用 HTTP/2 导致网站无法访问说起」。

网站无法访问,提示 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 证书」。

在 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 后,网站部分资源不加载或提示不安全

记住一个原则:HTTPS 网站的所有外链资源(CSS、JS、图片、音频、字体文件、异步接口、表单 action 地址等等)都需要升级为 HTTPS,就不会遇到这个问题了。

详见「关于启用 HTTPS 的一些经验分享(三)」。

仅 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 文件大小是否正常,尤其要关注是否存在空文件。

需要注意的是,根据官方公告,从 2016 年 12 月 1 日开始,Google 的 Aviator CT log 服务将不再接受新的证书请求。用 ct-submit 等工具手动获取 SCT 文件时,不要再使用 Aviator 服务,否则就会得到空文件。

本文链接:,参与评论 »

--EOF--

发表于 2016-12-12 23:50:26,并被添加「Nginx、HTTPS、HTTP2」标签,最后修改于 2016-12-25 15:26:07。查看本文 Markdown 版本 »

本站使用「署名 4.0 国际」创作共享协议,相关说明 »

专题「Web 服务器」的其他文章 »

  • 开始使用 VeryNginx (Dec 10, 2016)
  • 开始使用 ECC 证书 (Aug 27, 2016)
  • 为什么我们应该尽快升级到 HTTPS? (May 16, 2016)
  • 本博客 Nginx 配置之完整篇 (Mar 21, 2016)
  • 从无法开启 OCSP Stapling 说起 (Mar 13, 2016)
  • Certificate Transparency 那些事 (Feb 03, 2016)
  • Let's Encrypt,免费好用的 HTTPS 证书 (Dec 25, 2015)
  • 从 Nginx 默认不压缩 HTTP/1.0 说起 (Dec 15, 2015)
  • TLS 握手优化详解 (Nov 08, 2015)
  • 使用 BoringSSL 优化 HTTPS 加密算法选择 (Oct 15, 2015)

本文由澳门金莎娱乐网站发布于澳门金莎娱乐网站,转载请注明出处:关于启用,常见部署问题及解决方案

关键词:

JSONP跨域的原理解析及其实现介绍,谈谈前后端的

谈谈前后端的分工协作 2015/05/15 · HTML5 · 1评论 ·Web开发 原文出处:小胡子哥的博客(@Barret李靖)    前后端分工协...

详细>>

JavaScript初学者需要了解10个小技巧,LeetCode解题思

字符串 20# Leetcode 378. Kth Smallest Element in a Sorted Matrix Product of Array Except Self 除本身之外的数组之积 Given an array of n int...

详细>>

从雅虎军规看前端性能优化,雅虎前端优化35条规

Web性能优化系列 – 通过提前获取DNS来提升网页加载速度 2015/04/23 · HTML5 ·DNS,性能优化 本文由 伯乐在线 -刘健超-J.c翻...

详细>>

图片防盗链,跨域访问和防盗链基本原理

跨域访谈和防盗链基本原理(一) 2015/10/18 · HTML5 ·跨域,防盗链 原稿出处: 童燕群(@童燕群)    1、使用调节台查...

详细>>