深入HTTP协议(下)

Posted 测开成长记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入HTTP协议(下)相关的知识,希望对你有一定的参考价值。

前面一直介绍HTTP,本篇会介绍HTTPS了,就是会进入了安全方面的介绍。当然还有汇总性能方面的介绍。


一、安全认知

        众所周知,http是明文传输,并不安全,所以才有了https。那怎么样才是安全的呢?

  • 机密性:对传输数据进行保密

  • 完整性:数据传输保持原样不能被篡改

  • 身份认证:通信时对对方身份的确认,以防假冒

  • 不可否认:对事物真实性对保证


        在HTTP的基础上加上上面四大特性就是HTTPS了。HTTPS相比于HTTP,协议名不同,还有默认端口不同(http默认80,https默认443),其他语法和语义上跟http相同,在安全方面靠的是S(SSL/TLS)来保障的。

  • SSL:安全套接层,OSI模型里会话层的协议,后来到V3版本就被改名为TLS

  • TLS:传输层安全,由记录、握手、警告、扩展等协议组成,综合使用对称加密、非对称加密、身份认证等技术实现安全通信。

        我们把客户端和服务器建立TLS需要的一组加密算法称为“加密套件”,格式是“密钥交换算法+签名算法+对称加密算法+摘要算法”,举个例子:service suite:ECDHE-RSA-AES256-GCM-SHA384,这个加密套接的意思是:握手时用ECDHE算法进行密钥交换,用RSA签名和身份认证,握手后用AES对称加密算法,密钥长度256,分组模式GCM,摘要算法SHA384用于消息认证和产生随机数。

        你一定听过著名的OpenSSL吧,是开源密码学工具包,是SSL/TLS具体的实现。Apache、nginx都是用它作为底层库实现TLS功能。


二、机密性

        上面提到了一些概念,加密套接、密钥、加密算法等。这里就对加密解析一下,主要可以分为:对称加密、非对称加密。你还先需要了解几个概念:

  • 明文:加密前的消息

  • 加密:通过加密算法把明文转为密文的过程,与之对应的概念是解密

  • 密钥:加解密的钥匙,一串数字,单位是bit。

  • 密文:加密后咱们看到的乱码那种形式


        对称加密:加解密的密钥是同一个即对称的。常见的算法有AES(密钥长度128、192或256,应用广泛且有的硬件会做特殊优化)和ChaCha20(密钥长度固定256,曾在移动端上流行)。它还有一个概念是分组模式,用固定长度的密钥加密任意长度明文。常见的分组模式有:ECB、CBC、GCM、CCM、Poly1305。对称加密暴露出了一个安全性问题,怎么保证密钥的安全性呢,因为如果密钥被截获就可以进行解密了,所以就引入了非对称加密的概念。

        非对称加密:公钥加密私钥解密或者私钥加密公钥解密。解决了密钥交换的问题,网站秘密保管私钥,密文只有私钥持有者才能解密。常见的算法有:RSA、ECC等。非对称加密虽然保障了安全性,但是复杂的运算使通信速度变的很慢。


        上面我们看到了对称和非对称加密都各有优缺点,在实际TLS中是把两者结合起来,即混合加密方式。过程是:先用RSA等非对称加密解决密钥交换问题->随机数生成会话密钥(session key)->公钥对会话密钥加密,私钥解密就拿到了会话密钥(客户端和服务端用的同一个密钥,就实现了对称加密)->后续传输数据都是用的此对称加密。如下图所示,非对称加密实现了会话密钥的安全交换,后面对称加密保障了传输速度。


