XYCOVO CONSOLE KURISU · WEB 渗透 / AI 辅助攻防 ONLINE
#031 · 2024-04-20✓ PASS

TCP 三次握手

TCP 三次握手与四次断开详解,分析 TCP 连接建立与释放过程、状态变迁及 SYN Flood 防御机制。
csdn网络实验tcpipAUTHOR: KURISU

TCP 协议概述

TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议。在数据传输之前必须先通过三次握手建立连接,传输结束后通过四次挥手释放连接。

TCP 报文段关键字段

字段位数作用
序列号(Seq)32标识本段数据的第一个字节的序号
确认号(Ack)32期望收到对方下一个段的序列号
SYN1同步标志,用于建立连接
ACK1确认标志,确认号有效
FIN1结束标志,发送方已无数据
RST1复位标志,异常终止连接

三次握手(连接建立)

客户端                                         服务端
  |                                               |
  | —— [SYN]   Seq=x, Ack=0 ——→                   |  第一次
  | CLOSED → SYN-SENT                            |  LISTEN → SYN-RCVD
  |                                               |
  | ←—— [SYN+ACK] Seq=y, Ack=x+1 ——              |  第二次
  | SYN-SENT → ESTABLISHED                        |
  |                                               |
  | —— [ACK]   Seq=x+1, Ack=y+1 ——→              |  第三次
  |                                               |  SYN-RCVD → ESTABLISHED

第一次(SYN):客户端发送 SYN=1,随机初始序列号 Seq=x,进入 SYN-SENT

第二次(SYN+ACK):服务端分配缓冲区,回复 SYN=1, ACK=1, Seq=y, Ack=x+1,进入 SYN-RCVD

第三次(ACK):客户端回复 ACK=1, Seq=x+1, Ack=y+1,进入 ESTABLISHED。服务端收到后也进入 ESTABLISHED第三次握手可以携带数据

为什么不是两次? 两次握手只能验证客户端发送和服务端接收。第三次让服务端确认自己的发送能力和客户端的接收能力,同时防止过期 SYN 导致服务端误开连接。


四次挥手(连接释放)

TCP 全双工,每个方向必须独立关闭:

客户端(主动关闭)                              服务端(被动关闭)
  ESTABLISHED                                     ESTABLISHED
      |                                                |
      | —— [FIN]   Seq=u, Ack=v ——→                   |  第一次
      | → FIN-WAIT-1                                  |  → CLOSE-WAIT
      |                                                |
      | ←—— [ACK]   Seq=v, Ack=u+1 ——                |  第二次
      | → FIN-WAIT-2                                   |
      |                                                |
      | ←—— [FIN+ACK] Seq=w, Ack=u+1 ——              |  第三次
      |                                                |  → LAST-ACK
      |                                                |
      | —— [ACK]   Seq=u+1, Ack=w+1 ——→              |  第四次
      | → TIME-WAIT (等 2MSL ≈ 60s)                    |  → CLOSED
      | → CLOSED                                       |

第一次(FIN):客户端发 FIN=1,表示”我没数据了”,进入 FIN-WAIT-1

第二次(ACK):服务端确认收到 FIN,进入 CLOSE-WAIT。客户端进入 FIN-WAIT-2

第三次(FIN+ACK):服务端发完剩余数据后,发 FIN=1,进入 LAST-ACK

第四次(ACK):客户端确认后进入 TIME-WAIT,等待 2MSL 后关闭。

TIME-WAIT 为何等 2MSL? (1) 确保最后 ACK 能被服务端收到;(2) 让旧连接报文完全消失,避免干扰新连接。


状态变迁汇总

阶段客户端状态服务端状态
初始CLOSEDLISTEN
握手完成ESTABLISHEDESTABLISHED
主动关闭FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT → CLOSED-
被动关闭-CLOSE-WAIT → LAST-ACK → CLOSED

标志位速查

阶段SYNACKFIN
握手-1100
握手-2110
握手-3010
挥手-1001
挥手-2010
挥手-3011
挥手-4010

攻击原理

SYN Flood 是典型的 DoS 攻击:攻击者伪造大量不存在的 IP 地址,向服务端发送 SYN 包。服务端收到后为每个 SYN 分配资源(TCB,传输控制块)并回复 SYN+ACK,进入 SYN-RCVD 状态等待 ACK。由于源 IP 是伪造的,ACK 永远不会到达,半连接队列被占满,导致正常用户无法建立连接。

攻击者                      服务端
  |  —— SYN (伪造IP-A) ——→   |  分配TCB → SYN-RCVD
  |  —— SYN (伪造IP-B) ——→   |  分配TCB → SYN-RCVD
  |  —— SYN (伪造IP-C) ——→   |  分配TCB → SYN-RCVD
  |       ... (大量) ...       |  半连接队列满!
  |                            |
正常用户 —— SYN ——→            |  ❌ 丢弃,无法响应

SYN Cookie 的核心思想:收到 SYN 时不分配资源,而是将连接信息编码到序列号中返还给客户端,只有收到合法 ACK 时才分配资源。

具体流程:

  1. 服务端收到 SYN,不分配 TCB
  2. 服务端计算 cookie = hash(源IP, 源端口, 目的IP, 目的端口, 时间戳, 密钥)
  3. 将 cookie 作为初始序列号 Seq=y 在 SYN+ACK 中返回
  4. 如果客户端是真实的,会回复 ACK, Ack=y+1;攻击者(伪造 IP)收不到 SYN+ACK,不会回复
  5. 服务端验证收到的 Ack-1 是否等于 hash(源IP, 源端口, 目的IP, 目的端口, 时间戳, 密钥)
  6. 验证通过才分配 TCB 并建立连接

SYN Cookie 是 Linux 内核的默认防御策略。当半连接队列超过阈值时自动启用,无需手动配置。

← #030 RHCSA 实验笔记…#032 NAT 实验… →