更多时候,我们会使用到 HTTPS。对于服务器端的 HTTPS 配置,需要配置密钥证书、加密算法套件、TLS 版本等信息。一直疑惑如何选择加密算法套件和 TLS 版本是如何选择和搭配的,工作中也遇到过因为 TLS 版本和加密套件选择有误带来的种种麻烦。今天抽了点时间,以最常见的服务器中间件组件 NGINX 为例,整理了协议常用的 HTTPS 配置,供大家参考使用。

SSL/TLS

截止到目前,SSL/TLS 共推出过 6 个版本,SSL2/SSL3/TLS1.0/TLS1.1/TLS1.2/TLS1.3,其中 TLS1.3 是目前最新版本,SSL2 和 SSL3 由于存在过多的漏洞,现在已经被弃用了,在一些安全扫描中,会强制要求使用 TLS1.2 以上的版本。

CipherSuite

在 NGINX 中,OpenSSL 负责处理 HTTPS 连接,提供 SSL/TLS 加密,确保数据在互联网上传输时的安全性。所以 NGINX 支持哪些加密算法套件是由 NGINX 所使用的 OpenSSL 来决定的。

20240928233458

我们可以通过命令 openssl ciphers -V | column -t 查看支持的加密算法套件以及该加密套件对应的 TLS 版本等信息。

20240928233719

加密算法一直在加密和破解中不断对抗和博弈,一些旧的算法被破解,渐渐淡出历史舞台。例如著名的 CVE-2016-2183,可以说是在漏扫中非常常见的一个漏洞了。

TLS, SSH, IPSec协商及其他产品中使用的DES及Triple DES密码或者3DES及Triple 3DES存在大约四十亿块的生日界,这可使远程攻击者通过Sweet32攻击,获取纯文本数据。
– 摘自某漏扫报告中关于 CVE-2016-2183 的描述。

常用配置组合

Cloudflare 推荐配置

这部分是 Cloudflare 推荐的 SSL 配置组合。

  • 加密算法套件:[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES
  • TLS 版本:TLSv1 TLSv1.1 TLSv1.2 TLSv1.3

Mozilla 推荐配置

Mozilla 给出了三种推荐的配置,现代兼容性配置、推荐配置、旧版兼容性配置。详细可参考 Mozilla 服务器端 TLS 配置。推荐看看 Mozilla 的这个文档,写的还是蛮详细的。

  • 现代兼容性配置
    • 支持 TLS1.3 的新式客户端,安全性最佳,但兼容性稍差。
    • 加密算法套件:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    • TLS 版本:TLSv1.3
  • 推荐配置
    • 通用服务器推荐配置,安全性和兼容性均衡的配置。
    • 加密算法套件:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
    • TLS 版本:TLSv1.2 TLSv1.3
  • 旧版兼容性配置
    • 针对非常旧的客户端或库,用安全性换兼容性。
    • 加密算法套件:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
    • TLS 版本:TLSv1 TLSv1.1 TLSv1.2 TLSv1.3

Cipherli

cipherli.st 早在 2020 年就已经被停服了,目前有一个 Mark 版本的网站是由官方认可的,还在提供推荐的 TLS/SSL 配置。populair 服务的推荐 TLS/SSL 配置

  • 加密算法套件:EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM
  • TLS 版本:TLSv1.2 TLSv1.3

NGINX 官方配置

根据 NGINX 官方文档所述,ssl_ciphers 和 ssl_protocols 是存在 Default 配置的,也就是说,我们不在配置文件中显式的声明相关配置,会使用 NGINX 自带的默认配置。对于不同版本的 NGINX,默认配置有所不同,可参考配置 HTTPS 服务器-兼容性说明

1.23.4 及更高版本:默认 SSL/TLS 协议为 TLSv1, TLSv1.1、TLSv1.2 和 TLSv1.3(如果 OpenSSL 库支持)。
1.9.1 及更高版本:默认 SSL/TLS 协议为 TLSv1, TLSv1.1 和 TLSv1.2(如果 OpenSSL 库支持)。
0.7.65、0.8.19 及更高版本:默认 SSL/TLS 协议为 SSLv3、TLSv1、 TLSv1.1 和 TLSv1.2(如果 OpenSSL 库支持)。
0.7.64、0.8.18 及更早版本:默认 SSL/TLS 协议为 SSLv2、 SSLv3 和 TLSv1。
1.0.5 及更高版本:默认加密算法套件为 HIGH:!aNULL:!MD5
0.7.65、0.8.20 及更高版本:默认加密算法套件为 HIGH:!ADH:!MD5
0.8.19:默认加密算法套件为 ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM
0.7.64、0.8.18 及更早版本:默认加密算法套件为ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

从实际操作上看,一般都会显式声明服务器所支持的加密算法套件和 TLS 版本,使得服务器配置更加灵活且安全。

简单理解 NGINX 的 ssl_ciphers

我们关注到 NGINX 文档中,对于 ssl_ciphers 的描述是:

Specifies the enabled ciphers. The ciphers are specified in the format understood by the OpenSSL library, for example:
ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
The full list can be viewed using the “openssl ciphers” command.

在上述描述中,ssl_ciphers 的值是 OpenSSL 所支持的加密算法的组合,以[] 或 | 或 : 分隔,还包含了 ! 或 - 或 + 几种运算。

  1. !运算表示从算法列表中删除该算法。根据明确的规定,删除了的算法将不会再出现。
  2. -运算表示从算法列表中删除该算法。但是可以通过后面的选项将一个或所有的算法可以被再次添加。
  3. +预算表示将该算法移到算法列表的末尾。这个选项不会添加任何新的算法,它只是紧紧的移动匹配的已经存在的算法。

还有几种特殊的表示法,也很常用。

  1. ALL:除去 eNULL 以外的所有支持的加密算法。一般认为 ALL 是默认支持的加密算法。
  2. HIGH:高强度加密密码套件。目前,这意味着大于128位的密钥长度以及一些带有128位钥匙的密码套件。
  3. MEDIUM:中等强度加密密码套件,目前有一些使用128位加密的密码。
  4. LOW:低强度加密密码套件,目前使用64或56位加密算法,但不包括导出密码套件。从OpenSSL 1.0.2g开始,这些在默认版本中被禁用。
  5. AES:AES 加密算法。
  6. 3DES:3DES 加密算法。
  7. EXPORT56:56位导出加密算法。

关于这部分详细的说明,可以参考OpenSSL cipher-strings,里面说的很明确。

我们也可以通过命令,来查询 NGINX 所配置的 ciphers 都支持哪些加密算法套件。

例如,openssl ciphers -v 'ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'

20240929005317

常用工具