本文转载自《云栖社区》,作者:苗正辉前言分享一个HTTPS优化案例。随着相关浏览器引入“不安全”HTTP协议和红页警告等严格措施,以及iOS应用的ATS要求和微信、支付宝小程序的强制HTTPS要求,以及等级保护等合规方面对于传输的安全需求正在推动HTTPS的发展。虽然HTTPS优化了网站访问体验(防劫持),让传输更安全,但很多网站主在使用HTTPS后,经常会遇到页面加载速度慢、服务器负载高、证书过期等问题。及时更新等问题。所以本文讨论HTTPS的优化实践。事实上,ApacheHttpd、LigHttpd、Canddy等Web服务软件都可以设置HTTPS,但在相应的扩展生态和更新速度上都不如Nginx。Nginx作为大型互联网网站的门户软件,拥有广泛的支持率。比如阿里巴巴的Tengine,CloudFlare的cloudflare-nginx,还有Paiyun的OpenResty,都是基于Nginx的。Nginx已经接受了大规模的访问验证。同时大家也会将自己开发的组件回馈给Nginx社区,让Nginx有一个非常好的扩展生态。图1-1Nginx在全网的使用情况Nginx是一款非常优秀的Web服务软件。选择Nginx可以在提升性能的同时大大降低我们的扩容成本。新功能围绕Web服务已经有很多新功能需要我们去关注和应用。这里先列出相关的新功能。HTTP/2与比较老的HTTP/1.x相比,HTTP/2在底层传输上做了很大的改变和优化,包括:每个服务器只使用一个连接,节省了建立多个连接的时间。效果在TLS上尤为明显。加速TLS交付。HTTP/2只需要一次TLS握手。通过在一个连接上多次使用来获得最佳性能会更安全。通过减少TLS的性能损失,让更多的应用可以使用TLS,让用户信息更安全Akamai的HTTP/2DEMO中加载了300张图片,HTTP/2的优越性得到了极大的体现。HTTP/1.X运行需要14.8s,HTTP/2只需要1s。现在绝大多数现代浏览器都支持HTTP/2。只要我们保证Nginx版本大于1.9.5即可。当然,建议保持最新的稳定版Nginx,以便及时更新相关补丁。同时,HTTP/2要求OpenSSL版本大于1.0.2才能支持现代浏览器。TLS1.3与HTTP/1.x相同。目前主流支持的TLS协议版本为1.1和1.2,分别于2006年和2008年发布,都已经落后于时代需求。2018年8月,IETF终于宣布正式发布TLS1.3规范,标准规范(StandardsTrack)定义在rfc8446中。与上一版本相比,TLS1.3的优化内容如下:握手时间:同等情况下,TLSv1.3比TLSv1.2少1个RTT。应用数据:在会话复用场景下,支持0-RTT。之后就全是密文了。会话复用机制:放弃SessionID方式的会话复用,采用PSK机制的会话复用。密钥算法:TLSv1.3只支持PFS的密钥交换算法(即完全前向安全),禁用RSA的密钥交换算法。对称密钥算法只使用AEAD加密算法,在CBC模式下禁用AES和RC4算法。密钥推导算法:TLSv1.3使用了一种新设计的算法HKDF,而TLSv1.2使用的是PRF算法。后面我们再看看这两种算法的区别。综上所述,在更安全的基础上更快。目前TLS1.3的重要实现是OpenSSL1.1.1已经开始支持,1.1.1还是一个LTS版本。未来RHEL8和Debian10将以它作为主要支持版本。Nginx上的实现需要Nginx1.13+。BrotliBrotli是谷歌于2015年9月推出的一种无损压缩算法,它使用LZ77算法的变体、哈夫曼编码和二阶文本建模进行数据压缩。是一种压缩比很高的压缩方式。根据谷歌发布的一份研究报告,Brotli具有以下特点:对于常见的网络资源内容,Brotli的性能比Gzip提高17-25%;当Brotli的压缩级别为1时,压缩速度最快,此时的压缩率高于gzip压缩级别9(最高);在处理不同的HTML文档时,brotli仍然提供了非常高的压缩率;在兼容GZIP的同时,与GZIP相比:JavaScript减少14%,HTML减少21%17%Brotli对%CSS的支持必须依赖HTTPS,但换句话说,Brotli只能在HTTPS下实现。ECC证书Ellipticcurvecryptography(Ellipticcurvecryptography,简称ECC),一种建立公钥加密的算法,基于椭圆曲线数学。椭圆曲线在密码学中的应用是由NealKoblitz和VictorMiller于1985年独立提出的。内置ECDSA公钥的证书一般称为ECC证书,内置RSA公钥的证书称为RSA证书。由于256位ECCKey在安全性上等同于3072位RSAKey,而且ECC计算速度更快,ECDHE密钥交换+ECDSA数字签名无疑是最好的选择。由于在同等安全条件下,ECC算法所需的密钥更短,因此ECC证书的文件大小比RSA证书小。ECC证书不仅可以在HTTPS场景下使用,理论上可以替代所有RSA证书的应用场景,比如SSH密匙登录,SMTPTLS发送等。不过使用ECC证书有两点需要注意:一是,并非每种证书类型都受支持。只有一般商业证书中带有增强字的才支持签发ECC证书。2、ECC证书在某些场景下可能不支持,因为部分产品或软件可能还不支持ECC。这时候就需要用虚线来解决问题了。例如,对于一些不支持ECC的旧操作系统和浏览器,可以通过ECC+RSA双证书模式来解决问题。安装下载源码集成上面我们要用到的新特性,我们来集成需求:HTTP/2需要Nginx1.9.5+,OpenSSL1.0.2+TLS1.3需要Nginx1.13+,OpenSSL1.1.1+Brotli需要HTTPS,并在Nginx中增加对ECC双证书的扩展支持。这里需要Nginx1.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/releasesNginxOpenSLBrotli编译之后是相关的变量设置和服务设置,启动等步骤,篇幅限制从略。本文介绍Ubuntu下Nginx编译:https://www.mf8.biz/ubuntu-ng...。配置接下来我们需要修改配置文件。对于HTTP2,只需在server{}下的lisen443ssl之后添加http2。而且从1.15开始,只要写这句话,就不用再写sslon了。可能很多朋友在使用1.15+后使用原来的配置文件会报错,就是因为这个。如果TLS1.3不打算继续支持IE8,或者一些合规性要求,可以移除TLSv1。然后我们修改相应的加密算法,加入TLS1.3引入的新算法:如果不打算继续支持IE8,可以去掉包含3DES的CipherSuite。默认情况下,出于安全原因,Nginx不启用TLS1.30-RTT,您可以通过添加ssl_early_dataon来启用0-RTT支持;命令。————实验性的尝试众所周知,TLS1.3已经更新很久了,很多旧的浏览器版本仍然只支持Draft版本,比如23、26、28分别在Chrome和FiFox中支持,但是因为草稿,正式版已经发布很久了。因此,TLS1.3具有很多浏览器兼容性。可以使用https://github.com/hakasenyan...提供的OpenSSLPatch,让OpenSSL1.1.1同时支持draft23、26、28和正式版输出。但由于不是官方脚本,需要考虑稳定性和安全性。ECC双证书双证书配置非常简单,只需要保证域名证书有一张RSA证书和一张ECC证书即可。brotli需要在对应的配置文件中添加如下代码:为了不让大家看糊涂,放一个完整的server{}供大家参考:首先验证配置文件是否有误:如果反馈是:可以重启Nginx,然后去相应的网站查看效果。验证HTTP/2是否通过浏览器的开发者工具,我们可以通过在Network栏中的Protocol中是否显示h2来判断。在TLS1.3的老地方,我们可以通过浏览器的开发者工具中的Security栏,查看Connection栏下是否显示有TLS1.3ECC双证书ECC双证书。配置双证书后,无非就是在旧的浏览器设备上进行验证。这里我用一台够老的古董XP虚拟机来给大家证明一下。在XP系统上:在现代操作系统上:Brotli通过浏览器的开发者工具,我们可以在Network栏中打开具体页面的头部信息,看到accept-encoding中有一个br字样。小结通过以上手段,HTTPS访问的体验应该会优化很多,可能比没有HTTPS的网站访问速度更快。这种模式更适合构建在单个云服务器或者简单的集群上。如果有SLB七层代理、WAF、CDN等产品,我们的操作可能就白费了。我们这些操作都是自建Web七层服务。如果设置了SLB七层代理、WAF、CDN,这些设置会先于云服务器被覆盖。由于SLB七层、CDN等产品会追求广泛的兼容性和稳定性,所以不会马上使用上述新特性(常见的有HTTP/2),但都搭载了阿里云Tengine的外置专用算法加速硬件例如Intel?QuickAssistTechnology(QAT)加速器可以显着提高SSL/TLS握手阶段的性能。所有HTTPS加解密都在SLB或CDN上完成,而不是在ECS上完成,可以显着降低ECS的负载压力,提升访问体验。目前云上可以支持四层的网络产品可以继续兼容我们的设计,例如:SLB的四层转发(TCPUDP),DDOS高防的四层转发。
