HTTP/HTTPS/DNS/CA/TCP杂记
关于HTTP/HTTPS/DNS/CA等杂记
以下C(CLIENT-客户端) S(SERVER-服务端)
HTTP和HTTPS都是基于TCP
TCP三次握手
- C -(SYN 30000)-> S(C.HELLO)
- S -(SYN 30001-ACK 20000)->C(S.HELLO) 30001-1=30000
- C -(ACK-20001)->S(OK) 20001-1=20000
(TCP)什么是半连接队列和全连接队列?
半连接队列:S接收SYN后双方就处于半连接
全连接队列:S接收ACK后双方移入全连接队列
linux内核维护
双方处于等待第三阶段(ACK)为半连接成功established则转入全连接,如果C迟迟不发送ACK,则重传,重传时间指数增长,所以超过系统设定时间就丢弃半连接信息
第 2 次握手传回了 ACK,为什么还要传回 SYN?
服务端传回发送端所发送的 ACK 是为了告诉客户端:“我接收到的信息确实就是你所发送的信号了”,这表明从客户端到服务端的通信是正常的。回传 SYN 则是为了建立并确认从服务端到客户端的通信。了解到会通过加1减1来确认信息(当然不止这点,简单来讲)
在 TCP 三次握手过程中,第三次握手是可以携带数据的?
客户端发送完 ACK 确认包之后就进入 ESTABLISHED 状态了。也就是说,一旦完成了前两次握手,TCP 协议允许数据在第三次握手时开始传输.(怪不得在使用tcpdump进行分析时看到的第三步有些数据有长度[.]数据 )
如果第三次握手的 ACK 确认包丢失,但是客户端已经开始发送携带数据的包,那么服务端在收到这个携带数据的包时,如果该包中包含了 ACK 标记,服务端会将其视为有效的第三次握手确认。这样,连接就被认为是建立的,服务端会处理该数据包,并继续正常的数据传输流程。
为什么要四次挥手?
过程:
- C -(FIN-)->S
- S -(ACK-)->C
- S -(FIN-)->C
- C -(ACK-)->S
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
没有断开前都可以进行数据传输。
举个🌰 :A 和 B 打电话,通话即将结束后。第一次挥手:A 说“我没啥要说的了”第二次挥手:B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话第三次挥手:于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”第四次挥手:A 回答“知道了”,这样通话才算结束
为什么不能把服务端发送的 ACK 和 FIN 合并起来,变成三次挥手?
因为服务端收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务端到客户端的数据传送。
如果第二次挥手时服务端的 ACK 没有送达客户端,会怎样?
客户端没有收到 ACK 确认,会重新发送 FIN 请求。(Persistent)
为什么第四次挥手客户端需要等待 2MSL(Maximum Segment Lifetime报文段最长寿命)时间后才进入 CLOSED 状态?
第四次挥手时,客户端发送给服务端的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL,防止 Server 没有收到 ACK 而不断重发 FIN。MSL(Maximum Segment Lifetime) : 一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。
DNS基于UDP
DNS基于UDP主要是为了速度和轻量化,这与其核心需求高度匹配。
具体原因可归结为以下3点:
- 无连接 overhead 更低:UDP无需像TCP那样建立三次握手、维护连接状态,请求和响应可以直接传输,大幅减少了延迟,这对DNS这种“短平快”的查询(通常仅几百字节)至关重要。
- 满足DNS核心诉求:DNS查询通常是“一问一答”的简单交互,对可靠性要求可通过应用层机制弥补(如查询超时后重发),无需依赖TCP的重传、流量控制等复杂机制,避免了资源浪费。
- 服务器并发能力更强:UDP协议本身更简单,DNS服务器可同时处理更多并发查询,支持大规模网络访问。
不过需注意:当DNS响应数据量超过UDP最大报文长度(通常512字节,扩展后可达4096字节)时,会自动切换到TCP传输,以保证数据完整性。
DNS请求-部分
涉及OSI七层后续的细节待补充WAIT
发起DNS请求
根域名服务器(13 但是现在这13个ip里有很多服务器)
顶域名服务器cn,com等等
权威DNS
本地DNS(ISP-Internet-Server-Provider网络服务提供商)
迭代或者递归查询(向根,返回知道去顶,顶返回知道去权威,然后访问知道ip地址,完成一次DNS 这是迭代的)一般略过根,因为顶域名数量可数可记录,提高效率,降低根服务的压力。负载均衡
一个主机名可以有多个ip,这个我迷迷糊糊,我知道可以用ip addr(linux 关于ip的设置命令)为设备增加ip,是和这个差不多嘛?
A:不一样,这是两个完全不同的概念,核心区别在于“一个主机名对应多个IP”是DNS层面的映射关系,而“一个设备加多个IP”是操作系统/网络接口层面的配置。
- 一个主机名对应多个IP(DNS层面)
这本质是DNS服务器上的一条“多记录配置”,目的是实现负载均衡、故障转移等功能。
- 🌰 :访问 www.baidu.Com 时,DNS返回的可能是多个IP(比如180.101.49.11、180.101.49.12等),你的电脑会选其中一个连接。
- 特点:这些IP可能对应不同的物理/虚拟服务器(比如百度的多台Web服务器),也可能是同一台服务器的不同网卡IP,但核心是“DNS解析时返回多个目标IP”。
- 一个设备增加多个IP(操作系统/网卡层面)
这是给单台设备的网卡配置“附加IP”,让一个网卡同时拥有多个逻辑IP地址。
- 例子:用 ip addr add 192.168.1.100/24 dev eth0 给网卡eth0加第二个IP,此时这台设备可以通过192.168.1.10(原IP)和192.168.1.100(新IP)同时被访问。
- 特点:所有IP都属于同一台设备,只是给它分配了多个“网络身份”(比如一台服务器同时提供多个服务,用不同IP区分)。
简单类比
- 前者像“一个公司名(主机名)对应多个门牌号(IP),每个门牌号是不同的办公室(设备)”;
- 后者像“一个人(设备)有多个手机号(IP),都指向同一个人”。
“一个域名对应多个IP”,本质是DNS给一个“好记的名字”绑定了多个“服务器地址”,目的是分摊访问压力、避免单点故障、提升访问速度。
再提炼3个关键点:
-
层面不同:这是DNS服务器的配置,和单台设备本身有几个IP是两回事。
-
核心目的:实现负载均衡(分流不卡顿)、故障转移(坏了有备份)、就近访问(速度快)。
-
用户感知:用户只需要输入域名,不用管具体连哪个IP,系统会自动选最优的。
A表示IPV4
AAAA表示IPV6
CNAME的本质是“域名别名”,让多个域名可以指向同一个“主域名”,从而简化管理、灵活调整。
CA过程
- 证书验证仅在 TLS 握手阶段执行一次
当发起 HTTPS 请求时,客户端与服务器会先完成 TLS 握手,证书验证(解密签名、比对摘要等)是握手过程中的核心步骤。一旦握手成功、建立起加密连接,在 keep-alive 保持的长连接期间,双方直接使用握手阶段协商好的对称密钥进行数据加密传输,不再重复验证证书。 - 连接断开后需重新验证证书
当 keep-alive 超时、连接被主动关闭(如关闭浏览器标签页)或网络中断后,若再次发起 HTTPS 请求,需要重新建立 TLS 连接,此时会 再次执行完整的证书验证流程。
在发起HTTPS请求时会进行SSL/TLS,这时候会验证证书对吧,然后在keep-alive时间内都是正常的加密了,不用再进行证书验证了?然后断开后重新访问还需要验证码?
HTTPS生成预主密钥过程
Summary:C向S发起请求,包含加密算法等等,S接收后确认算法,并回复包括证书等响应信息。然后C通过本地信任链验证确认身份。C验证后使用算法生成预主密钥(类似于我随手捡到的独一无二的树叶),然后C通过S的公钥(非对称过程)加密后发给S,S用自己的私钥解码后双方就通过这个预主密钥进行对称加密通信。所以由此每次断开就需要重新生成预主密钥。
初始疑问:不理解 CA 证书认证过程,想知道服务器 S 发来的证书包含什么内容,是否是用服务器加密过的公钥的 HaSh 值。
解答:证书含服务器公钥、域名等信息及数字签名。签名由 CA 对上述信息计算 HaSh 摘要后,用 CA 私钥加密得到,非服务器加密的公钥 HaSh 值。客户端验证时,用 CA 公钥解密签名,再计算证书内容摘要比对。Hash不可逆的特性来确保信息不被篡改。
后续追问:询问客户端 C 是否要向 CA 请求服务器 S 的信息做比对。
解答:不用向 CA 额外请求。C 用本地预装的 CA 公钥解密签名得原始摘要,再自行对证书的明文部分(公钥、域名等)算 HaSh 得本地摘要,直接比对两个摘要验证可信性。
明确
- S传的不是“证书明文”,而是“证书 + 证书的CA签名”
S发送给C的证书包含两部分:
- 证书主体:S的公钥、域名、有效期等明文信息。
- CA签名:CA用自己的私钥,对“证书主体的HaSh摘要”加密后的结果(不是对证书明文加密)。
- C的验证步骤
C收到后,验证逻辑是 “两步HaSh比对”,而非直接解密摘要:
- 步骤1:C用本地信任的CA公钥,解密S发来的“CA签名”,得到一个“CA生成的摘要A”。
- 步骤2:C自己对证书里的“明文主体信息”做相同的HaSh运算,得到“本地生成的摘要B”。
- 步骤3:对比摘要A和摘要B,一致则证明证书未被篡改,且确实是该CA签发的,从而信任S的公钥。
为什么要这么设计?
- 用CA私钥签名,是为了防止“假证书”:只有CA才能用自己的私钥生成有效签名,其他人伪造不了(非对称加密的“签名防伪造”特性)。
- 先HaSh再签名,是为了效率:证书明文可能很长,直接用非对称加密签名耗时,而HaSh后得到固定长度的摘要(如256位),签名/验证速度更快。
“CA公钥验证”和“HaSh比对”的核心,补充“CA签名是对摘要加密”和“两步HaSh比对”后,就是完整的证书信任逻辑了。

浙公网安备 33010602011771号