基于 Nginx 的 HTTPS 性能优化实践


本文转载自「云栖社区」,做者:妙正灰html

前言nginx

分享一个HTTPS优化案例。随着相关浏览器对HTTP协议的“不安全”、红色页面警告等严格措施的出台,以及向 iOS 应用的 ATS 要求和微信、支付宝小程序强制 HTTPS 需求,以及在合规方面如等级保护对传输安全性的要求都在推进 HTTPS 的发展。git

虽然 HTTPS 优化了网站访问体验(防劫持)以及让传输更加安全,可是不少网站主赶鸭子上架式的使用了 HTTPS 后每每都会遇到诸如:页面加载速度变慢、服务器负载太高以及证书过时不及时更新等问题。github

因此本文就来探讨一下 HTTPS 的优化实践。算法

选型ubuntu

其实像 Apache Httpd、LigHttpd、Canddy 等 Web 服务软件均可以设置 HTTPS,可是在相应的扩展生态和更新率上都不如 Nginx。 Nginx 做为大型互联网网站的 Web 入口软件有着普遍的支持率,例如阿里系的 Tengine、CloudFlare 的 cloudflare-nginx、又拍云用的 OpenResty 都是基于 Nginx 而来的,Nginx 是接受过大规模访问验证的。同时你们也将本身开发的组件回馈给 Nginx 社区,让 Nginx 有着很是良好的扩展生态。小程序

图1-1 Nginx 在全网的使用状况 浏览器

因此说 Nginx 是一款很好的 Web 服务软件,选择 Nginx 在提高性能的同时能极大的下降咱们的扩展成本。安全

新功能服务器

围绕 Web 服务已经有很是多的新功能须要咱们关注并应用了,这里先罗列相关新功能。

HTTP/2

相比廉颇老矣的 HTTP/1.x,HTTP/2 在底层传输作了很大的改动和优化包括有:

  1. 每一个服务器只用一个链接,节省屡次创建链接的时间,在TLS上效果尤其明显
  2. 加速 TLS 交付,HTTP/2 只耗时一次 TLS 握手,经过一个链接上的多路利用实现最佳性能
  3. 更安全,经过减小 TLS 的性能损失,让更多应用使用 TLS,从而让用户信息更安全

在 Akamai 的 HTTP/2 DEMO中,加载300张图片,HTTP/2 的优越性极大的显现了出来,在 HTTP/1.X 须要 14.8s 的操做中,HTTP/2 仅需不到1s。

HTTP/2 如今已经得到了绝大多数的现代浏览器的支持。只要咱们保证 Nginx 版本大于 1.9.5 便可。固然建议保持最新的 Nginx 稳定版本以便更新相关补丁。同时 HTTP/2 在现代浏览器的支持上还须要 OpenSSL 版本大于 1.0.2。

TLS 1.3

和 HTTP/1.x 同样,目前受到主流支持的 TLS 协议版本是 1.1 和 1.2,分别发布于 2006年和2008年,也都已经落后于时代的需求了。在2018年8月份,IETF终于宣布TLS 1.3规范正式发布了,标准规范(Standards Track)定义在 rfc8446。

TLS 1.3 相较以前版本的优化内容有:

  1. 握手时间:同等状况下,TLSv1.3 比 TLSv1.2 少一个 RTT
  2. 应用数据:在会话复用场景下,支持 0-RTT 发送应用数据
  3. 握手消息:从 ServerHello 以后都是密文。
  4. 会话复用机制:弃用了 Session ID 方式的会话复用,采用 PSK 机制的会话复用。
  5. 密钥算法:TLSv1.3 只支持 PFS (即彻底前向安全)的密钥交换算法,禁用 RSA 这种密钥交换算法。对称密钥算法只采用 AEAD 类型的加密算法,禁用CBC 模式的 AES、RC4 算法。
  6. 密钥导出算法:TLSv1.3 使用新设计的叫作 HKDF 的算法,而 TLSv1.2 是使用PRF算法,稍后咱们再来看看这两种算法的差异。

总结一下就是在更安全的基础上还作到了更快,目前 TLS 1.3 的重要实现是 OpenSSL 1.1.1 开始支持了,而且 1.1.1 仍是一个 LTS 版本,将来的 RHEL八、Debian10  都将其做为主要支持版本。在 Nginx 上的实现须要 Nginx  1.13+。

Brotli

Brotli 是由 Google 于 2015 年 9 月推出的无损压缩算法,它经过用变种的 LZ77 算法,Huffman 编码和二阶文本建模进行数据压缩,是一种压缩比很高的压缩方法。

根据Google 发布的研究报告,Brotli 具备以下特色:

  1. 针对常见的 Web 资源内容,Brotli 的性能要比 Gzip 好 17-25%;
  2. Brotli 压缩级别为 1 时,压缩速度是最快的,并且此时压缩率比 gzip 压缩等级为 9(最高)时还要高;
  3. 在处理不一样 HTML 文档时,brotli 依然提供了很是高的压缩率;

在兼容 GZIP 的同时,相较 GZIP:

  1. JavaScript 上缩小 14%
  2. HTML上缩小 21%
  3. CSS上缩小 17%

Brotli 的支持必须依赖 HTTPS,不过换句话说就是只有在 HTTPS 下才能实现 Brotli。

ECC 证书

椭圆曲线密码学(Elliptic curve cryptography,缩写为ECC),一种创建公开金钥加密的算法,基于椭圆曲线数学。椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。

