本文将讲述DNS协议、DHCP协议、HTTP协议、Websocket协议。其中HTTP协议将以进化史的角度带你快速理解HTTP的发展与演化,同时深入分析HTTPS是如何设计的来解决网络安全问题。
应用层是面向用户的一层
FTP | HTTP | HTTPS | DNS | TELNET(远程登录协议) | SMTP(邮件传送协议) | POP3协议(邮局协议) |
---|---|---|---|---|---|---|
21 | 80 | 443 | 53 | 23 | 25 | 110 |
域名解析的顺序:
具体 DNS 查询的方式有两种
- | 图示 | 描述 |
---|---|---|
递归查询 | 如果请求者不知道所请求的内容,那么接收者将扮演请求者,发出有关请求,直到获得所需要的内容,然后将内容返回给最初的请求者。 | |
迭代查询 | 如果接收者 B 没有请求者 A 所需要的准确内容,接收者 B 将告诉请求者 A,如何去获得这个内容,但是自己并不去发出请求。 |
计算机中 DNS 记录在本地有两种缓存方式:浏览器缓存和操作系统缓存。
ipconfig
/displaydns
可以查看电脑中缓存的域名。我们有一台电脑, 在家的时候自动连接家里的wifi,在公司的时候自动连接公司wifi 并分配IP地址 这里就多亏了DHCP协议。
DHCP指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分配的IP地址,子网掩码,Gateway地址、DNS服务器地址等信息,并能够提升地址的使用率
获取IP的方式有两种
DHCP交互过程
什么是HTTP协议?
发展史
请求流程:
总的来说,当时的需求很简单,就是用来传输体积很小的 HTML 文件,所以 HTTP/0.9 的实现有以下三个特点。
1994 年底出现了拨号上网服务,同年网景又推出一款浏览器, 从此万维网就不局限于学术交流了,而是进入了高速的发展阶段。随之而来的是万维网联盟(W3C)和 HTTP工作组(HTTP-WG)的创建,它们致力于 HTML 的发展和 HTTP 的改进。
万维网的高速发展带来了很多新的需求,而 HTTP/0.9 已经不能适用新兴网络的发展,所以这时就需要一个新的协议来支撑新兴网络,这就是 HTTP/1.0 诞生的原因。
新的需求
为了解决新功能引入了请求头和响应头,它们都是以为 Key-Value 形式保存的,在 HTTP 发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。
具体的请求流程
HTTP/1.0 的方案是通过请求头和响应头来进行协商。
请求头
accept: text/html
期待服务器返回html类型的文件accept-encoding: gzip, deflate, br
期待服务器可以采用的压缩算法accept-Charset: ISO-8859-1,utf-8
期待服务器返回文件的具体编码accept-language: zh-CN,zh
告诉服务器它想要什么语言版本的页面响应头
content-encoding: br
content-type: text/html;
charset=UTF-8
除此之外还有一些问题要解决
随着技术的继续发展,需求也在不断迭代更新,很快 HTTP/1.0 也不能满足需求了,所以 HTTP/1.1 又在 HTTP/1.0 的基础之上做了大量的更新。
改进持久连接 HTTP/1.0 每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开TCP 连接三个阶段
为了解决这个问题,HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。
持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上Connection: close。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。
我们知道 HTTP/1.1 为网络效率做了大量的优化,最核心的有如下三种方式:
这些优化资源加载策略,也取得了一定的效果,但是HTTP1.1对带宽的利用率却并不理想 比如100M的带宽,实际下载速度12.5M/s 采用HTTP/1.1时,或许最大能使用到2.5M/S,很难将12.5M全部用满
主要有以下三个问题
队头阻塞
TCP的队头阻塞
HTTP1.1的队头阻塞
队头阻塞的因素很多,一个请求被阻塞5s,后续的每个请求都延迟了5s,这是很严重的问题。
如何解决HTTP1.1无法充分利用带宽的能力呢?
首先慢启动和TCP连接之间相互竞争带宽 是TCP本身机制所决定的,我们没有换掉TCP的能力, 而队头阻塞是http/1.1机制导致的,这个可以优化。
HTTP/2的思路是
HTTP2引入了二进制分帧层,
多路复用 流、消息、帧之间的关系
- 一个TCP连接包含多个流
- 数据流:双向通信的数据流,包含一条或者多条消息
- 消息: 对应http1.1中的请求或响应
- 数据帧:最小单位, 以二进制压缩格式存放HTTP/1中的内容,一个消息由一个或多个帧组成 注意: 消息在流中的必须有序, 在不同的流中可以无需
总结
虽然HTTP/2引入了二进制分帧层,但是语义与1.1依然一样的(可以将不支持2的代理服务器降级为1.1处理),复用TCP协议,推广起来会更轻松
如何理解HTTP/2解决队头阻塞
:method: GET
用2
表示就行了延伸:
listen 443 ssl http2;
Upgrade: h2c
中间设备僵化
- 我们知道互联网是由多个网络互联的网状结构,为了能够保障互联网的正常工作,我们 需要在互联网的各处搭建各种设备,这些设备就被称为中间设备。
- 这些中间设备有很多种类型,并且每种设备都有自己的目的,这些设备包括了路由器、防火墙、NAT、交换机等。它们通常依赖一些很少升级的软件,这些软件使用了大量的 TCP 特性,这些功能被设置之后就很少更新了。
- 所以,如果我们在客户端升级了 TCP 协议,但是当新协议的数据包经过这些中间设备时, 它们可能不理解包的内容,于是这些数据就会被丢弃掉。这就是中间设备僵化,它是阻碍 TCP 更新的一大障碍。
- 除了中间设备僵化外,操作系统也是导致 TCP 协议僵化的另外一个原因。因为 TCP 协议都是通过操作系统内核来实现的,应用程序只能使用不能修改。通常操作系统的更新都滞后于软件的更新,因此要想自由地更新内核中的 TCP 协议也是非常困难的。
为了解决上述三个问题, HTTP3 决定重塑 TCP功能(握手、拥塞控制、丢包重传机制)及HTTP2功能(多路复用)解决队头阻塞问题
拥塞控制方面,
握手方面: 将TCP握手与TLS握手合并减少了握手次数.
队头阻塞: 借鉴HTTP2的多路复用功能。
虽说这套协议解决了 HTTP/2 中因 TCP 而带来的问题,不过由于是改动了底层协议,所以 推广起来还会面临着巨大的挑战。
在学习HTTPS协议前需要先掌握加解密技术。
起初设计 HTTP 协议的目的很单纯,就是为了传输超文本文件,那时候也没有太强的加密传输的数据需求,所以 HTTP 一直保持着明文传输数据的特征。但这样的话,在传输过程中的每一个环节,数据都有可能被窃取或者篡改,这也意味着你和服务器之间还可能有个中间人,你们在通信过程中的一切内容都在中间人的掌握中,如下图:
为了解决中间人劫持网络问题就必须使用加密方案
在 TCP 和 HTTP 之间插入一个安全层
安全层有两个主要的职责:
由于client-random、server-random、协商的加密套件是明文, 再加上公开的合成密钥算法就可以合成密钥,进而伪造和篡改数据
虽然使用非对称加密能保证浏览器发送给服务器的数据是安全的了,但是服务器发送的消息依旧存在被黑客解密的情况,因为公钥是公开的。
另外还有一个更严重的问题是 非对称加密效率太低!
先利用非对称加密计算出密钥,然后使用对称加密通信,这样解决了传输效率问题
在DNS劫持的情况下,(伪造一个代理服务器作为中间人劫持),服务端发送的消息已经能被破解
数字证书简单说就是第三方公证人,它能证明服务器是否为真,杜绝DNS劫持问题
黑客能否合成这个pre-master呢? 如果黑客提前请求服务器,也会得到服务器的公钥,进而合成pre-master。
所以这里不是直接使用网站的公钥来合成pre-master,而是再产生一个随机数,加上之前的随机数合成pre-master,再使用这个公钥对这个随机数加密,由于黑客没有网站的私钥,所以无法合成pre-master,而网站服务器可能安全的合成pre-master,进而与客户端通信
参考资料
注意:CA机构也分层级,有一个证书信任链关系,这样就能新网站的就很方便了。
其他:
延伸:前面的内容知识为了快速理解HTTPS,完整的TLS协议要复杂很多,如下图,感兴趣的可以自行研究。
在 WebSocket 出现之前,如果我们想实现实时通信,比较常采用的方式是 Ajax 轮询,即在特定时间间隔(比如每秒)由浏览器发出请求,服务器返回最新的数据。这种方式有一些缺陷
定义:Websocket是基于TCP的一种新的应用层协议,它实现了浏览器与服务器的全双工通信,即允许服务器主动发送信息给客户端。因为,在Websocket中浏览器和服务器只需要完成一次握手,两者就直接创建持久性的连接,并进行全双工数据传输,客户端与服务器之间的数据交换变得更加简单。
如何建立连接
http# 请求头 Connection: Upgrade Upgrade: websocket Sec-Websocket-key: XXXXX # 服务端响应 HTTP/1.1 101 SwitchProtocals Connection: Upgrade Upgrade: websocket Sec-Websocket-Accept: YYY
Sec-Websocket-Accept
是由 Sec-Websocket-key
加密得到的
它有两个作用
1) 用于确保服务器有Websocket的能力
2)它提供基本防护(恶意链接、无效连接)
经过以上两步就切换到一个全新的协议 websocket
websocket 是二进制协议,一个字节可以存储更多信息。
利用HTTP完成握手有以下好处
如何交换数据?
readyState
美团一面面试题: 2023年10月18日
CORS是浏览器限制的是HTTP响应头,浏览器不把响应的数据给到JS,而Websocket握手响应头被忽略,所以CORS策略无效。
因此攻击者可以视图建立跨源WS连接并发送恶意数据或从订阅的通道接收数据(即使服务器不响应 CORS 标头,如果服务器支持 WebSocket 并发送 101 切换协议状态,也会建立 WebSocket 连接)。 这类似于跨站请求伪造 (CSRF)。因此服务器实现应验证升级请求上的 Origin 标头,以防止跨站点 WS 连接。
jsconst io = require("socket.io")(httpServer, {
allowRequest: (req, callback) => {
const isOriginValid = check(req);
callback(null, isOriginValid);
}
});
参考资料: websocket绕过SOP/CORS
Websocket 可以通过设置请求头中的 "Cookie" 字段来携带 cookie。代码实现取决于使用的编程语言和 websocket 库。例如,在 JavaScript 中,使用 WebSocket API 可以通过如下方式设置请求头并携带 cookie:
jsvar socket = new WebSocket('ws://example.com');
socket.onopen = function () {
socket.send('hello');
};
socket.setRequestHeader("Cookie", "cookiename=cookievalue");
注意:服务器必须允许 websocket 请求携带 cookie,否则请求将失败。
Websocket API 是 HTML5标准的一部分 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览器的应用程序中使用。 实际上,许多语言、框架和服务器都提供了 WebSocket 支持,例如:
不同的 socket框架 之间不能共用
参考资料:
websocket协议头部有个MaskKey,用来防止代理服务器的缓存污染攻击
它的原理是 强制浏览器执行以下方法:
本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!