ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

eNSP+Wireshark抓包实战:详解TCP三次握手与四次挥手

eNSP+Wireshark抓包实战:详解TCP三次握手与四次挥手 前几天带网络技术基础训练讲到TCP三次握手和四次挥手有学员问老师状态图翻来覆去就是SYN、ACK、FIN这几个词有没有办法自己动手看一眼真实线上跑的包长什么样这个问题正中下怀。我直接把eNSP拉出来搭了一个最简拓扑打开抓包让大家亲眼看了TCP连接从建立到释放的全部过程。今天这篇就把整个实验完整还原出来从拓扑设计、设备配置到三次握手和四次挥手的逐包拆解再到Wireshark过滤技巧和几个容易踩的坑一次讲透。如果你是刚开始接触TCP/IP协议栈或者刚学完网络基础想动手验证一下这篇文章很适合。它不要求你有真实网络设备只要一台普通电脑装好eNSP就能复现整个抓包过程。1. 为什么要用eNSP来观察TCP握手与挥手1.1 eNSP在做抓包实验上的优势eNSP是华为官方出的网络模拟器我拿它做实验很多年了到现在它依然是不少网络工程师入门时搭拓扑练手的第一工具。你不需要买真实的交换机路由器从机柜里搬几台设备连起来的工作在这里就是拖拽几个图标的事。更重要的是它自带和Wireshark的联动抓包能力设备接口上点一下就能把真实转发过程中的报文抓下来分析这对理解TCP三次握手和四次挥手特别有用。比起纯看教材上的状态迁移图用eNSP抓包你能直观看到每一个报文SYN标志位怎么置1序列号和确认号怎么递增FIN又是从哪个方向发出来的。这些细节靠背是背不住的但亲眼看过一遍很容易印在脑子里。而且它是模拟器做错了重启设备重抓一遍都很方便完全不需要担心把生产网络搞坏。1.2 整个实验的核心思路这个实验的总体思路其实很朴素准备一台客户端和一台服务器让两者建立一个TCP连接再主动断开在中间链路上把报文全部抓下来。麻烦点在于TCP本身是传输层协议需要有上层应用来触发它。我见过不少人拿ping去触发结果抓包一看全是ICMP半条TCP都没有这就是没想清楚TCP和ICMP的区别。ping走的是ICMP协议工作在网络层和TCP没有关系。要让TCP跑起来必须有依赖TCP的上层服务比如HTTP、FTP、Telnet。我选的是Telnet。原因很简单Telnet是文本交互协议登录和退出本身正好分别对应TCP连接的建立和释放一步到位。在eNSP里AR路由器很容易配置成Telnet服务器PC机自带Telnet客户端两边之间拉一根线就能开始实验。整个链路是PC1作为客户端AR1作为服务器PC执行telnet命令AR完成认证PC再输入quit退出全程抓包。2. 实验拓扑与前置配置2.1 拓扑与地址规划拓扑非常简单真正的“一台PC对一台路由器”。打开eNSP从左侧设备栏拖一台PC通常叫PC1和一台AR路由器AR1选AR3260或AR2220都行用线缆把PC1的网卡口和AR1的GigabitEthernet0/0/0口连起来。地址规划也按最小原则来PC1192.168.1.10/24AR1的GigabitEthernet0/0/0192.168.1.1/24说实话地址不特殊只要在同一个网段就行。在eNSP里PC的IP是直接在图形界面填的非常直观。双击PC1进到“基础配置”标签页把IPv4地址、掩码、网关填上。这里注意网关可以填AR1的接口地址192.168.1.1虽然直连场景下网关不是必须的但保持习惯填上没问题。2.2 路由器和PC的基础配置启动设备后先在AR1上配置接口地址和Telnet服务。用命令行进入系统视图配好接口IP然后开启Telnet登录认证AR1system-view [AR1]interface GigabitEthernet0/0/0 [AR1-GigabitEthernet0/0/0]ip address 192.168.1.1 255.255.255.0 [AR1-GigabitEthernet0/0/0]quit [AR1]aaa [AR1-aaa]local-user admin password cipher Admin123 [AR1-aaa]local-user admin privilege level 15 [AR1-aaa]local-user admin service-type telnet [AR1-aaa]quit [AR1]user-interface vty 0 4 [AR1-ui-vty0-4]authentication-mode aaa [AR1-ui-vty0-4]protocol inbound telnet这里有个容易忽略的细节VTY是虚拟终端线路用来接收远程登录连接。默认VTY线路有五条0到4这里把它们全部指定成Telnet协议并采用AAA认证。如果你漏掉protocol inbound telnet设备默认可能只允许SSH接入后面用PC的Telnet客户端去连就会失败而且失败原因还不直观排查起来很费劲。配置完之后把设备启动起来等设备状态灯从红色变成绿色。然后双击PC1进入命令行用一条ping先探活PC ping 192.168.1.1能ping通后TCP实验的前置条件就齐了。注意ping通说明网络通但它验证的是ICMP不是TCP后面抓包时会看到两者完全不同的报文形态。2.3 在eNSP里接上抓包工具这是整个实验最容易出错的一步很多人抓不到包就是在这里卡住的。eNSP抓包并不是在整个设备上抓也不是在整条链路上抓而是在你选中的某个接口上抓。我建议大家把抓包点放在AR1的GigabitEthernet0/0/0接口上因为PC1发的包最终都要从这里进来或出去抓到的内容最全。操作方式是先用鼠标选中AR1然后在接口区域右键点击GigabitEthernet0/0/0选择“数据抓包”等待eNSP自动拉起Wireshark。有的eNSP版本是选中设备后在工具栏点一下“抓包”按钮再点要抓包的接口效果一样。Wireshark起来之后先不要急着操作确认列表里已经开始实时捕获了再去PC1上敲命令。接下来让PC1去连Telnet服务器也就是在PC1命令行输入PC telnet 192.168.1.1然后输入用户名admin和密码Admin123。登录成功后命令行会变成路由器的系统提示符说明TCP连接已经建立并进入交互阶段。接着输入quit退出登录AR1quit回到PC提示符后立刻停止Wireshark抓包保存pcap文件。这个时候整个抓包里就包含了从建立连接到断开连接的全部TCP报文。3. 三次握手抓包拆解3.1 打开Wireshark找到第一段会话保存好抓包文件后先别急着乱翻。抓包里通常会有Telnet认证期间产生的一些交互内容也会有个别ARP报文我们要找的是TCP连接建立那一刻的连续三个包。最简单的方式是在Wireshark过滤器里输入tcp.port 23把显示范围缩小到Telnet服务端口的TCP报文。这时你会看到几个标志性的报文开头三个就是三次握手No.1PC1 - AR1SYNNo.2AR1 - PC1SYNACKNo.3PC1 - AR1ACK如果抓包文件里的Telnet交互夹杂了很多后续数据包可以用Wireshark的Follow TCP Stream功能来定位整段会话。在任意一个TCP报文上右键选择“追踪流 - TCP流”Wireshark会把同一TCP流的所有报文按顺序列出来分段非常清晰。接下来逐包看细节。3.2 第一个包客户端发出的SYN请求选中第一个SYN报文看中间面板的TCP协议头。关键字段有三个源端口是PC1上的随机大端口比如1026目的端口是23SYN标志位置1Sequence Number显示为0。这里有个重要概念要解释清楚Wireshark默认显示的是相对序列号为了让人好读它把连接建立时的初始序列号算作0。如果你想看真实传输的32位绝对序列号可以进到Wireshark的Protocol Preferences里把TCP页签下的Relative sequence numbers勾选去掉就能看到每次连接随机生成的那个大整数ISN。第一次握手的功能从应用角度看就是客户端告诉服务器我想和你建立TCP连接这是我的初始序列号。标志位区域里SYN变为高亮说明这个包的控制位是SYN没有ACK位。此时服务器收到这个包会在内核里把连接状态从LISTEN转成SYN_RCVD并等待回答。3.3 第二个包服务器返回SYNACK第二个报文方向反过来了AR1 - PC1。TCP头部里Flags区域的SYN和ACK两个位都置1所以叫SYNACK。同样它的Sequence Number是0这是AR1自己选择的初始序列号Acknowledgment Number是1。确认号1怎么来的服务器在确认号字段里填“客户端的ISN 1”含义是你刚才那个序号为0的SYN报文我已经收到了下次请你从序列号1开始给我发数据。可以说第二次握手同时干了两件事一是应答第一次握手二是携带服务器自己的初始序列号。这就解决了“既要回复又要同步ISN”的问题。其实这也是TCP比UDP复杂但可靠的核心原因之一一个报文里可以同时承载ACK和SYN两个含义后续每次交互都需要对序列号进行确认两边才能对齐字节流的位置。在做实验时你可以对比前后几个包的Window字段还能看到TCP窗口大小协商的过程不过在三次握手期间窗口值通常还只是双方默认参数真正要理解的是序列号的变化逻辑。3.4 第三个包客户端的ACK确认第三个包是PC1发出的ACK。这个包的Sequence Number是1Acknowledgment Number是1。如果理解了前两步这一步就很简单客户端收到了服务器的SYNACK于是确认服务器的初始序列号把自己的确认号设置成“服务器的ISN 1”并置ACK位不带SYN同时数据长度通常为0。到这一步客户端知道自己发出的SYN被接收了服务器知道自己发出的SYNACK被接收了双方的初始序列号互相确认完毕连接进入ESTABLISHED状态。Wireshark里在第三个ACK包之后紧接着往往就是Telnet发来的第一个数据包这也能从侧面印证连接已经建立。为了直观对比把三次握手的三个报文整理成一张表方向报文类型关键标志相对序列号相对确认号含义PC1 - AR1SYNSYN1seq0无请求建立连接同步客户端ISNAR1 - PC1SYNACKSYN1, ACK1seq0ack1确认客户端ISN同步服务器ISNPC1 - AR1ACKACK1seq1ack1确认服务器ISN连接建立完成在这个抓包里如果只看三次握手的三个包你会看到一个很规律的现象每一步的确认号都等于对方前一个报文里的序列号加对方报文承载的数据长度。这个规律在整条TCP交互里都成立是后续排查协议问题时最核心的计算方式。3.5 为什么必须是三次握手少一次会怎样很多初学者会问为什么不能只握两次手我用这个实验里能看到的现场来解释。假设网络中存在一个延迟很长的旧SYN报文它是在很久以前某次连接中发出的如果只有两次握手服务器收到这个迟到报文后就会立刻回复SYNACK并认为连接建立成功于是开始等待客户端发数据。但客户端压根没有发起这次连接也不会发任何数据服务器的资源就白等了。三次握手解决了这个问题客户端只有在确实发过SYN的情况下才会响应服务器的SYNACK。如果客户端根本没发过SYN收到迟到的SYNACK就不会回复第三个ACK服务器收不到最终的ACK也就不会建立连接并把半开连接回收掉。所以在做这个实验时第三个ACK绝不只是礼貌性确认它是防止历史连接误建立的关键一层保险。同时三次握手也让双方的初始序列号都收到了对方的确认。TCP是面向字节流的可靠传输双方必须知道对方从哪个字节开始编号否则后续按序重组、去重、确认都无法进行。这也是为什么TCP里面每次连接都要精心地交换一轮同步信息而UDP不需要的原因。4. 四次挥手抓包拆解4.1 主动断开连接前的准备接下来看连接关闭阶段。在Wireshark过滤器里保留tcp.port 23把显示拉到末尾会看到方向相反、标志位为FIN的几个报文。先把概念说清楚TCP是全双工通信数据既可以从A流向B也可以从B流向A因此断开连接时两个方向的传输通道必须分别关闭这就是为什么正常情况下会出现四次挥手。这次的实验里主动断开连接的是PC1因为我在PC端输入quit命令退出Telnet从逻辑上说就是客户端先提出“我要关闭这个连接了”。如果你改成在路由器上强制清理用户或者设备超时主动方就可能变成服务器抓到的FIN方向会反过来但流程结构是一样的不影响理解。4.2 第一个包主动方发送FIN第一个挥手报文是PC1 - AR1Flags区域FIN置1同时序列号等于PC1上一次发送数据的最后一个序列号Wireshark显示为一个空载荷的控制报文。这个FIN的实际语义是PC1这个方向的数据已经全部发送完了我不再向你方向发送数据请你确认。注意FIN并不代表PC1不再接收数据。TCP支持半关闭状态主动方发完FIN后还可以继续读取服务器方向发来的数据直到服务器也关闭自己那半边。很多人第一次看四次挥手会被“关闭”两个字误导以为一旦发FIN整条连接就废了其实不是。4.3 第二个包服务器的ACK应答第二个报文是AR1 - PC1ACK置位确认号比第一个FIN的序列号大1。这个ACK的作用很单纯服务器收到客户端的FIN确认这个方向的数据接收完毕于是回复一个确认。但此时服务器的TCP连接状态还没有彻底关掉。在标准状态机里服务器在收到客户端FIN并回复ACK后会从ESTABLISHED进入CLOSE_WAIT状态。它还可以继续往客户端方向发送数据因为服务器这一侧的发送通道还开着。这也是四次挥手中第二次和第三次必须分开发送的本质原因ACK只负责确认收到FIN而服务器可能还有数据要发必须等它发完才能发自己的FIN。如果应用层确实没有任何剩余数据服务器可以把ACK和FIN合并成一个包发出去就会出现三次挥手但Telnet这类交互服务里服务器通常还会先回一个正式的会话结束响应因此更多时候你看到的是四次。这里补充一个实际经验如果看到FIN之后反复出现服务器重发FIN多半是最后一个ACK丢了主动方处于TIME_WAIT期间会替它重发ACK。这个现场在真实网络排查里偶尔能碰到非常有辨识度。4.4 第三四个包服务器的FIN与客户端的最终确认第三个挥手报文是AR1 - PC1FIN和ACK同时置位说明服务器确认自己方向的数据也发完了请求彻底关闭连接。它的序列号是在自己最后一个数据包的序列号基础上递增的确认号不变继续等于客户端之前FIN的序列号加1。第四个报文是PC1 - AR1纯ACK确认号是服务器FIN的序列号加1。这个ACK发完之后主动方PC1就进入TIME_WAIT状态等待2MSL时间然后连接才彻底消失。从线路上的报文数来看这个TCP连接从建立到现在经历了SYN、SYNACK、ACK然后FIN、ACK、FIN、ACK完整闭环。同样把四次挥手整理成一张表方向报文类型关键标志含义PC1 - AR1FINFIN1客户端不再发送数据请求关闭AR1 - PC1ACKACK1服务器确认收到FIN进入CLOSE_WAITAR1 - PC1FINFIN1, ACK1服务器不再发送数据请求关闭PC1 - AR1ACKACK1客户端确认收到FIN连接释放你还可以用Wireshark的统计功能验证一下Statistics - Conversations - TCP页签能看到这条TCP流的总包数、总字节数以及TCP流的一些签名信息。把这个报文序列和书上的状态迁移图对照几乎是一一对应的。4.5 TIME_WAIT这个隐藏角色我带学员做实验时总有人盯着第四个ACK发完之后问连接是不是已经关掉了答案是应用层关掉了但TCP协议栈里还留着TIME_WAIT状态主动关闭方要等2MSL两倍最大报文段生存时间才真正释放这个连接五元组。TIME_WAIT存在有两个理由。第一个是保证最后一个ACK能可靠到达如果它丢失了服务器会重发FIN客户端在TIME_WAIT期间还能再补一个ACK避免服务器永远收不到最终确认。第二个是让这条连接上传送过的所有报文在网络中彻底消逝防止复用相同IP和端口的连接收到上一次连接的延迟数据出现数据串包。在eNSP抓包里看不到TIME_WAIT因为它不是线路上的报文而是主机协议栈的内部状态。不过有个办法可以侧面观察到AR1路由器上执行display tcp status能看到连接条目的状态。如果你的eNSP版本支持实验结束后立刻去看PC1发起的Telnet连接条目可能还挂在TIME_WAIT状态过一会儿再看就会消失。这个命令在真实华为设备上也通用排查连接异常时很实用。4.6 常见抓包中只有三个报文的情况实际抓包时你可能会遇到FIN、ACK、FIN、ACK里第二和第三个包合并成一个ACKFIN的情况也就是线路上一共只有三个报文就完成关闭。很多教材把它当成异常其实它是完全正常的优化前提是服务器在收到客户端FIN时确认自己方向上没有剩余的未发送数据于是顺手把自己的FIN也一起发出去了。那为什么Telnet实验里通常能看到四次而不是三次因为Telnet服务端收到quit命令后还会先回一条会话结束的响应文本然后再发FIN。也就是说服务器确实还有数据要发它不能立刻半关闭发送方向只能先回复ACK把数据发完再补发FIN。这也从侧面解释了四次挥手的完整语义所谓的“四次”是通用情况下应用层可能还有数据需要传输的保底流程而不是强制要求每次必须是四个独立报文。5. 实操避坑与Wireshark过滤技巧5.1 抓包看不到TCP流怎么办这是这个实验里被问得最多的问题。首先要确认抓包点是否选对。很多人习惯在PC上右键抓包但eNSP的PC设备有时抓包支持不如路由器接口稳定我更推荐在AR1的GigabitEthernet0/0/0接口上抓。其次是启动抓包和执行telnet的先后顺序一定要先让Wireshark开始抓包再去PC上敲telnet命令顺序反了就只能抓到连接后续的交互看不到握手的开场三包。还有一个容易踩的坑输入telnet命令后PC端会弹出登录交互提示如果你在交互过程中输错用户名或密码连接可能会反复尝试或强制关闭导致抓包里多出SYN重传的报文。这不算坏事反而能顺便看TCP的重传机制但如果只想看干净的握手建议在熟悉配置后争取一次成功。如果抓包里连一个TCP包都没有请先确认是不是用ping来触发。ping是ICMP不经过TCP抓包结果全是ICMP请求和应答自然看不到握手。5.2 用过滤器快速定位关键报文Wireshark过滤器建议记熟几个这些都是排查TCP协议问题的常用工具需求过滤器表达式只看Telnet端口的TCP报文tcp.port 23只看纯SYN报文tcp.flags.syn 1 and tcp.flags.ack 0只看SYNACK报文tcp.flags.syn 1 and tcp.flags.ack 1只看FIN报文tcp.flags.fin 1只看建立连接和释放连接的报文tcp.flags.syn 1 or tcp.flags.fin 1追踪单个完整TCP流右键任意TCP报文选择“追踪流 - TCP流”这些过滤器组合在排查TCP异常时非常实用。比如你只想看有没有SYN重传就用tcp.flags.syn 1把SYN全部筛出来数一下同一个序号出现了几次就能判断是否存在超时重传。在eNSP模拟环境里如果不额外添加丢包模拟通常看不到重传但学会这个思路后面对真实网络中的连接变慢问题就有切入点了。5.3 eNSP常见启动与抓包失败问题eNSP本身有些老毛病这里也一起说一下。安装eNSP时要求配套合适的Oracle VM VirtualBox版本不匹配会直接导致设备启动失败比如AR设备灯一直停在红色甚至报启动AR1失败、错误码40之类的问题。这个问题和抓包实验本身没有直接关系但它会卡住整个实验所以先处理干净再开始。处理思路一般是调整VirtualBox版本或者把eNSP和VirtualBox都卸载干净后按设备兼容版本重新安装。另外抓包时Wireshark弹不出来也是常见问题。eNSP调用的是本机安装的Wireshark如果版本不兼容或者安装路径里有中文有可能导致抓包时闪一下就没反应。解决办法是先单独安装一个Wireshark再在eNSP的设备配置里把抓包工具路径指定到正确位置。我在多台电脑上装过基本都靠这个方式解决。6. 从抓包回看TCP状态机个人心得6.1 状态机与抓包的对应很多人学TCP时觉得状态机是个抽象的表格但做完这次抓包你会发现状态机的每一步都能在线路上找到对应的报文。LISTEN阶段是服务器监听端口SYN_SENT是客户端发出第一个SYNSYN_RCVD是服务器收到SYN并等待ACKESTABLISHED是三次握手完成FIN_WAIT_1是主动方发出FINCLOSE_WAIT是服务器收到FIN并回复ACKFIN_WAIT_2是主动方等待服务器发FINLAST_ACK是服务器发完FIN等待最后确认TIME_WAIT是主动方发出最终ACK后等待2MSL。把这些状态和抓包报文一一对应之后TCP对初学者就不再是七个状态字母的组合游戏了而是一条有方向、有确认、有等待的传送带。这也是我坚持让学员亲手抓一次包的原因。状态图可以背但抓包看到报文的那一刻你是真的理解它为什么这样设计了。6.2 后续还可以做的扩展实验这个实验做完后别急着删除拓扑它还可以继续扩展。比如在同一台PC上再telnet一次观察新连接是不是又重新完成三次握手两次连接的源端口和初始序列号有什么差别或者用两台不同网段的PC同时访问同一台FTP服务器看服务器怎么管理并发连接再比如在eNSP里对链路设置丢包率观察TCP的SYN重传和超时机制这是生产网络上很难操作的危险实验在模拟器里却可以随便折腾。我个人建议你把抓包文件保存下来过几天再打开不看本文提示自己重新筛选、追踪流、数一遍报文。几次下来TCP握手挥手的包结构就像肌肉记忆一样印在脑子里比反复背什么“第三次握手能否合并”有用得多。实验本身不难难的是把每个字段都看明白这也正是网络工程师排查问题时最核心的基本功。
返回列表