阿里云 CDN HTTPS 最佳实践——动态密钥套件

简介: 阿里云CDN HTTPS最佳实践系列文章,由CDN高防技术专家金九撰写

背景

在 ssllabs 中可以测试域名的 SSL 安全等级:

https3_1

影响这个测试等级的最主要因素就是密钥套件,在接入阿里云 CDN 的所有域名中,绝大多数域名评级都是 A,但是有少数域名为了兼容一些老浏览器或者客户端,需要支持比如 RC4 这样的加密算法,这样就导致评级为 B,但用户体验更重要,这就需要为这些对密钥套件有特殊需求的域名特殊配置密钥套件。

另外,当我们调试 https 时,比如抓包分析数据包时,发现应用数据都是加密的,无法分析 HTTP 协议的问题,但是如果我们有私钥,那就有办法可以通过 wireshark 来配置解密抓包信息。但是这个有个前提条件是密钥交换算法是 RSA,如果使用 ECDHE 即使有私钥也是无法解密抓包文件的,这就是所谓的 PFS(Perfect Forward Secrecy)。所以当我们想调试 HTTPS 里面的明文信息时,临时调整一下服务器的密钥套件列表中密钥交换算法仅包含 RSA 即可,调试完成之后再恢复成 PFS 密钥套件,这样就很方便的调试 HTTPS 了。

原理

密钥套件也称加密套件、密码套件,是 SSL 中最核心的算法套件,称之为套件是因为其中包含了密钥交换算法、签名算法、加密算法和摘要算法,由两个字节表示。以下是 TLS 密钥套件的语法:

https3_2

在 Client Hello 中有密钥套件列表,表示客户端所支持的密钥套件:

http3_3

服务端只能从 Client Hello 的密钥套件列表中选择一个做为本次会话的密钥套件:

https3_4

那服务端又是怎么选择这个密钥套件呢?这就涉及到密钥套件选择算法了,在 openssl 里面密钥套件的选择与几个因素有关:

  1. 服务端配置的密钥套件列表。
  2. 客户端支持的密钥套件列表。
  3. 服务端密钥套件列表优先还是客户端密钥套件列表优先。
  4. 已选择的 SSL 协议版本。
  5. 证书所支持的算法。

如果服务端密钥套件列表优先,则挨个从服务端配置的密钥套件列表中选择一个密钥套件是证书所支持的、已选择的 SSL 协议版本所支持的,并且在客户端密钥套件列表的密钥套件,如果是客户端密钥套件列表优化也是类似,一般都是配置服务端密钥套件优先。

其中最关键的就是服务端配置的密钥套件列表,下面先来看看 openssl 中密钥套件的表达方式:

openssl ciphers 'ALL' -V

https3_6

上面的协议版本就是该密钥套件支持的协议最低版本,比如 ECDHE-RSA-AES128-GCM-SHA256 的协议版本是 TLSv1.2,那如果握手时选择了 TLSv1.1、TLSv1.0、SSLv3 这些版本则不能使用该密钥套件。

    密钥套件之间用4个分隔符之一分开——冒号、分号、逗号或者空格,一般使用冒号。如下密钥套件列表中包含了所有特殊字符:

EECDH+AESGCM:+EECDH+AES256:ALL:-RSA+3DES:!DH:!PSK:!KRB5:!MD5:!RC4:!aNULL:!EXP:!LOW:!SSLV2:!NULL

其说明如下:

EECDH+AESGCM:同时包含EECDH和AESGCM算法的密钥套件,+号相当于『与』操作。  
密钥套件前面+号:将该算法移到算法列表的末尾。这个选项不会添加任何新的算法,它只是紧紧的移动匹配的已经存在的算法。  
密钥套件前面-号:从算法列表中删除该算法。但是可以通过后面的选项将一个或所有的算法可以被再次添加。  
密钥套件前面!号:从算法列表中删除该算法。删除了的算法将不会再出现。

通过 openssl ciphers 指令列出来的顺序就是服务端的密钥套件列表顺序:

$openssl ciphers 'EECDH+AESGCM:+EECDH+AES256:ALL:-RSA+3DES:!DH:!PSK:!KRB5:!MD5:!RC4:!aNULL:!EXP:!LOW:!SSLV2:!NULL' -V
          0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
          0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
          0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
          0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
          0xC0,0x28 - ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
          0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
          0xC0,0x14 - ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
          0xC0,0x0A - ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
          0xC0,0x32 - ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
          0xC0,0x2E - ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
          0xC0,0x2A - ECDH-RSA-AES256-SHA384  TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA384
          0xC0,0x26 - ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA384
          0xC0,0x0F - ECDH-RSA-AES256-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA1
          0xC0,0x05 - ECDH-ECDSA-AES256-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA1
          0x00,0x9D - AES256-GCM-SHA384       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(256) Mac=AEAD
          0x00,0x3D - AES256-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA256
          0x00,0x35 - AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
          0x00,0x84 - CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
          0xC0,0x27 - ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
          0xC0,0x23 - ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256
          0xC0,0x13 - ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
          0xC0,0x09 - ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
          0xC0,0x12 - ECDHE-RSA-DES-CBC3-SHA  SSLv3 Kx=ECDH     Au=RSA  Enc=3DES(168) Mac=SHA1
          0xC0,0x08 - ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH     Au=ECDSA Enc=3DES(168) Mac=SHA1
          0xC0,0x31 - ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
          0xC0,0x2D - ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
          0xC0,0x29 - ECDH-RSA-AES128-SHA256  TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128)  Mac=SHA256
          0xC0,0x25 - ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128)  Mac=SHA256
          0xC0,0x0E - ECDH-RSA-AES128-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128)  Mac=SHA1
          0xC0,0x04 - ECDH-ECDSA-AES128-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128)  Mac=SHA1
          0xC0,0x0D - ECDH-RSA-DES-CBC3-SHA   SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1
          0xC0,0x03 - ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1
          0x00,0x9C - AES128-GCM-SHA256       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(128) Mac=AEAD
          0x00,0x3C - AES128-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA256
          0x00,0x2F - AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
          0x00,0x96 - SEED-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=SEED(128) Mac=SHA1
          0x00,0x41 - CAMELLIA128-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(128) Mac=SHA1
          0x00,0x07 - IDEA-CBC-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=IDEA(128) Mac=SHA1

