阿里云 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

目录
相关文章
|
安全 CDN
阿里云CDN产品解读及全站加速在游戏行业的最佳实践!
阿里云CDN(内容分发网络)为全球用户提供快速、稳定、安全的内容分发加速服务,显著提升访问响应速度和成功率
319 13
|
SQL DataWorks Java
DataWorks操作报错合集之在阿里云 DataWorks 中,代码在开发测试阶段能够成功运行,但在提交后失败并报错“不支持https”如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
352 1
DataWorks操作报错合集之在阿里云 DataWorks 中,代码在开发测试阶段能够成功运行,但在提交后失败并报错“不支持https”如何解决
|
网络协议 安全 应用服务中间件
阿里云 网站https设置 sll申请与nginx跳转配置
阿里云 网站https设置 sll申请与nginx跳转配置
500 1
阿里云提供https://www.fcomcn.com备案耐心指导。
到现在备案已经有八个网站了,现在是https://www.fcomcn.com 在三天前提交了备案,初审速度阿里云还是很快的,商标是人民井茶,可能是名字有带人民就不能通过,所以备案了外星人。在这里谢谢阿里云工作人员。
229 4
阿里云提供https://www.fcomcn.com备案耐心指导。
|
域名解析 网络协议 应用服务中间件
阿里云服务器配置免费https服务
阿里云服务器配置免费https服务
|
域名解析 网络协议 应用服务中间件
阿里云SSL证书配置(HTTPS证书配置)
该内容是一个关于如何在阿里云上准备和购买SSL证书,以及如何为网站启用HTTPS的步骤指南。首先,需要注册并实名认证阿里云账号,然后在SSL证书控制台选择证书类型、品牌和时长进行购买。申请证书时填写域名信息,并进行DNS验证,这包括在阿里云域名管理板块添加解析记录。完成验证后提交审核,等待证书审核通过并下载Nginx格式的证书文件。最后,将证书配置到网站服务器以启用HTTPS。整个过程涉及账户注册、实名认证、证书购买、DNS设置和证书下载及安装。
9488 1
|
安全 网络安全 CDN
阿里云CDN HTTPS 证书配置流程
阿里云CDN HTTPS 证书配置流程
1993 1
阿里云十分钟初审https://www.fcomcn.com
https://www.fcomcn.com 但是到现在十天了
289 0
|
弹性计算 负载均衡 安全
一文带你搞懂阿里云上HTTPS配置
目前绝大多数网站都已经实现了HTTPS,不过云上HTTPS的SSL证书在哪配、怎么配是一个值得讨论的问题,在大型企业复杂的部署架构下,一个Web应用访问路径可能经过CDN->WAF->SLB->NGINX等多层,下面就带大家了解云上服务如何启用HTTPS。
3128 0
一文带你搞懂阿里云上HTTPS配置
|
6月前
|
缓存 前端开发 JavaScript
适合阿里云CDN分发的文件类型有哪些?
静态文件如网页、图片、视频等适合CDN分发,可提升加载速度,减轻源站压力。动态、私有或频繁变更内容则不适合。合理选择资源包,助力高效上云。