基于 Nginx 的 HTTPS 性能优化实践

标签: nginx https 性能优化 | 发表时间:2019-07-09 08:00 | 作者:
出处:http://www.phpxs.com

前言


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


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


所以本文就来探讨一下 HTTPS 的优化实践。


选型


其实像 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 版本,未来的 RHEL8、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 证书有两个点需要注意:


一、 并不是每一个证书类型都支持的,一般商业证书中带增强型字眼的才支持ECC证书的签发。




二、 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.html

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

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

Nginx


OpenSSL


Brotli



编译


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

配置


接下来我们需要修改配置文件。


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/hakasenyang/openssl-patch/ 提供的 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高防的四层转发。

相关 [nginx https 性能优化] 推荐:

基于 Nginx 的 HTTPS 性能优化实践

- - 编程学习网
分享一个HTTPS优化案例(文章稍长. 随着相关浏览器对HTTP协议的“不安全”、红色页面警告等严格措施的出台,以及向 iOS 应用的 ATS 要求和微信、支付宝小程序强制 HTTPS 需求,以及在合规方面如等级保护对传输安全性的要求都在推动 HTTPS 的发展. 虽然 HTTPS 优化了网站访问体验(防劫持)以及让传输更加安全,但是很多网站主赶鸭子上架式的使用了 HTTPS 后往往都会遇到诸如:页面加载速度变慢、服务器负载过高以及证书过期不及时更新等问题.

Nginx性能优化

- - 博客 - 伯乐在线
Nginx作为一个非常流行和成熟的Web Server和Reserve Proxy Server,网上有大量的性能优化教程,但是不同的业务场景千差万别,什么配置是最适合自己的,需要大量的测试和实践以及不断的优化改进. 最近用户调用量突破百万大关之后,就遇到了一些问题,虽然不算太复杂,但也折腾了挺长时间才搞定,积累了不少经验.

Nginx配置性能优化

- - CSDN博客互联网推荐文章
大多数的Nginx安装指南告诉你如下基础知识——通过apt-get安装,修改这里或那里的几行配置,好了,你已经有了一个Web服务器了. 而且,在大多数情况下,一个常规安装的nginx对你的网站来说已经能很好地工作了. 然而,如果你真的想挤压出Nginx的性能,你必须更深入一些. 在本指南中,我将解释Nginx的那些设置可以微调,以优化处理大量客户端时的性能.

Nginx 安装 HTTPS 证书

- - idea's blog
基本步骤可以参考 这篇文章, 但这篇文章有一个致命错误, 就是没有安装 INTERMEDIATE CA, 照样会被浏览器显示证书不可信.. 生成 server.key.orig. 生成 server.csr 和 server.key. 拿着 server.csr 去证书厂商买证书. 买完后, 厂商会给你发两个证书 server.crt 和 server.intermediate.crt.

nginx 配置 https 的双向认证

- - 操作系统 - ITeye博客
SSL 的双向认证就是,客户端要获取服务端的证书,检查下服务端是不是我可以信任的主机,否则我就认为那个站点的内容不可信任,不应该去访问你(浏览器会告诉你),同时服务端也要检查客户端的证书,客户端如果不是服务端所信任的,那服务端也会认为,你不是我的合法用户,我拒绝给你提供服务. 所以,要让 HTTPS 的双向认证顺利完成,就要在服务端给定一个证书,这个证书是浏览器可信任的,同时客户端(浏览器)也要发送给服务端一个证书,服务器端也要信任这个证书.

nginx强制使用https访问的多种方法(http跳转到https)

- - C1G军火库
nginx强制使用https访问的多种方法(http跳转到https). 先说明一下HTTP跳转的状态码. 301 Moved Permanently:该方式将所有的 HTTP 请求重定向到 HTTPS 上,并且该重定向是永久性的. 客户端在收到 301 响应后,会自动将 HTTP 请求转为 GET 请求,同时将请求地址修改为重定向后的地址.

Nginx + Tomcat + HTTPS 配置原来不需要在 Tomcat 上启用 SSL 支持

- -
之前在网上搜索到的很多文章在描述. Nginx + Tomcat启用 HTTPS 支持的时候,都必须在 Nginx 和 Tomcat 两边同时配置 SSL 支持. 但我一直在想为什么就不能按照下面的方式来配置呢. 就是 Nginx 上启用了 HTTPS,而 Nginx 和 Tomcat 之间走的却是普通的 HTTP 连接.

certbot在Centos7上配置合法签名证书,实现nginx的https访问-咖啡猫Mr-51CTO博客

- -
  公司因之前使用的openssh创建的自签名证书,有一个弊端,就是在某些客户端上不能使用此证书,无法使用https连接,所以,研究了一下certbot 做签名证书. 你需要有一个公网地址,并绑定合法域名. (1)、下载Certbot客户端:. (2)、下载后,进入下载的目录,添加执行权限. 3、介绍一下certbot的两种工作方式:.

如何让网站和API都支持HTTPS?在Nginx上做文章是个好选择!

- - 掘金后端本月最热
SpringBoot实战电商项目mall(40k+star)地址:. 随着我们网站用户的增多,我们会逐渐意识到HTTPS加密的重要性. 在不修改现有代码的情况下,要从HTTP升级到HTTPS,让Nginx支持HTTPS是个很好的选择. 今天我们来讲下如何从Nginx入手,从HTTP升级到HTTPS,同时支持静态网站和SpringBoot应用,希望对大家有所帮助.

https协议

- - 互联网 - ITeye博客
SSL 协议的握手过程   .       为了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议. SSL 协议既用到了公钥加密技术(非对称加密)又用到了对称加密技术,SSL对传输内容的加密是采用的对称加密,然后对对称加密的密钥使用公钥进行非对称加密. 这样做的好处是,对称加密技术比公钥加密技术的速度快,可用来加密较大的传输内容,公钥加密技术相对较慢,提供了更好的身份认证技术,可用来加密对称加密过程使用的密钥.