三、完整性和身份认证

        保障完整性的手段是摘要算法,把任意长度字符串压缩成独一无二摘要字符串,这个过程就是你在原文后面附上它的摘要,你收到后也进行相应的计算,对比一下摘要是否一致,一致就表示没有被篡改过。既然摘要是一起发送的,所以还要保障原文里的摘要不能被篡改,所以完整性是要建立在机密性之上。常见的摘要算法有:MD5、SHA-2。

        虽然保障了机密性和完整性,那两端的安全怎么保障,就需要身份认证了。实现身份认证的手段是数字签名(非对称加密的私钥+摘要算法),签名的原理是私钥加密、公钥解密,签名和公钥一样对外公开,但只有对应但公钥才能解密拿到摘要,然后再比对完整性。这就是签名和验签。它也同时实现了不可否认。

        那如果公钥被伪造了怎么办,这里就需要CA证书认证机构来保障公钥是可信的。操作系统和浏览器都内置了各大CA的根证书。


四、HTTPS性能优化

        咱们通常能感觉到https的连接比http的要慢,这里的慢主要是因为建立连接的时候非对称加密握手和对称加密传输、证书验证等。要优化的话可以从以下几个方面入手:

  • 软件升级:通常软件更新版本会有性能优化,比如把linux内核、Nginx升级等。不过机器太多升级也有风险。

  • 协议优化:可以从握手使用密钥交换协议入手,选取速度快安全性高的算法。

  • 证书优化:从证书传输和验证方面优化,证书可以选取节约带宽并减少运算量的如ECDSA证书,验证方面可以优化的地方是防止证书失效客户端访问CA的时间,考虑OCSP装订补丁,让服务器预先访问CA获取OCSP响应,然后握手时发给客户端。

  • 会话复用:一个是session ID方式,客户端和服务器各保存会话id,省去了每次证书验证和密钥交换过程。但这个会给服务器加重负担,因为它要保存很多客户端的会话数据。为此引入了session ticket概念,类似于cookie,由客户端分担。


五、Web服务器

(1)Nginx

        主流的web服务器有Apache和Nginx,小编所在的公司用的也是Nginx,这里也是主要介绍Nginx。它作为后起之秀,发展的非常迅速,是轻量级web服务器,占用的CPU、内存非常少,咱们就来剖析下它的工作原理吧。

        进程池:以前web服务器为每个请求单独起进程或线程,进程或线程的创建和上下文切换会浪费很多开销,而Nginx预先创建好固定数量的worker进程即进程池,进程池上面由一个master进程管理(nginx由C语言实现,作用自动恢复异常的worker)进程池,并自动绑定到独立CPU上。这种模式省去来进程创建和切换成本,且利用了多核CPU的能力。

        I/O多路复用:nginx采用单线程,因为多线程有一些成本如上下文切换、数据竞争和同步等问题,那单线程的它怎么提高处理能力呢?web服务器是I/O密集型而不是CPU密集型,提高能力需要提高网络收发,Nginx采用I/O多路复用epoll,将多个HTTP请求打碎复用到单线程里,不按顺序,当连接阻塞切换出去,可读写时才处理,如果你对IO模型并不清楚,推荐你先看看https://zhuanlan.zhihu.com/p/115220699这篇文章,redis也是采用epoll方案。

        多阶段处理:在配置文件里任意拼接,实现灵活性和扩展性。Nginx对HTTP处理有如下几个模块:handler(直接处理HTTP请求)、filter(不直接处理,经过加工过滤响应报文)、upstream(反向代理,转发请求到其他服务器)、balance(反向代理实现负载均衡算法)。

        说了这么多优点,那它有啥缺点呢,nginx使用磁盘上静态配置文件,每次修改后需要重启才能生效,这点非常不灵活。所以引入了javascript作为可编程配置脚本,一定程度上实现了动态配置。接下来介绍另一种web服务器有nginx的优点,又没有它的缺点,就是OpenResty。


(2)OpenResty

        它的核心还是Nginx,利用Nginx的模块化扩展性,开发了一系列增强模块,把Lua语言嵌入到Nginx可以用脚本方式操作Nginx内部进程、多路复用、阶段处理等,关键是Lua脚本语言有“代码热加载”特性,不需要重启进程就能从任何地方加载数据,实现动态配置。总结特性如下:

  • 基于Nginx打包了很多模块和库

  • 工作语言是Lua,小巧灵活,支持热加载,无需重启

  • 核心编程范式是同步非阻塞,使用协程,无需异步回调

  • 也采用阶段式处理模式,但使用Lua所以更加灵活


