一:http?
1、http报文认识
Remote Address
:访问目标
URL
解析出来的
IP
地址,
443
:表示当前
https
协议。
Referrer Policy : Referrer
用户指明当前请求的来源页面,对于同源的请求,会发送完整的url
作为引用地址,防盗链。
accept
:请求可以支持的响应格式列表信息
accept-encoding
:告知服务器本地浏览器支持是压缩方式
sec-fetch-dest
:期望获得什么类型的资源
sec-fetch-mode
:
navigate
,表示这是一个浏览器的页面切换请求
sec-fetch-site
:表示一个请求发起的来源和目标资源来源之间的关系,
cross-site:跨域请求,
same-origin:同源请求。 none: 不是同源也不是跨域,请求与任意上下文无关。比如浏览器窗口中拖放一个文件
sec-fetch-user:
表示一个导航请求是否由用户激活触发(如用户主动点击鼠标、键盘) 。
Sec-Fetch-User: ?0? ?否? ? ? ? ? ? ? ? Sec-Fetch-User: ?1? ?是
upgrade-insecure-requests :1,? ? ??
浏览器告诉服务器,浏览器是可以处理https
请求的,即使访问的
https
请求中又包含了其他的
http
请求。
user-agent
:描述浏览器的信息
?
response中的属性,基本都是和request中对应上 ,在request支持的里面选择一个使用。
介绍两个:
server
:部署web应用
的容器。?
openresty
:封装了
Nginx
以及第三方的类库,Lua
语言,
redis
等。
vary
:accept-Encoding。指的是参考request中的accept-Encoding属性,支持的是什么格式,然后,告诉代理服务器缓存对应格式的资源(压缩、不压缩)。? ?代理服务器指的是,各地区的边缘服务器,如cdn,不可能所有请求都去请求主服务器。
2、http链接管理-TCP
http通信是基于tpc/ip承载的,https多了一个安全层,所以https是安全的。
?TCP就是为了建立链接,传输数据的一种管道。 一个设备可以同时有多个管道,所以TCP使用一个信封一样的东西:TCB数据结构,把每个管道的数据包起来隔离开。
TCP建立连接需要三次握手,释放连接需要四次挥手:
1、三次握手:
(
0
)准备工作
最开始的时候客户端和服务器都是处于
CLOSED
状态。主动打开连接的为客户端,被动打开连接的是服务器。
TCP
服务器进程先创建传输控制块
TCB
,时刻准备接受客户进程的连接请求, 此时服务器就进入了LISTEN
(监听)状态。
(
1
)一次握手:
TCP
客户端创建传输控制块
TCB
,然后向服务器发出连接请求报文, 报文首部中的同步位SYN=1表示我要发起同步,建立连接
,同时选择一个初始序列号
seq=x ,就是一个标识,后续需要累加
。
此时,TCP
客户端进程进入了
SYN-SENT
(同步已发送状态)状态。
TCP
规定,SYN
报文段(
SYN=1
的报文段)不能携带数据,但需要消耗掉一个序号。
(
2
)二次握手:
TCP服务器收到请求报文后,如果同意连接,则发出确认报文:
ACK=1,表示同意并确认要建立连接(0则表示不包含确认信息)。
ack=x+1,确认号,确认的是上一条客户端发起的那个请求。
SYN=1,表示服务端也要发起同步
seq=y
,向客户端发起同步,也需要一个自己的序列号。
此时TCP
服务器进程进入了
SYN-RCVD(同步收到)状态。
(
3
)三次握手:
TCP
客户端收到确认后,还要向服务器给出确认。确认报文的
ACK=1
,
ack=y+1确认的是服务端发过来的序列号
,自己的序列号
seq=x+1
,此时,
TCP连接建立,客户端进入ESTABLISHED
(已建立连接)状态。
TCP
规定,
ACK
报文段可以携带数据,但是如果不携带数据则不消耗序号。
当服务器收到客户端的确认后也进入
established
状态,此后双方就可以开始 通信了。
为什么需要第三次握手?
表面上看,两次握手后即可建立连接,但是并不严谨,比如:客户端发了同步请求,由于网络或其他原因,服务端暂时没有收到,于是客户端重试又发送了一条一模一样的请求。? 经过两次握手后建立了连接并传输了数据,第一次的请求恢复正常到达了服务端,于是,服务端给出了回应。 这样又会再次建立连接传输数据,造成资源开销和浪费。?
有了第三次握手后,,客户端就算收到了重试那一条的确认,但是它知道已经建立过相同的链接,就不会再进行第三次握手了。
也从另一个角度看:
第一次握手: 客户端只确认了自己的发送能力OK,,服务端只确认了自己的接受能力OK。
第二次握手:客户端确认了自己和服务端的发送能力OK、接受能力OK;? 但是服务端只知道自己的接受和发送能力OK,客户端发送能力OK(服务端并不知道客户端是否接受到自己的回应)。
第三次握手:服务端和客户端,都确认了自己和对方的发送和接受能力。
?
TCP
协议缺陷
?
DDOS又称为分布式拒绝服务,就是不应答正常的请求。 比如经典的
SYN flood攻击就会造成这样的情况:
1. SYN flood
在攻击时,首先伪造大量的源
IP
地址,分别向服务器端发送大量的SYN
包。
2.
服务器端返回
SYN/ACK
包,因为源地址是伪造的,所以伪造的
IP
并不会应答。
3.
服务器端没有收到伪造
IP
的回应,会重试
3~5
次并且等待一个
SYN Time
(
—般为30
秒至
2
分钟),如果超时则丢弃这个连接。
4.
攻击者大量发送这种伪造源地址的
SYN
请求,服务器端将会消耗非常多的资源来处理这种半连接,同时还要不断地对这些IP
进行
SYN+ACK
重试。
5.
最后的结果是服务器无暇理睬正常的连接请求,导致拒绝服务。
2、四次挥手:
?
?数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于established(表示连接已经建立)状态,然后客户端主动关闭,服务器被动关闭。
(
1
)
TCP
客户端发送一个
FIN
,用来关闭客户到服务器的数据传送(和SYN相反)。
(
2
) 服务器收到这个
FIN
,它发回一个
ACK
,确认序号为收到的序号加
1。当然,此次确认也需要带上自己的一个seq,标识一次独立的请求应答。
(
3
) 服务器关闭客户端的连接,主动在发送一个
FIN
给客户端,标识我也要关闭(
为什么这个FIN不放到第2步呢)
。
(
4
) 客户端发回
ACK
报文确认,并将确认序号设置为收到序号加
1
。
为什么服务端的FIN不放到第2步呢?
关闭连接时,服务器收到对方的
FIN
报文时,仅仅表示对方不再发送数据了,但对方还能接收数据,而自己也未必已经将全部数据都发送给对方
了,所以自己可以立即关闭,也可以发送一些数据给对方后,再发送FIN
报文给对方来表示同意现在关闭连接,因此,服务器的ACK
和
FIN
一般都会分开发送,从而导致多了一次,这也是握手三次,挥手需四次的原因。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
服务端有一个计时器,每次收到客户端请求都会复位,若2小时内没有收到数据,就会发送探测报文,后每隔75s探测一次,共10次,没有反馈就关闭连接。
3、TCP的数据传输方式-滑动窗口协议
TCP传输是将报文切割成多个,按顺序分段传输的,因为网络有流量大小限制,每段大小一般默认为536字节,接收后按顺序拼接起来。? 那么问题来了,如果串行发送,效率太低;如果并行发送,可能造成网络阻塞。? 怎样来把握这个度呢?
使用滑动窗口,根据段数据大小和网络情况,每次发送合适数量的段,以及该发送哪一些。如图:
灰色:已发送且已确认。
黄色:已发送还没确认。
绿色:等待发送,还没确认。
白色:未发送,也没确认。
滑动窗口管理的就是中间两部分数据。 比如,当5被确认后,窗口就会右移一格,5变成灰色,将10发出去变成黄色,12加入内存准备发送,变成绿色。(当然,并不一定只处理一段)
超时重发:?
滑动窗口可以保证每一段是否被成功发送并确认,但是,万一5阻塞了,一直等待5的ACK,就没法把12号加进来。。 这时候就会对5做重试,原理是有一个超时重传时间RTO,决定重试的等待时间:默认首次是6s,后续已2,4的倍数指数增长。? 当重试次数达到限制后,认为有问题,关闭连接。
4、TCP性能解析
http事务消耗的时间,主要有:
- DNS解析,将url中域名解析为服务器的ip。
- 建立TCP连接(三次握手)。
- 网络传输报文和服务端处理报文都需要时间。
- 服务端回传报文。
这些问题和网络,设备性能都有很大关系。 假如网络和设备都很好的情况下,性能就主要看TCP了。
创建TCP的性能问题:
- TCP建立需要三次握手:
- 建立一个http链接,需要建立一个TCP,经过三次握手耗时。? 如果打开一个页面需要访问很多个http,耗时一下就上去了。
- TCP慢启动:
- 上面说了滑动窗口可以根据网络确定发送多少个分组的报文,如何确定的? 其实就是TCP建立后,不断的探测网络情况,第一次发送一个,第二次发送两个,四个… 直到达到合适的量。? ? ?如果一个http中包含了很多个分组报文,是不能一次发送完的。
- 延迟确认ACK:
- 在进行ACK确认时,为了有效利用网络,会尽量”捎带“一些其他的输出数据。 也就是说并不会马上给对方返回ACK确认,而是要等待一定的时间,这段时间内看看有没有数据可以顺带返回。? 如果没有,就白等了,也就是延迟确认ACK这种算法,一定程度上会造成性能降低。
5、http特性
基于TCP的特点,可以想象,如果打开一个页面时访问了多个http,也就是要建立多个TCP请求,假如串行来执行,那页面加载得多慢啊。? ?http如何使用TCP才能达到性能最优呢?
- 并行连接
- 多个TCP并行执行,不用等第一个完成关闭后,再创建第二个。? (当然了,不可能说有多少个http请求,就并行创建多少个TCP,那不得把服务器耗死! 比如浏览器实际上是对相同域名的http请求-同源请求,做了并行创建TCP数量的限制。 大部分浏览器是6个。)?
- 持久连接
- 管道化连接
- 基于持久连接来说,为了提升性能,一个TCP中让多个http事务不串行,在响应到达之前, 可以将多条请求放入队列。 当第一条请求通过网络流向另一端的服务器时, 第二条和第三条请求也可以开始发送了。
- 对管道化连接有几条限制:
- 必须按照请求相同的顺序返回报文。 因为http请求报文中没有序列号标签,一旦失序,就会造成错乱。? 因此,必须按序响应。但是,某个请求如果耗时太长,容易导致后面的请求堆积阻塞。
- 客户端必须准备好连接可能随时关闭。 出现这种情况时,客户端须能正确的应对并重新发送失败的请求。
- 只有幂等请求能管道化。? 幂等请求如GET,浏览器可以缓存get的url,每次都返回一样的结果,但是POST为写操作,每次可能创建新的资源。
对于上面介绍的http特性,都是在http的发展进程中不断优化的。 像什么持久连接,管道技术,都是HTTP1.1才有的。 在进入http2后,性能才有了飞跃。下面看看http2的特性。
6、http2新特性
HTTP 2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码 ,其中HTTP1.x的首部信息会被封装到Headers 帧,而我们的request body则封装到Data帧。
帧是数据传输的最小单位, 以二进制传输代替原本的明文传输。
- Connection-连接:HTTP 2.0 所有的通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。
- Stream-数据流:数据流以消息的形式发送,每个数据流包含多条消息。?每个流有唯一整数标识符,为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。
- Message-消息:消息由一或多个帧组成。??比如一系列DATA帧和一个HEADERS帧组成了一个完整的http请求消息。
- Frame-帧:每个帧首部都有一个流标识,代表属于哪个流,所以可以乱序发送,接收端重新组装。
对于http的性能来说,关键就在于低延迟而非高宽带。? 通常http请求的时间都很短,甚至是突发性的。 如果在这短时间内,还要花非大部分时间去创建和关闭TCP连接,性能肯定差。 反之,如果能让一个TCP连接长时间保持,所有http都共用它,那么创建TCP的性能问题就可以忽略不计。 http2.0就是很好的利用了这一点。
????????在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主
体」三部分组成。 一般body部分都会用gzip压缩后传输(或本身就是压缩过的二进制文件,如图片音频),但header部分都是纯文本传输的,现在很多页面中都会产生几十上百个请求,header部分也会占用很大部分的流量。
?
????????HTTP/2协议中定义了新的压缩方法
HPACK,它需要浏览器和服务端都支持HTTP2。 原理是两端维护一份相同的静态表 和 一份相同的动态表。?有了相同的表后,header传输时就可以传递索引值了,接收方根据索引值解析出内容。
- ? ? ? ? 静态表:?header中预定义好 不可更改的通用名称和value,有61个
? ? ? ? 动态表:在静态表中不存在的,比如自定义的值。 当然,第一次肯定需要明文发送,接收端才能维护,后续就可以传输索引了。
- 多路复用
- ?http1.1后虽然可以管道化连接,但是浏览器对同一个域名下的请求有数量限制,超过限制数目的请求会被阻塞。这也是为何一些站点会有多个静态资源CDN 域名的原因之一。
- http 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个
域名一个连接),http2连接可以承载数十或数百个流的复用,多路复用意
味着来自很多流的数据包能够混合在一起传输。当到达终点时, 再根据不同帧首部的流标识符重新连接将不同的数据流进行组装。
虽然多个流可以混在一起,但是同一个Stream中的Frame必须按顺序,因为Frame中的标识是流的id,只能区分出他们是属于哪个流。?
- 服务器推送
经过http2后,对TCP的利用已经达到了极限,所有的性能瓶颈几乎都集中在了TCP本身的特性上,所以http3中,已经开始用UDP替代TCP了。在未来http3肯定会成为主流。
二:https
https就是在http基础上加了一层安全层SSL/TLS(就是一种安全协议,SSL现在几乎没有使用了,都是用的TLS),作用只是让http传输更安全。 所以https和http1 或者 http2、http3没有关系,不管是哪个http的版本,只要配置了安全层,就是https(只不过http2及后续版本的http,默认都必须要配置安全层,也就是要以https为基础)。
?那https是如何安全的? 其实就是在客户端和服务器之间提供一座桥梁,帮助双方约定出一种加密算法传输密文,只有双方自己可以解析。 认识https前,先看看几个基本概念:
对称加密:
加密和解密都使用同一个密钥,常用算法:
- DES(Data Encryption Standard):数据加密标准(加密强度不够,能够暴力破解)
- 3DES:原理和DES几乎是一样的,只是使用3个密钥,对相同的数据执行三次加密,增强加密强度。(缺点:要维护3个密钥,大大增加了维护成本)
- AES(Advanced Encryption Standard):高级加密标准,用来替代原先的DES,目前美国国家安全局使用的,苹果的钥匙串访问采用的就AES加密。是现在公认的最安全的加密方式,是对称密钥加密中最流行的算法。 AES128和AES256主要区别是密钥长度不同(分别是128bits,256bits)、加密处理轮数不同(分别是10轮,14轮),后者强度高于前者。
优点:速度快、加密效率高。? ?
缺点:只有一个秘钥,不安全,?假如被拦截容易被破解。
非对称加密:
有一对秘钥,公钥和私钥。? ?公钥加密的需要私钥才能解,反过来一样。 常用算法:
RSA
、
DSA
、
ECDSA等。
优点:算法复杂难以破解,公钥存在客户端,私钥存在服务端,不用像对称加密那样传输秘钥,安全性提高很多。
缺点:效率没有对称加密的高,另外,公钥是公开的,也可能会泄露。
既然上面两种加密方式各有优缺点,那可以把两种方式结合。? 传输的业务数据用对称加密方式(效率高),但是呢,对称加密的秘钥,我们先用非对称加密的方式把它加密,保证此秘钥的安全。 如下图:
此时还有问题,假如客户端请求一开始就被黑客拦截了,?也就是说一直请求的是个假Server,它自己不知道,那还是有问题!如下图:
?要解决这个问题,那就还要验证两个东西:
1、传输的报文有没有被篡改过。? 解决:数字签名。
2、Server端的身份是否被伪装。? 解决:数字证书。
数字签名:确定消息是由发送方发出的,以及消息的完整性
?发送方:将消息通过hash算法生成消息摘要,?接着用私钥加密摘要得到数字签名,并把消息原文和数字签名一起发送。
接收方:通过公钥解密数字签名,得到摘要1(能解密说明消息确实是发送方发出来的,私钥和公钥能对上),再通过相同的hash算法对消息原文生成摘要-摘要2并与摘要1对比(只要摘要1和2相同,说明消息未被篡改)。
数字证书:证明消息发送方是合法的
数字证书就像一个身份证,是权威机构-认证中心 颁发给发送方(服务端)的,证明服务端是合法的。而权威证书颁发机构(Certificate Authority,简称CA)在全球的数量并不多,因此,一个合法的服务端必定要先从CA申请证书。
实际上,我们使用的证书分很多种类型,SSL证书只是其中的一种,用于加密HTTP协议,也就是HTTPS,TLS。如果一个web应用想要升级为https,需要购买证书。
流程如下:
- 服务器的运营人员向第三方机构CA(或者其代理机构)提交公钥、组织信息、域名等信息并申请认证;
- CA通过线上、线下等多种手段验证申请者提供信息的真实性。
- 如信息审核通过,CA会向申请者签发认证文件-证书。证书内容包含:申请者公钥、申请者的组织信息和个人信息、签发机构 的信息、有效时间、证书序列号等信息的明文,同时包含一个CA机构的数字签名。 其中签名的算法是使用散列函数计算上述的明文信息,得到的信息摘要,再采用 CA的私钥对信息摘要进行加密,也就是证书本身的签名;
- 客户端(如浏览器)和服务端进行https通信时,首先就要请求获取服务端的CA证书并验证。 而浏览器或操作系统等,都是提前内置了很多CA的证书,也就是具有CA的公钥信息(所以操作系统什么的,要用正版)。?这个时候,当请求到服务端的证书签名时,就能解密并验证证书内容是否合法。
- 如果证书合法,就能拿到服务器的CA证书的内容,也就是可以拿到服务端的公钥了(这样,公钥一定是安全的,服务器也一定是合法的)。 接下来,双方就可以按照上面介绍的,通过非对称加密和对称加密传输业务数据。
SSL
证书分类:
DV
(域名型
SSL
):个人站点
OV
(企业型
SSL
):企业官网
EV
(增强型
SSL
):对安全需求更强的企业官网、电商、互联网金融网站
三:https升级
介绍完https后,如何把http升级为https? 首先先申请CA证书,然后在服务端配置使用https即可。 流程如下:
- 申请证书:
- 下载证书:
- 购买成功后,登录阿里云控制台下载即可。 解压后得到两个文件:证书文件和秘钥文件
- Nginx配置https:
- 保存并加载配置:
- cd /usr/local/nginx/sbin? ? ? ???
-
./nginx
-s
reload?
配置完成后,访问一下域名,就可以看到域名地址栏加上了一把锁。?
四:https性能优化
|