实现

在 Tengine 中有两个指令跟密钥套件有关:

ssl_ciphers                  EECDH+AESGCM:+EECDH+AES256:ALL:-RSA+3DES:!DH:!PSK:!KRB5:!MD5:!RC4:!aNULL:!EXP:!LOW:!SSLV2:!NULL;
ssl_prefer_server_ciphers    on;

其中,ssl_ciphers 是配置服务器支持的密钥套件列表,ssl_prefer_server_ciphers 为 on 则指定从服务器支持的密钥套件列表中的优先顺序来选择密钥套件,为 off 则表示从客户端支持的密钥套件列表中的优先顺序来选择密钥套件。

ssl_prefer_server_ciphers 配置为 on 是必须的,因为如果不设置为 on,那意味着优先从客户端支持的密钥套件列表中选择加密套件,这样的话可能导致 SSL 的性能比较低,而且可能导致被攻击。

另外,我们知道 ssl_ciphers 指令是静态配置,想要修改服务器支持的密钥套件列表的话,必须 reload Tengine,对于单台服务器或者少量服务器这么操作是可以的,但是对于阿里云 CDN 上万台机器的集群来 reload Tengine 的话,这么做就不现实了,所以我们也实现了 ssl 密钥套件列表的动态配置。

如下图,可以在阿里云 CDN 管理后台管理系统上根据域名来调整密钥套件。(由于密钥套件的修改是比较底层的配置,非专业人员配置容易出问题,所以没有开放到 CDN 用户控制台。)
https3_7

目录
相关文章
|
2月前
|
缓存 前端开发 JavaScript
适合阿里云CDN分发的文件类型有哪些?
静态文件如网页、图片、视频等适合CDN分发,可提升加载速度,减轻源站压力。动态、私有或频繁变更内容则不适合。合理选择资源包,助力高效上云。
|
2月前
|
域名解析 缓存 监控
阿里云渠道商:如何排查阿里云CDN访问问题?
排查阿里云CDN访问问题需分步诊断:先检查DNS解析与CDN基础配置,再根据访问慢、内容未更新或50x错误等现象定位原因,结合ping、tracert及阿里云实时日志、节点检测等工具深度分析。掌握此流程,快速解决异常。
|
2月前
|
边缘计算 缓存 双11
阿里云渠道商:什么时候应该使用阿里云 CDN 预热?
阿里云CDN预热可将资源提前分发至边缘节点,降低首字节时间50%以上,减轻源站压力。适用于大促活动、大文件发布、定期更新、突发流量及APP资源更新等场景,提升访问速度与稳定性。首次访问求快用预热,内容更新生效用刷新。
|
2月前
|
缓存 安全 网络安全
阿里云渠道商:怎么通过阿里云CDN提高全球用户的访问体验?
阿里云CDN通过全球2800+节点、智能调度、性能优化与安全防护三大技术,实现低延迟、高稳定的内容分发,助力企业提升全球访问体验,让业务如本地般流畅。
|
2月前
|
Web App开发 缓存 监控
阿里云渠道商:如何优化阿里云 CDN 配额的使用效率?
CDN可提升网站速度,但30%企业因配置不当致带宽超支。本文分享阿里云验证的三大优化方案:精细化缓存、智能压缩与数据驱动配额调配,最高节省40%带宽成本。附实操步骤,助你高效降本。
|
2月前
|
缓存 边缘计算 双11
阿里云渠道商:适合使用CDN 预热的场景有哪些?
本文介绍CDN预热功能在大型活动、大文件分发、周期性更新等场景中的应用。通过提前将资源推送至边缘节点,可显著降低首字节时间、减轻源站压力,提升访问效率与系统稳定性。
|
2月前
|
缓存 安全 调度
阿里云渠道商:如何使用CDN加速全球业务?
阿里云CDN通过全球2800+节点,将内容分发至用户附近,实现“本地化”访问,显著降低延迟。支持智能压缩、动态缓存与HTTPS加密,兼具加速、优化与安全,助力企业高效出海,提升全球用户体验。
|
7月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
212 18
|
7月前
|
网络安全 开发者
如何解决HTTPS协议在WordPress升级后对网站不兼容的问题
以上就是解决WordPress升级后HTTPS协议对网站的不兼容问题的方法。希望能把这个棘手的问题看成是学校的管理问题一样来应对,将复杂的技术问题变得更加有趣和形象,并寻觅出解决问题的方式。希望你的网站能在新的学期得到更好的发展!
212 19
|
7月前
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
711 20