iliuyt / blog

1 stars 0 forks source link

HTTP2请求流程解析 #13

Open iliuyt opened 6 years ago

iliuyt commented 6 years ago

通过wireshark抓取HTTP2请求截图

image

TCP握手

这里还是简单说一下TCP握手,加深下自己的印象。

字段介绍

image

1、序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记
2、确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
3、标志位:
    * F : FIN - 结束; 结束会话
    * S : SYN - 同步; 表示开始会话请求
    * R : RST - 复位;中断一个连接
    * P : PUSH - 推送; 数据包立即发送
    * A : ACK - 应答
    * U : URG - 紧急
    * E : ECE - 显式拥塞提醒回应
    * W : CWR - 拥塞窗口减少

注意

ACK和ack是大小写不一样是两个不同的东西
ACK是确认报文是否有效,在标志位中,只有ACK=1请求才是有效的。
ack是确认序号,ack=seq+1

握手过程

image

1、客户端发出请求,SYN=1,ACK=0,ACK为默认值为0 seq=x,x为随机数(通俗语言:你能听见吗?)
2、服务端发出回复,SYN=1,ACK=1,seq=y,y为随机数,ack=客户端发送的seq+1=x+1(通俗语言:能,你能听到我说话吗?)
3、客户端发出请求,ACK=1,seq=客户端继续生成一个线性增长随机数,ack=服务端发送的seq+1=y+1(通俗语言:我听得到你,你也听到我了,那么我开始说正事)

关于seq序号生成

seq生成是一个不完全随机的,而是随着时间而线性增长的到了2^32尽头再回滚,为了让攻击者难以猜测seq
TCP四次挥手 (题外话)

image image

挥手过程

1、客户端发出FIN请求,客户端进入等待接收数据状态FIN-WAIT(通俗语言:我发完数据了,你还有数据吗?我等你发。)
2、服务端进入CLOSE_WAIT状态,应答客户端FIN请求(通俗语言:我知道了,我关闭接收通道,你等我消息。)
2.x、服务端可以继续发送数据,可以客户端可以继续接收数据。
3、服务端数据发送完成。(通俗语言:我也发完了,你关闭链接吧,我准备关闭了)
4、客户端回复客户端关闭请求(通俗语言:我关闭连接了)

为什么四次关闭

因为建立请求后,请求SYN和应答ACK可以同时发送,但是关闭连接时,FIN和ACK需要分开发送。
简单的说,在建立连接的第二步,服务端同时做了两件事
    1、我收到你的请求 
    2、你在吗?
而关闭连接的第二步却不能同时回复
    1、我收到了你的请求。
    2、我发送完了数据,可以关闭连接
因为,第二步也可能是
    1、我收到了你的请求
    2、我还有123数发送
所以这一步是分了两步,一个是应答客户端请求,一个是回复客户端数据。所以关闭请求需要四步

为什么要等待2MSL

主动关闭的一方为:A 被动关闭的一方为:B 
A发送FIN给B,A状态为A进入FIN_WAIT_1,B回复ACK,A接受后状态为FIN_WAIT_2,B发送FIN,A接受后状态为TIME_WAIT,立即发送ACK给B,如果网络不稳定,导致ACK丢失,那么B会再超时后,再次发送FIN,如果A的状态是TIME_WAIT,那么A会再次回复ACK,如果非TIME_WAIT,会回复RST,导致B异常。

简述SSL/TLS协议

直接引用网络上的一段话描述

第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。

第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。

第三步,爱丽丝确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。

第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。

第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。

简单的说

(1)生成对话密钥一共需要三个随机数。
(2)握手之后的对话使用"对话密钥"加密(对称加密),服务器的公钥和私钥只用于加密和解密"对话密钥"(非对称加密),无其他作用。
(3)服务器公钥放在服务器的数字证书之中。

session简述

握手阶段用来建立SSL连接。如果出于某种原因,对话中断,就需要重新握手。

这时有两种方法可以恢复原来的session:一种叫做session ID,另一种叫做session ticket。

session ID的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的"对话密钥",而不必重新生成一把。

session ticket是加密的,只有服务器才能解密,其中包括本次对话的主要信息,比如对话密钥和加密方法。当服务器收到session ticket以后,解密后就不必重新生成对话密钥了。

SSL/TLS握手过程

image

1、客户端 Client Hello 图中序号:238
    a、客户端支持的版本协议
    b、客户端支持的加密算法
    c、客户端生成的随机数

2、服务端 Server Hello 图中序号:240
    a、确认协议版本
    b、服务器生成随机数
    c、确认加密算法

3、服务端发送服务器证书 Certificate 图中序号:241
4、服务端发送DH参数 Server Key Exchange 图中序号:242
5、客户端端发送DH参数 Client Key Exchange,握手完成 图中序号:244
6、服务端生成Session Ticket 图中序号:247

ALPN扩展

什么是NPN和ALPN

NPN(Next Protocol Negotiation,下一代协议协商),是一个TLS 扩展,由Google 在开发SPDY 协议时提出,也就是服务端和浏览器之间用来决定使用HTTP/1.1 还是最新的HTTP/2 的协议。随着SPDY 被HTTP/2 取代,NPN 也被修订为ALPN(Application Layer Protocol Negotiation,应用层协议协商)。二者的目标一致,都是用来在服务端和浏览器之间协商使用哪个HTTP 版本,但实现细节不一样,相互无法兼容。

HTTP2中的ALPN如何应用的

image image

在SSL/TLS握手过程中,客户端发送Client Hello中,扩展了ALPN(Application Layer Protocol Negotiatio),上图是HTTP2扩展的ALPN,可以看到Client Hello中与服务器协商使用什么协议,客户端提供了httP/1.1和h2,服务器回复的Server Hello中确认了使用的协议为h2。

HTTPS版本HTTP2请求

image image

1、客户端和服务端TLS层协商(HTTP2中的ALPN如何应用的已经说明了如何协商)
2、一旦确认HTTP2格式,客户端立即发送链接序言,图中序号:245
连接序言格式
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n // 纯字符串表示,翻译成字节数为24个字节  
SETTINGS帧                       // 其负载可能为空  

3、服务器端发送连接序言 图中序号:248
4. 接收到客户端连接序言之后,双方各自确认SETTINGS帧,图中序号:250,252
头部压缩

image image image

HTTP2通过首部表压缩头部信息,首部表由服务端和客户端共同维护。通过上图可以很清晰的看到HTTP2是如何进行压缩的,和压缩有的效果。

HTTP/2 头部压缩技术详细介绍

首部表维护的猜想

首部表是在创建连接时候创建一个属于该域名的首部表(猜想),然后服务端和客户端共同维护该表。

HTTP2相关资料查阅