1. 从一个HTTP请求来看网络的分层
- 众所周知,我们的网络是非常复杂的,那么我们便由简及繁介绍下网络
1.1 复杂的网络
- 由上图我们可以看到,我们为了简化网络的复杂度,网络通信的不同方面被分解成多层次结构,
每一层只与紧挨着的上层或者下层进行交互
,将网络分层,这样就可以修改,甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层。
1.2 OSI与TCP/IP的网络模型
- OSI:开放系统互联参考模型
- TCP/IP协议族:对OSI模型的一个简化,将表示层和会话层合并到应用层中
1.3 一个HTTP请求的分层解析流程
- 现在有一个服务器部署了一个静态页面,通过nginx部署在公网上面
- 在浏览器中输入域名http://www.domian.com
- 首先我们浏览器会先进行域名解析,然后看浏览器中是否有对应DNS的缓存,如果有就直接拿到服务端的IP地址,如果没有就去本地的host文件中取,如果本地host也没有配置,就会发起DNS的请求,用来获取服务器对应的IP地址。
- 应用端会构建一个DNS的请求报文,应用层会调用传输层的一个接口,因为DNS是使用UDP来进行数据的传输,所以在传输层我们使用的是UDP相关的协议,所以加上UDP的请求头传给网络层,网络层在上一个请求报文的基础上加一个IP的请求头
- 网络层的ARP协议会将IP地址转换成一个MAC地址
- 网络层拿到数据加上对应的报头之后会交给数据链路层
- 链路层会加上对应信息,传给物理层。
- 物理层一般是与路由器进行连接。路由器一般是有三层,先过物理层,再过数据链路层,再到网络层。
- 然后发到供应商的路由器中,如果运营商自己配置了DNS服务器,就直接取出对应的IP信息,然后原路返回
- 逐一解析进行还原,这时候,我们拿到了HTTP的请求,这时候我们就可以以HTTP的请求发送
- 应用层是Http,传输层是TCP,然后各自加请求头,依次类推继续向下
为什么我们会进行域名的解析呢?
- 这是因为我们的客户端和服务端在进行数据交互的时候是不认域名的,只认ip地址,所以需要把域名解析。
总而言之,我们一层只能与紧挨着的一层通信,上层加上自己的协议头然后传给下面,解析的时候当前层也只是解析自己的协议头,相当于是洋葱一层一层剥,快递一层一层包。
2. HTTP协议
- HTTP是超文本传输协议,其是一种无状态的,以请求/应答的方式运行的协议,它使用可以扩展的语义和自描述消息格式,与基于网络的超文本信息系统灵活的互动。
无状态表示的是不会存储用户的信息
2.1 HTTP的报文格式
- HTTP协议的请求报文和响应报文的结构基本相同,由三大部分组成。
- 起始行:描述请求或者响应的基本信息
- 头部字段集合:使用key-value形式更详细的说明报文
- 消息正文:实际传输的数据,他不一定是纯文本,可以是图片,视频等二进制数据
2.2 请求行的报文格式
【请求方法】
- 如GET/HEAD/PUT/POST,表示对资源的操作。
【请求目标】
- 通常是一个URI,标记了请求方法要操作的资源
【版本号】
- 表示报文使用的HTTP协议版本
2.3 响应行报文格式
【版本号】
- 表示报文使用的HTTP协议版本
【状态码】
- 一个三位数,用代码的形式表示处理的结果,比如200是成功,500是服务器错误
【原因】
- 作为数字状态码补充,是更详细的解释文字,帮助人理解原因
2.4 HTTP头字段
- 头部字段是key-value的形式,key与value之间用“:”分割,最后用回车换行表示结束。
- 比如前后分离的时候经常遇到的要与后端写上传输数据的类型:“Content-type:application/json”,这里的key就是Conten-type,其value就是application/json。HTTP头字段非常的灵活,不仅可以使用标准里的Host,Connection等已经存在的头,还可以自己添加任意的自定义头,这就给HTTP协议带来了无限的扩展的可能性。
2.4.1 头字段的注意事项
- 字段名不区分大小写,字段里不允许出现空格,可以使用连字符“-”,但是我们不允许使用下划线“_”,有的服务器是不允许解析带有“ _ ”的头字段
- 字段名后面必须紧挨着“:”,不能有空格,但是:号后面的字段值前面可以有多个空格
- 字段的顺序是没有意义的,可以任意排列不影响语义
- 字段原则上是不允许重复的,即key是理论上不允许重复的,但是,如果这个字段本身的语义允许,比如Set-Cookie,还是可以有多个的。
2.5 常用头字段
- HTTP协议中有非常多的头字段,但是基本上可以分为四大类
- 请求字段:请求头中的字段,如Host,Referer
Referer是防止盗图等,可以看当前的链接的来源,做防盗链的。
-
响应字段:响应头中的头字段,如:Server
-
通用字段:在请求头和响应头里都可以出现,如Content-type,Connection
Content-type表示的是数据是以什么格式发送到服务端(在请求头中)或者数据以什么格式响应给客户端(响应头)
3. HTTP请求的完整过程
- 当用户在浏览器输入网址回车之后,网络协议都做了哪些工作呢?
- 首先干活的是浏览器应用程序,他要解析出URL中的对应的域名
- 根据域名获取对应的IP地址,我们首先从浏览器缓存中获取,如下可以查看浏览器缓存中的域名对应IP的解析
我们直接在浏览器中输入:
chorme://net-interbals/#events
通过这个可以查看到我们浏览器中缓存的域名对应的IP解析。
- 如果浏览器没有则从本机域名解析文件hosts(/etc/hosts)中查看,还没有则从LDNS,Rootserver域名服务器,国际顶级域名服务商的DNS的底层进行解析
- 拿到了IP之后,我们浏览器就可以发起与服务器的三次握手
- 握手建立成功之后,就开始组装http请求报文,发送报文
- 服务器收到请求报文之后开始,请求报文解析,生成响应数据,发送响应数据
- 浏览器收到响应之后,就开始渲染页面。
- 最后是TCP的四次挥手断开连接。
4. TCP协议
- TCP是面向连接的,可靠的,基于字节流的传输层的通信协议
4.1 特点
- 基于连接的,数据传输之前需要建立连接。
- 全双工的:双向传输,客户端和服务端可以互相写数据,并且都可以主动建立/关闭连接,但是我们为了方便,把主动的叫做客户端,被动的叫做服务端而已
- 字节流:不限制数据大小(文件如果过大会被切割 ),打包成报文段,保证有序接受,重复报文自动丢弃
- 流量缓冲:解决双方处理能力的不匹配
- 可靠的传输服务,保证可达,丢包的时候通过重发机制实现可靠性
- 拥塞控制:防止网络出现恶性拥塞
(1)source port:源端口,如果是发送端的话,源端口是随机生成的
(2)dest port:目的端口,一般就是发送到哪个服务器上的端口
(3)sequence number:序列号
(4)acknowledgment number:应答序列号
两个序列号保证了TCP的靠性传输
(5)SYN:表示的是建立连接的报文
(6)ACK:响应的报文
(7)FIN:关闭连接的报文
(8)receive window:当前服务器可以接受数据大小的窗口的值
(9)data:就是我们真实要发送的数据
4.2 TCP连接管理
- TCP连接:四元组【源地址,源端口,目的地址,目的端口】
- 确定连接:TCP三次握手
- 其三次握手就是主要做了下面的两件事情:
(1)同步通信双方初始序列号(ISN)
(2)协商TCP通信参数(MSS,窗口信息,指定校验和算法)
4.3 如何进行握手
连接状态的查看:
netstat -ntp -c 1
4.4 TCP的四次挥手
A:发送FIN数据包,代表A不再发送数据
B:收到请求,开始应答,避免了A重新发送FIN重试(应答机制)
B:处理完数据之后关闭,关闭连接,以及发送FIN请求
A:收到请求后发送ACK应答,B服务可以释放连接
重要
- TIME_WAIT这个状态的时候这里我们等待2MSL(一个报文来回的时间)后,再释放连接:
- 防止报文丢失(ACK j + 1),导致B重复发送FIN
- 防止滞留在网络中的报文,对新建立的连接造成数据扰乱。
4.5 字节流的协议
- TCP把应用交付的数据仅仅看成是一连串的无结构字节流,TCP并不知道字节流的含义,TCP并不知道字节流的含义,TCP并不关心应用程序一次将多大的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥堵的程度来决定一个报文段应该包含多少个字节。
MSS:Max Segment Size,默认是536byte实际数据
4.6 数据可靠性传输
停止等待协议
重试机制
- 重试机制分为
(1)ack报文丢失的重试
(2)请求报文丢失的重试
ack报文丢失
超时的时长通常是一个报文来回的时间
请求报文丢失
4.7 滑动窗口协议与累计确认(延时ack)
- 滑动窗口大小通过tcp三次握手和对端协商,且受网络状况影响
5. HTTPS协议
5.1 HTTPS
- 由于HTTP天生“明文”的特点,整个传输过程中完全透明,任何人都能够在链路中截获,修改或者伪造请求/响应报文,数据不具有可信性。因此就诞生了HTTPS的协议
- 使用HTTPS的时候,所有的HTTP请求和响应在发送到网络之前,都要进行加密
5.2 SSL/TLS
- SSL即安全套接层,1999年更名为TLS
5.2.1 摘要算法
- 摘要算法能够把任意长度的数据“压缩”成固定长度,而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。任意微小的数据差异,都可以生成完全不同的摘要。所以可以通过把明文信息的摘要和明文一起加密传输,数据传输到对方之后再进行解密,重新对数据进行摘要,再对比就能发现数据有没有被篡改,这样就保证了数据的完整性。
- 常用的摘要算法有md5,sha1,sha2等
5.3 加密算法
- 加密算法主要分为:
(1)对称密钥加密算法
(2)非对称密钥加密算法
5.3.1 对称密钥加密算法
- 编解码使用相同的密钥的算法
- 如:AES,RC4,ChaCha20
5.3.2 非对称密钥加密算法
- 他有两个密钥,一个叫做“公钥”,一个叫做“私钥”。
- 两个密钥是不同的,公钥可以公开给任何人使用,而私钥必须严格保密。
- 非对称加密可以解决“密钥交换”的问题
- 网站私密保管私钥,在网上任意发布公钥,你想要的登录网站只要用公钥加密就行了,密文只能由私钥持有者才能进行解密。而黑客因为没有私钥,所以就无法破解密文。
- 非对称密钥加密系统通常需要大量的数学运算,比较慢。如:DH,DSA,RSA,ECC
TLS里面使用的是混合加密的方式,即把对称加密和非对称加密结合起来,两者取长补短,既可以高效的加密解密,又能够安全的密钥交换。其大致流程如下:
- 通信开始的时候,使用非对称算法,如RSA,ECDHE先解决密钥交换的问题
- 用随机数产生对称算法使用的“会话密钥”,再用公钥加密,会话密钥很短,所以即便使用非对称加密算法也可以很快的完成加解密。
- 对方拿到密文之后用私钥解密,取出会话密钥。完成对称密钥的安全交换,后续就使用对称算法完成数据交换。
5.4 身份验证
- 数字证书组成:
(1)CA信息,公钥用户信息,公钥,权威机构的签名,有效期数字证书 - 有效期数字证书的作用
(1)通过数字证书向浏览器证明身份
(2)数字证书里面包含了公钥
5.4.1 数字证书的申请和验证
- 生成自己的公钥和私钥,服务器自己保留私钥
- 向CA机构提交公钥,公司,域名信息,等待认证
- CA机构通过线上,线下多种途径验证你提交信息的真实性,合法性
- 信息审核通过,CA机构则会向你签发认证的数字证书,包含了公钥,组织信息,CA信息,有效时间,证书序列号,同时生成一个签名;
- 签名步骤:hash(你用于申请证书所提交的明文信息) = 信息摘要;CA再使用私钥对摘要信息进行加密,密文就是证书的数字签名。
5.4.2 浏览器如何验证呢?
- 有了CA签名过的数字证书,当浏览器访问服务器的时候,服务器会返回数字证书给浏览器。浏览器收到证书后会对数字证书进行验证。
- 首先浏览器读取证书中相关的明文信息,采用CA签名时相同的hash函数计算得到信息摘要A,再利用对应的CA公钥解密数字签名数据得到信息摘要B,如果摘要A和摘要B一致,则确认证书合法。