前面文章介绍了 TCP 报文头部的格式,TCP 协议是一个面向连接的协议,所以在使用 TCP 协议之前需要先建立连接,而建立连接就需要先 握手,在握手的时候就会有 TCP 报文头部数据的传递,这篇文章介绍一下 TCP 连接的 三次握手,然后使用 tcpdump 抓包工具分析 三次握手是如何被建立的,然后使用 netstat 命令查看分析 TCP 状态。
1.TCP 三次握手的目的
- 同步 Sequence 序列号,初始化序列号 ISN(Initial Sequence Number)
- 交换 TCP 通讯参数,如 MSS、窗口比例因子、选择性确认、指定校验和算法
2.三次握手示意图
3.tcpdump抓包分析
以 curl www.baidu.com 为例,使用如下命令抓取 TCP 报文:
tcpdump host www.baidu.com -c 3 -S
Tips:其中 host www.baidu.com 表示使用 BFP 过滤语法抓取和 www.baidu.com 相关的报文数据,-c 3 表示抓取次数为 3,-S 表示 信息以绝对序列号替代相对序列号。
如下图所示:
Tips:图中窗口是 tcpdump 抓取报文窗口,可以另起一个窗口执行 curl www.baidu.com。
4.tcpdump报文关系示意图对应
- 第一次:SYN
18:33:27.289687 IP localhost.localdomain.33952 > localhost.http: Flags [S], seq 1108648416, win 29200, options [mss 1460,sackOK,TS val 3178219629 ecr 0,nop,wscale 7], length 0
Tips:其中 seq 的值为 1108648416。
- 第二次:SYN/ACK
18:33:27.317960 IP localhost.http > localhost.localdomain.33952: Flags [S.], seq 737377256, ack 1108648417, win 64240, options [mss 1460], length 0
Tips:其中 seq 的值为 737377256,ack 的值为 1108648417,比第一次的 seq 大 1。
- 第三次:ACK
18:33:27.318021 IP localhost.localdomain.33952 > localhost.http: Flags [.], ack 737377257, win 29200, length 0
Tips:其中 ack 的值为 737377257,比第二次的 seq 大 1。
5.wireshark 抓包分析
以抓取浏览器访问 http://www.singwa666.com 网站发起的 HTTP/1.1 请求时,建立的 TCP 连接握手为例,使用 BPF 捕获过滤器语法 host www.singwa666.com 抓取报文,然后使用 显示过滤器 语法 tcp.stream eq 1过滤报文,如下图所示:
- 第一次:SYN
Tips:其中 Sequence Number(seq) 的值为 4150432755(f7 62 93 f3),FLAGS 的第 7 位置 1。
- 第二次:SYN/ACK
Tips:其中 Sequence Number(seq) 的值为 257427380(0f 58 07 b4),Acknowledgment number (ack) 的值为 4150432756(f7 62 93 f4),比第一次的 Sequence Number(seq) 大 1。
- 第三次:ACK
Tips:其中 Acknowledgment number (raw) 的值为 257427381(0f 58 07 b5),比第二次的 Sequence Number(seq) 大 1。
6.三次握手报文说明
6.1 第一次:SYN 报文说明
Tips:FLAGS 报文中的第 7 位置 1 表示 SYN 报文,此时 seq 序列号码有效,需要传递设置 序列号码(seq)。
6.2 第二次:SYN/ACK 报文说明
Tips:FLAGS 报文中的第 4 和 第 7 位置 1 表示 SYN/ACK 报文,此时 seq 和 ack序列号码有效,需要传递 序列号码(seq)和 确认号码(ack),此时确认号码(ack)是第上一次 seq 加 1。
6.3 第三次:ACK 报文说明
Tips:FLAGS 报文中的第 4 位置 1 表示 ACK 报文,此时 ack 序列号码有效,需要传递设置 确认号码(ack),此时 确认号码(ack)是第上一次 seq 加 1。
7.三次握手过程中的状态变迁
当我们做服务器端的开发时,服务器端同时处理成千上万的 TCP 连接时,需要理解 三次握手 中的状态变迁,对于定位复杂的网络问题非常有帮助。
7.1 三次流程中涉及到的五种状态及示意图
- CLOSED
- LISTEN
- SYN-SENT
- SYN-RECEIVED
- ESTABLISHED
Tips:TCB 的意思是 Transmission Control Block,保存连接使用的源端口、目的端口、目的 IP、序号、应答序号、对方窗口大小、己方窗口大小、TCP 状态、TCP 输入/输出队列、应用层输出队列、TCP 的重传有关变量等。
7.2 netstat 命令参数介绍
- interval:重新显示选定的统计信息,各个显示间暂停的间隔秒数
- -a:显示所有连接和监听端口
- -n:以数字形式(如IP地址)显示地址和端口号
- -r:显示路由表
- -s:显示每个协议的统计信息
- -o(Widnows):显示拥有的每个连接关联的进程
ID
- -b(Windows)/-p(Linux):显示对应的可执行程序名字
7.3 服务端查看 TCP 状态变迁
下面在服务器端使用如下命令:
netstat -anp
Tips:其中 -anp 的 a 所有的连接,n 表示以数字的形式,p 表示显示进程号。
Tips:一般很难观察到 SYN-SENT 状态,有一种 ACK 攻击就是攻击者构造一个 SYN 帧,却不返回 ACK 帧,这样会让服务器大量的连接都处于 SYN-RECEIVED 状态。