CDN SSL/TLS 配置最佳实践:保障传输安全与性能

CDN 承载 HTTPS 流量时,SSL/TLS 配置直接决定两件事:数据在边缘节点和用户之间安不安全,以及握手环节要花几个网络往返。这两件事经常被当成"要么选安全、要么选快"的单选题,但实际上,一份优化的 TLS 配置可以同时把两者做好——关键是证书、协议版本、密码套件、会话复用这几块分别下功夫。

一、证书选择与部署

1.1 证书类型怎么选

证书类型 适用场景 验证级别 成本
DV(域名验证) 个人/小型网站 免费-低
OV(组织验证) 企业网站
EV(扩展验证) 金融/电商
通配符证书 多子域名 按级别 中-高

对绝大多数内容型网站,DV 证书足够。地址栏的小锁和"浏览器报不安全"的差距,DV 和 EV 都能解决;OV/EV 多的主要是企业信息展示,对转化率的影响其实很小。值得一提的是,浏览器厂商这两年陆续移除了地址栏对 EV 的绿色标识展示,EV 的"信任背书"价值进一步缩水,选型时可以更放心地先上 DV。

1.2 CDN 上的证书管理

优先用自动管理,省心且不会过期翻车:

Cloudflare: 自动 SSL
AWS CloudFront: ACM 自动续期
Azure: App Service 托管证书
阿里云: 免费 DV 证书

手动上传的话,注意把中间证书链一起上传,只传叶子证书会一路"证书链不完整",部分老客户端直接拒绝连接。

1. 在 CA 购买或生成证书
2. 上传到 CDN 控制台
3. 配置证书链(完整链)
4. 设置自动续期提醒

1.3 Let's Encrypt 集成

大部分 CDN 支持 Let's Encrypt 自动签发:

  • Cloudflare:内置免费证书,自动续期
  • Bunny CDN:自动 Let's Encrypt
  • AWS:需 ACM 导入

参考:Let's Encrypt 文档 https://letsencrypt.org/docs/;Cloudflare SSL 指南 https://developers.cloudflare.com/ssl/

二、TLS 协议版本配置

协议 安全性 性能 推荐
TLS 1.3 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ✓ 启用
TLS 1.2 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ✓ 启用
TLS 1.1 ⭐⭐⭐ ⭐⭐⭐ ✗ 禁用
TLS 1.0 ⭐⭐ ⭐⭐ ✗ 禁用
SSL 3.0 ✗ 禁用

TLS 1.3 最大的变化在握手:从 1-RTT 缩到 0-RTT(配合会话恢复),省掉 1-2 个往返。对移动网络这种高延迟场景,一个往返可能就是 50-100ms 的体感差异。

Cloudflare: SSL/TLS → Edge Certificates → Minimum TLS Version: 1.2
CloudFront: Security Policy → TLSv1.2_2021
Nginx + CDN: ssl_protocols TLSv1.2 TLSv1.3;

配置上从"允许 TLS 1.0"升到"最低 1.2",同时保留 1.3,是当前兼容性和安全性的平衡点。除非目标用户群里有极老的浏览器(如 Windows XP 时代的 IE),否则没有理由再开 1.0/1.1。

一个常被忽略的细节是 TLS 1.3 的 0-RTT:它省握手的同时也带来重放风险,对下单、支付这类需要幂等性的接口,建议关掉或只在 GET 上启用,别让一个被截获的请求被重复执行。

三、密码套件配置

TLS 1.3 的密码套件是强制的,不用配;要花心思的是 TLS 1.2 部分,别用默认顺序:

# TLS 1.3 密码套件(无需配置)
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256

# TLS 1.2 密码套件(推荐)
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305

一律优先 ECDHE(前向保密)+ GCM/ChaCha20。像 RSA 静态密钥、CBC、RC4、3DES 这些要么不支持前向保密,要么有已知攻击,直接禁用:

TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
所有 RC4、3DES、CBC 模式

参考:Mozilla SSL 配置生成器 https://ssl-config.mozilla.org/;IETF TLS 1.3 RFC 8446 https://datatracker.ietf.org/doc/html/rfc8446

四、性能优化

4.1 OCSP Stapling

默认情况下,客户端拿到证书后还要自己去 CA 查一次吊销状态(OCSP),多一次请求。OCSP Stapling 让 CDN 代查并把结果"钉"在握手响应里,客户端直接省掉这一步:

# Nginx 配置
ssl_stapling on;
ssl_stapling_verify on;

4.2 会话复用

同一个用户频繁建连(比如页面里有几十个资源请求)时,会话复用能把后续握手从完整握手降级为 1-RTT 甚至 0-RTT:

# Nginx 配置
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets on;

4.3 HSTS

HSTS 告诉浏览器"以后只能走 HTTPS",从根上杜绝中间人降级攻击,顺带省掉 301 跳转那一次往返:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

参考:MDN HSTS https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security

五、各 CDN 配置参考

CDN 证书管理 最低 TLS HSTS 支持 OCSP
Cloudflare 免费自动 可配置
CloudFront ACM 免费 可配置
Fastly 需上传 可配置
阿里云 CDN 免费/上传 可配置
Bunny CDN Let's Encrypt TLS 1.2+

六、一个排查案例

某站点上线后 Chrome 用户秒开,但一部分老 Android WebView 用户报"连接不安全"。查日志发现这些客户端还停留在 TLS 1.0/1.1,密码套件也只认 CBC。把 CDN 最低 TLS 设为 1.2 后,这批用户全部无法访问——问题不是配置错了,而是目标用户群里确实还有老客户端。这类问题最好的预防方式是在上线前用 https://www.ssllabs.com/ 全量扫一遍,看客户端兼容矩阵里有没有你不想服务的版本。最后方案:全局最低 1.2,单独为老客户端保留一个 1.1 的源站域名白名单,过渡半年后再收紧。

16IDC 建议

  1. 先在测试域名上改配置,用 SSL Labs 免费测一遍再上生产。
  2. HSTS preload 一旦提交就"回不了头",先跑几个月 max-age=31536000(不带 preload)观察再说。
  3. 证书快过期时,CDN 控制台通常有告警;把续期提醒同时发到邮箱和 Slack,双保险。
  4. 用 sslscan 或 cipherscan 定期检查线上证书与套件,配合 CDN 的版本升级计划一起做,别等出了漏洞才想起来。