六、HTTP性能测试

        从请求-应答模式上可以拆分成3个方面来分析性能:客户端、服务器、传输链路。

(1)服务器

        服务端压测工具很多,比如ab,ab -c 100 -n 10000 'http://xx' 表示并发数100总共发送10000个请求,还有Jmeter衡量服务器常见的性能指标如下:

  • 吞吐量:RPS/TPS/QPS,没秒请求数,该值越高说明服务器性能越好。

  • 并发数:服务器能同时支持客户端数量。

  • 响应时间:反映服务器处理能力即快慢。

  • CPU/内存:常用命令如uptime、top等

  • 硬盘和网卡等:sar -n DEV 2 定时查看网卡流量


(2)客户端

        客户端的数据需要从服务器获取,它的性能指标就是延迟。影响它的因素也很多:带宽、DNS查询、TCP握手等,下面我通过chrome浏览器请求一个网址查看它各部分的延迟如下图。



分析这里几个延迟的点:

  • 队头阻塞:一个域名下浏览器最多并发6个连接,当页面链接多时需要排队(Queue、Queueing),这里一共耗费17ms

  • 预先分配资源调度连接即stalled,耗费16.48ms

  • 域名解析DNS Lookup,耗费18us

  • 建立连接Initial connection一共耗费31.67ms,其中SSL耗费来20.05ms,那剩下的就是TCP握手时间。

  • 发送数据Request sent耗费0.28ms

  • 等待服务器响应TTFB(首字节响应,包含服务器处理时间和网络传输时间)耗费147.05ms

  • 接收数据Content Download耗费17.05ms

上面只是指的HTTP方面的性能,web性能还有html、CSS、JS等,比如页面渲染顺序优化可以考虑CSS放在HTML顶部,JS放在底部。

(3)传输链路

        链路这里分为几个部分:网站的出口(直接决定网站对外服务能力,即吞吐量等指标)、中间部分(受距离、网站互通影响,可以用CDN)、互联网入口(用户端网线、WIFI、基站等,不受控制)。


(4)优化

  • 开源:

    1、高性能服务器如Nginx并利用反向代理实现动静分离,动态页面交给tomcat、Django,静态资源交给Nginx; 

    2、HTTP协议启用长连接,减少TCP和SSL新建连接的成本

    3、在操作系统或Nginx开启TCP Fast Open,在初次握手就传输数据,减少内外网握手延迟

  • 节流

    1、数据压缩,文本文件可以采用gzip或br压缩,但对于一些已经高度压缩的图片等可以去掉一些不必要等数据如地点,同时降低分辨率缩小尺寸等方式压缩,对于HTML/CSS/JS等文本可以通过去掉空行换行注释等元素。对于小文本或图片可以采用资源合并的方式节省请求次数。头部减少cookie记录数据量或减少使用cookie传输。

    2、域名方面,减少DNS解析域名开销,适当缩减域名

    3、尽量减少使用重定向,之前的文章介绍过重定向会增加一次请求,而且还会导致新DNS解析,也可能会导致客户端延迟过高。

  • 缓存

    1、服务内部可以采用memcache、redis等缓存服务,加快访问后台服务时间。

    2、中间链路可以用CDN缓存网络加速功能

    3、每个资源设置cache-control、expire缓存属性,并结合ETag和Last-Modified字段,这样资源到客户端可以被缓存起来,有效期内就无需再请求服务端。

  • HTTP/2

    HTTP/2相比HTTP/1有很多优点,如消除队头阻塞、增加头部压缩、实现多路复用、流量控制等新特性,直接升级到HTTP/2也可以带来性能上的优化。

以上是关于深入HTTP协议(下)的主要内容,如果未能解决你的问题,请参考以下文章

深入理解HTTP协议

深入理解HTTP协议

HTTP协议HTTP协议初体验,深入浅出网络协议

HTTP协议HTTP协议初体验,深入浅出网络协议

深入浅出HTTP协议

Webserver-HTTP项目(深入理解HTTP协议)