NGINX 配置 HTTPS 最佳实践
1202 年了,不会还有网站不支持 HTTPS 吧?不过 HTTPS 的配置还是有很多讲究的。本文以 NGINX 的配置为例,嫌麻烦的可以直接跳到 最后 抄配置。
如果你不清楚 HTTPS 与 TLS 的工作原理,可以先阅读 这篇文章,可以帮助你理解下述配置。
获取证书
证书是实现 HTTPS 的基础,现在各个云服务商都提供了免费的证书申请,可以直接去申请。这里我以 acme.sh 为例说明下申请证书时的注意事项。
1
acme.sh --issue -d "*.zinglix.xyz" --keylength ec-256 --ocsp
上面是一个简单的用 acme 申请证书的命令,其中关键的是 keylength 和 ocsp 两个参数,OCSP 的作用我们 后面 再说,建议能开启则开启,先来谈谈密钥长度的问题。
证书加密的算法分为 RSA 和 ECDSA 两类,这对应到证书也就分为两类。acme 中 keylength 支持的参数有 2048, 3072, 4096, 8192 和 ec-256, ec-384, ec-521(参数支持,但暂不支持申请)。
ec- 开头的对应着 ECDSA 证书,其他的为 RSA 证书,长度越长安全性也就更高,但对性能的消耗也就越高。RSA 有更好的兼容性,ECDSA 可以提供更好的前向安全,具体差异可以看 这里。
根据 SSL Labs 的推荐,长于 2048 的 RSA 密钥和 256 bits 的 ECDSA 密钥对于 CPU 性能是一种浪费,从中获得安全性的提升有限,导致过度加密。
因此推荐密钥长度为 2048 与 ec-256!
那么两种类型证书选择哪一个呢?那当然是全都要啦~ NGINX 支持同时使用两个证书,只需要都写上就行了
1
2
3
4
5
6
# RSA 证书
ssl_certificate /cert/*.zinglix.xyz/fullchain.cer;
ssl_certificate_key /cert/*.zinglix.xyz/*.zinglix.xyz.key;
# ECDSA 证书
ssl_certificate /cert/*.zinglix.xyz_ecc/fullchain.cer;
ssl_certificate_key /cert/*.zinglix.xyz_ecc/*.zinglix.xyz.key;
这里 ssl_certificate 最好是使用完整的证书链,如果没有提供必要的中间证书可能会导致证书链不可信。
HTTP/2 与会话恢复
HTTP/2 可以有效提升对网络的利用效率,会话恢复可以复用曾经协商过的数据,两者都可以帮助减少 RTT,所以建议开启,可以有效减少建立连接时的耗时。
1
2
3
4
5
listen 443 ssl http2;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
加密协议与套件
SSL 已经是不安全的了,绝不要使用。TLSv1.0 与 TLSv1.1 虽然没有被证明不安全,但作为老旧的协议即将过时,除非你的客户真的需要,也不要开启。
TLSv1.2 可以说是目前被最广泛使用的协议,应当被开启。TLSv1.3 作为最新的协议,在性能和安全性上都有提升,支持的话也应当开启。
如果为了极致的安全,只开启 TLSv1.3 也是没有问题的,现代的浏览器都已经支持 TLSv1.3,只要你相信你的客户不会使用略微老旧的软件
至于加密套件,RC4、DES 等等都不安全,但说那么多套件头也晕了,下面已经整理了一份支持绝大多数客户端且安全的配置
1
2
3
4
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 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;
ssl_prefer_server_ciphers on;
ssl_prefer_server_ciphers 用于指定服务器是否有推荐的套件,为了能够根据服务器配置用上更安全的套件,防止 BEAST 攻击,建议开启。
HSTS
HSTS (HTTP Strict Transport Security) 能够告诉浏览器,该网站只应该通过 HTTPS 访问,避免使用 HTTP。开启方式如下,只需要添加一个 HTTP 头
1
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
其中三个参数
max-age=<expire-time>:指明 HSTS 的有效期,最佳实践是一年时间即31536000。注意,开启后如果关闭...
剩余内容已隐藏