内置 ECDSA 公钥的证书通常被称之为 ECC 证书,内置 RSA 公钥的证书就是 RSA 证书。因为 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,加上 ECC 运算速度更快,ECDHE 密钥交换 + ECDSA 数字签名无疑是最好的选择。因为同等安全条件下,ECC 算法所需的 Key 更短,因此 ECC 证书文件体积比 RSA 证书要小一些。

ECC 证书不只仅能够用于 HTTPS 场景当中,理论上能够代替全部 RSA 证书的应用场景,如 SSH 密钥登录、SMTP 的 TLS 发件等。

不过使用 ECC 证书有两个点须要注意:

1、 并非每个证书类型都支持的,通常商业证书中带加强型字眼的才支持ECC证书的签发。

2、 ECC证书在一些场景中可能还不被支持,由于一些产品或者软件可能还不支持 ECC。 这时候就要虚线解决问题了,例如针对部分旧操做系统和浏览器不支持ECC,能够经过ECC+RSA双证书模式来解决问题。

安装

下载源码

综合上述咱们要用到的新特性,咱们整合一下需求:

HTTP/2  要求 Nginx 1.9.5+,,OpenSSL 1.0.2+

TLS 1.3  要求 Nginx 1.13+,OpenSSL 1.1.1+

Brotli 要求 HTTPS,并在 Nginx 中添加扩展支持

ECC 双证书 要求 Nginx 1.11+

这里 Nginx,我我的推荐 1.15+,由于 1.14 虽然已经能支持TLS1.3了,可是一些 TLS1.3 的进阶特性还只在 1.15+ 中提供。

而后咱们定义一下版本号:

建议去官网随时关注最新版:

http://nginx.org/en/download....

https://www.openssl.org/source/

https://github.com/eustas/ngx_brotli/releases

Nginx

OpenSSL

Brotli

编译

后续还有相关变量设置和设置服务、开启启动等步骤,篇幅限制就省略了,这篇文章有介绍在 Ubuntu 下的 Nginx 编译:https://www.mf8.biz/ubuntu-ng...

配置

接下来咱们须要修改配置文件。

HTTP2

只要在 server{}  下的lisen 443 ssl 后添加  http2 便可。并且从 1.15 开始,只要写了这一句话就不须要再写 ssl on 了,不少小伙伴可能用了 1.15+ 之后衍用原配置文件会报错,就是由于这一点。

TLS 1.3

若是不打算继续支持 IE8,或者一些合规的要求,能够去掉TLSv1。

而后咱们再修改对应的加密算法,加入TLS1.3引入的新算法:

若是不打算继续支持 IE8,能够去掉包含 3DES 的 Cipher Suite。

默认状况下 Nginx 由于安全缘由,没有开启 TLS 1.3 0-RTT,能够经过添加 ssl_early_data on; 指令开启 0-RTT的支持。

————

实验性尝试

众所周知,TLS1.3 因为更新了好久,不少浏览器的旧版本依旧只支持 Draft 版本,如 23 26 28 分别在 Chrome、FirFox 上有支持,反而正式版因为草案出来好久,致使TLS1.3在浏览器上兼容性很多太好。

可使用 https://github.com/hakasenyan... 提供的 OpenSSL Patch 让 OpenSSL 1.1.1 同时支持草案23,26,28和正式版输出。 不过因为不是官方脚本,稳定性和安全性有待考量。

ECC双证书

双证书配置的很简单了,保证域名的证书有RSA和ECC各一份便可。

Brotli

须要在对应配置文件中,添加下面代码便可:

为了防止你们看糊涂了,放一个完整的 server{}供你们参考:

先验证一下配置文件是否有误:

若是反馈的是:

就能够重启 Nginx ,而后到对应网站中去查看效果了。

验证

HTTP/2

经过浏览器的开发者工具,咱们能够在 Network 栏目中看到 Protocol 中显示 h2 有无来判断。

TLS 1.3

老地方,咱们能够经过浏览器的开发者工具 中的 Security 栏目看到 Connection 栏目下是否有显示 TLS 1.3

ECC 双证书

ECC 双证书配置了之后无非就是在旧浏览器设别上的验证了。这里用足够老的上古XP虚拟机来给你们证实一波。

XP系统上:

现代操做系统上的:

Brotli

经过浏览器的开发者工具,咱们能够在 Network 栏目中,打开具体页面的头信息,看到 accept-encoding 中有 br 字眼就行。

总结

经过上述手段应该可让 HTTPS 访问的体验优化很多,并且会比没作 HTTPS 的网站访问可能更快。

这样的模式比较适合云服务器单机或者简单集群上搭建,若是有应用 SLB 七层代理、WAF、CDN 这样的产品可能会让咱们的这些操做都白费。 咱们的这几项操做都是自建的 Web 七层服务,若是有设置 SLB 七层代理、WAF、CDN 这样设置在云服务器以前就会被覆盖掉。

因为 SLB 七层和CDN这样的产品会更加追求普遍的兼容性和稳定性并不会第一时间就用上上述的这些新特性(HTTP/2 是广泛有的),可是他们都配备了阿里云的 Tengine 的外部专用算法加速硬件如 Intel® QuickAssist Technology(QAT) 加速器能够显著提升SSL/TLS握手阶段性能。 全部 HTTPS 的加密解密都在 SLB 或 CDN 上完成,而不会落到ECS上,能够显著下降 ECS 的负载压力,而且提高访问体验。

目前云上的网络产品中能支持四层的都是能够继续兼容咱们这套设计的,例如:SLB 的四层转发(TCP UDP)、DDOS高防的四层转发。

相关文章
相关标签/搜索