1. 这不是“刷题”,而是网络协议的临床诊断现场
很多人看到《计算机网络(三十二):习题解析》这个标题,第一反应是:“哦,又一套课后题答案”。但在我带过十几届网络课程、参与过多个中小规模网络系统交付项目的实际经验里,真正卡住工程师的,从来不是“会不会背OSI七层”,而是当一个HTTP请求在测试环境里超时、当Wireshark抓到一串重复的TCP重传包、当某台交换机端口突然持续闪烁却无流量转发——你得立刻判断:这是物理层的线缆接触不良?数据链路层的MAC地址表溢出?还是传输层的拥塞控制算法在特定RTT下触发了非预期退避?习题不是考卷上的符号游戏,它是把真实网络故障压缩成可推演、可验证、可复现的病理切片。本篇不提供标准答案,而是还原一个资深网络从业者面对典型习题时的完整思维链:从题目字面拆解协议字段含义,到结合RFC原文确认行为边界,再到用真实抓包数据反向验证逻辑,最后落到生产环境里同类问题的排查路径。关键词如“TCP三次握手”“IP分片”“ARP缓存”“ICMP重定向”等,不是记忆点,而是故障树上的关键分支节点。适合两类人:一是正在啃《计算机网络:自顶向下方法》或类似教材的学生,需要把抽象描述和真实报文对应起来;二是刚接手网络运维工作的初级工程师,手头有设备、有流量、有压力,但缺一套把教科书知识翻译成命令行动作的映射手册。下面这道题,就是我们今天的“首例病历”。
2. 题干解剖:一道关于IP分片与重组的“陷阱题”实录
题目原文(模拟某高校期末试卷第5题):
主机A向主机B发送一个总长度为3000字节的IP数据报(含20字节IP首部),链路MTU为1500字节。假设该数据报在路由器R处被分片,且所有分片均成功到达主机B。请回答:
(1)主机B收到的分片数量是多少?
(2)各分片的MF标志位、片偏移值(以8字节为单位)分别是多少?
(3)若主机B收到的第一个分片丢失,其余分片均到达,主机B将如何处理?
这道题表面看是计算题,但背后藏着三个极易被忽略的底层机制:IP分片的不可逆性、重组超时的静默丢弃、以及接收端对不完整分片集的零响应策略。我们逐层剥开。
2.1 分片数量计算:为什么不是简单除法?
常规思路是:总数据长度 = 3000 - 20 = 2980 字节;每个分片最大载荷 = 1500 - 20 = 1480 字节;2980 ÷ 1480 ≈ 2.01 → 所以是3个分片?错。这个算法忽略了IP分片的核心约束:片偏移值必须是8字节的整数倍,且每个分片的载荷长度也必须是8字节的整数倍(因为偏移值以8字节为单位)。这是RFC 791明确定义的,目的是简化重组逻辑——接收端只需将偏移值乘以8,就能得到该分片在原始数据中的起始字节位置。
所以正确计算步骤是:
- 有效载荷长度 = 3000 - 20 = 2980 字节;
- 每个分片最大有效载荷 = 1500 - 20 = 1480 字节;
- 但1480 ÷ 8 = 185,是整数,符合要求;
- 第一片载荷 = 1480 字节(偏移0);
- 剩余载荷 = 2980 - 1480 = 1500 字节;
- 第二片载荷 = min(1480, 1500) = 1480 字节?不行,1500 - 1480 = 20字节剩余,但20不能被8整除(20÷8=2.5),违反偏移对齐规则;
- 因此第二片必须载荷 ≤ 1480 且使剩余部分能被8整除。尝试1472字节(1472÷8=184):剩余1500-1472=28字节,28÷8=3.5,仍不行;尝试1464字节(1464÷8=183):剩余1500-1464=36,36÷8=4.5,不行;继续试… 直到1456字节(1456÷8=182):剩余1500-1456=44,44÷8=5.5;再试1448(1448÷8=181):剩余52,52÷8=6.5;终于,1440字节(1440÷8=180):剩余1500-1440=60,60÷8=7.5 —— 还是不行。等等,这个思路错了。
更高效的方法是:直接按“最大可能载荷且满足8字节对齐”来分配。标准做法是:前N-1个分片载荷取最大值,该值需满足:(MTU - IP首部长度) 向下取整到8的倍数。1500 - 20 = 1480,1480 ÷ 8 = 185,正好整除,所以前两片均可载荷1480字节。但1480 × 2 = 2960,总载荷2980,剩余20字节。20字节本身无法构成一个分片(因为分片首部20字节 + 数据20字节 = 40字节 < MTU 1500,但20字节数据长度不满足8字节对齐?不,20字节数据长度本身没有对齐要求,对齐要求的是“片偏移值”,而最后一个分片的偏移值由前面分片总长度决定)。我们重新梳理:
- 总数据长度:2980 字节
- 分片1:载荷 = 1480 字节 → 占用原始数据 [0, 1479] → 片偏移 = 0
- 剩余数据:2980 - 1480 = 1500 字节
- 分片2:载荷 = 1480 字节?但1500 - 1480 = 20,20字节可以作为第三片的数据。此时分片2的片偏移 = 1480 ÷ 8 = 185;分片3的片偏移 = (1480 + 1480) ÷ 8 = 2960 ÷ 8 = 370。但2960 > 2980,不可能。所以分片2载荷不能是1480。
正确计算:
- 分片1:载荷 = 1480 字节,偏移 = 0
- 已覆盖:0~1479(1480字节)
- 剩余:1480~2979(1500字节)
- 分片2:最大载荷需 ≤ 1500 且使剩余部分 ≥0。设分片2载荷为X,则分片3载荷为1500-X。X必须是8的倍数(因片偏移 = 1480/8 + X/8 必须是整数,而1480/8=185是整数,所以X/8必须是整数 → X是8的倍数)。同时,1500-X也必须 ≥0,且作为最后一片,其MF=0,无特殊对齐要求。所以X最大可取1496?1496÷8=187,是整数;1500-1496=4,即分片3载荷为4字节。但IP数据报最小数据长度是0(空数据报合法),4字节完全可行。然而,实际中路由器分片会尽量填满MTU,所以更常见的是取X=1480,但1480+1480=2960 > 2980,超了。因此,分片1载荷1480,分片2载荷应为2980-1480=1500?但1500字节数据 + 20字节首部 = 1520 > MTU 1500,非法。所以分片2载荷最大为1480,但1480+1480=2960,剩余20字节,分片3载荷20字节。20字节是允许的(RFC未禁止),且20÷8=2.5,但片偏移值只对前两个分片有意义,第三个分片的偏移值 = (1480+1480)/8 = 2960/8 = 370,是整数。所以分片数量是3个:1480 + 1480 + 20 = 2980。但1480+1480=2960,+20=2980,正确。分片1:1480字节,偏移0;分片2:1480字节,偏移1480/8=185;分片3:20字节,偏移(1480+1480)/8=2960/8=370。MF标志:分片1和2的MF=1(还有后续),分片3的MF=0。这就是标准答案。我当年第一次算也卡在这里,后来在实验室用Scapy构造了这个数据报,用tcpdump在接收端验证,确实如此。
2.2 MF标志与片偏移:Wireshark里的“时间戳”逻辑
MF(More Fragments)标志位和片偏移(Fragment Offset)共同构成了IP分片的“时空坐标系”。MF不是简单的“是否还有下一片”,而是重组引擎的启动开关:只要MF=1,接收端就必须等待下一个分片,否则不开始重组;只有收到MF=0的分片,才触发最终重组动作。片偏移则像磁盘的扇区号,告诉接收端:“这一片的数据,应该放在原始数据的第几个8字节块上”。
我们用真实Wireshark截图逻辑来说明(虽无图,但可描述):
- 分片1:
Flags: 0x2 (Don't Fragment: 0, More Fragments: 1),Fragment offset: 0 - 分片2:
Flags: 0x2,Fragment offset: 185(即185×8=1480字节处开始) - 分片3:
Flags: 0x0(MF=0),Fragment offset: 370(370×8=2960字节处开始)
这里的关键洞察是:片偏移值不是按分片顺序累加,而是按原始数据字节位置计算。分片2的偏移185,意味着它承载的数据在原始2980字节中的起始位置是第1480字节(索引1480),而非“第二个分片就该是185”。这解释了为什么分片3的偏移是370而不是185+185=370——它恰好是(1480+1480)/8。如果分片2载荷是1472字节,那么它的偏移仍是185,但分片3的偏移就会是(1480+1472)/8 = 2952/8 = 369。这个细节在调试分片丢失问题时至关重要:当你在Wireshark里看到一个分片的偏移值“跳变”(比如从185直接到372),基本可以断定中间有分片丢失或被篡改。
提示:在Linux下用
ping -s 1472 -M do(禁止分片)测试路径MTU时,1472是ICMP数据部分,加上8字节ICMP首部+20字节IP首部=1500,刚好填满。若用-s 1473,则总长1501,必然触发分片或返回"Message too long"错误。这是实测MTU最可靠的方法,比任何理论计算都直接。
2.3 第一分片丢失:为什么主机B“装作没看见”?
这是本题最具现实意义的一问。标准答案是:“主机B将丢弃所有已收到的分片,并不发送任何ICMP差错报文。” 但为什么?RFC 791规定,IP层对不完整的分片集不进行任何反馈。原因有三:
- 避免放大攻击:如果每收到一个孤立分片就发ICMP“超时”,攻击者可伪造海量分片,让接收端产生指数级ICMP响应,形成反射放大攻击;
- 状态维护成本:为每个未完成的分片集维护一个重组缓冲区和定时器,对路由器和主机都是资源消耗,尤其在高并发场景;
- 语义模糊性:一个分片丢失,可能是链路问题,也可能是上游路由器故意丢弃(如ACL策略),发送ICMP反而暴露网络拓扑。
所以,当你的应用层看到HTTP请求超时,Wireshark却只抓到分片2和3,第一反应不应该是“重传”,而是检查分片1是否在上游某个节点被过滤。我曾在某次CDN回源故障中遇到类似情况:边缘节点配置了严格的IP分片过滤规则,导致大文件上传的首分片被静默丢弃,后端服务日志显示“连接建立但无数据”,排查三天才发现是防火墙策略问题。习题里的“第一个分片丢失”,在现实中往往对应着最上游的策略型丢包,而非物理链路故障。
3. TCP三次握手:从SYN洪泛到TIME_WAIT的生存周期管理
题目原文(模拟某企业面试题):
客户端C与服务器S进行TCP连接。C发送SYN,S回复SYN-ACK,C再发送ACK。若C在发送ACK后立即崩溃,S将处于什么状态?S在此状态下会等待多久?若此时C重启并重发SYN,S将如何响应?
这道题直指TCP状态机的核心矛盾:连接是双向的,但状态维护是单向的。服务器S在收到SYN后进入SYN_RCVD状态,发送SYN-ACK后,若收到ACK,则进入ESTABLISHED;若ACK丢失,S会重传SYN-ACK,直到超时。但本题设定是ACK已发出、C崩溃,这意味着S已经收到了ACK,进入了ESTABLISHED状态。C崩溃后,S的连接状态是ESTABLISHED,但这是一个“幽灵连接”——它有socket、有缓冲区、有计时器,却永远等不到应用层数据。
3.1 ESTABLISHED状态的“心跳”机制:保活定时器(Keepalive)
TCP规范定义了保活机制(RFC 1122),但默认关闭。一旦启用,流程是:
- 连接空闲超过
tcp_keepalive_time(Linux默认7200秒,即2小时)后,启动保活探测; - 每隔
tcp_keepalive_intvl(默认75秒)发送一个ACK=0的探测包; - 连续
tcp_keepalive_probes(默认9次)无响应,则关闭连接。
所以,若S开启了keepalive,它会在2小时后开始探测,约11分钟(75×9)后判定C死亡,发送RST终止连接。但绝大多数Web服务默认关闭keepalive,因为HTTP/1.1的持久连接(Connection: keep-alive)已由应用层管理,TCP层保活反而增加无谓开销。因此,S的实际行为是:维持ESTABLISHED状态,占用一个socket、内存缓冲区、端口资源,直到应用层主动关闭或系统重启。这就是著名的“C10K问题”根源之一——大量半死连接耗尽服务器资源。
3.2 C重启后重发SYN:RST风暴与ISN随机化的防御价值
当C重启并用相同IP:Port重连,向S发送新SYN时,S的响应取决于其当前状态:
- 若S仍处于ESTABLISHED(即未超时),它会认为这是“非法序列号”,直接回复RST(Reset);
- 若S已超时关闭,它会正常处理SYN,进入SYN_RCVD。
但问题在于:C发送SYN时,其初始序列号(ISN)是随机生成的(RFC 793要求ISN每4微秒加1,现代系统用加密哈希)。S收到SYN后,会检查该ISN是否在自己当前窗口内。由于C刚重启,其ISN极大概率远小于S期望的序列号(S以为连接还在,期望的是上次ACK后的序号),因此S判定为“攻击”,回复RST。
这个RST对C来说是“惊喜”:C本想建新连接,却收到RST,于是立即放弃,重试时可能换端口或延迟。而S端,若C频繁重试,S会不断发送RST,形成“RST风暴”,加重CPU负担。这就是为什么生产环境的负载均衡器(如LVS、Nginx)必须配置net.ipv4.tcp_fin_timeout和net.ipv4.tcp_tw_reuse参数——它们不是优化性能,而是防止RST风暴压垮内核协议栈。我曾见过一个未调优的Nginx集群,在客户端大规模闪断后,ss -s显示tw(TIME_WAIT)连接数飙升至20万,netstat -s | grep "segments retransmited"每秒数百次,根本原因是RST响应来不及处理,堆积在发送队列。
3.3 TIME_WAIT状态:2MSL的“法律追溯期”
当C崩溃前,连接正常关闭(四次挥手),C发送FIN,S回复ACK,然后S发送FIN,C回复ACK。此时C进入TIME_WAIT状态,持续2倍MSL(Maximum Segment Lifetime,RFC 793定义为2分钟,Linux实现为60秒,故TIME_WAIT=60秒)。为什么是2MSL?
- 第一MSL:确保C发送的最后一个ACK能到达S。若丢失,S会重传FIN,C在TIME_WAIT中能收到并重发ACK;
- 第二MSL:确保网络中残留的旧连接报文(如迟到的FIN或数据)全部消失,避免与新连接混淆。
TIME_WAIT不是bug,而是TCP可靠性的基石。但它在高并发短连接场景(如HTTP API)下会耗尽本地端口(65535个)。解决方案不是禁用TIME_WAIT(net.ipv4.tcp_tw_recycle已被废弃且不安全),而是:
- 服务端使用长连接(HTTP/1.1 keep-alive,HTTP/2 multiplexing);
- 客户端复用连接池(如OkHttp、Apache HttpClient);
- 确需短连接时,调整
net.ipv4.ip_local_port_range扩大端口范围,或启用net.ipv4.tcp_tw_reuse(仅对客户端有效,且需net.ipv4.tcp_timestamps=1)。
注意:
tcp_tw_reuse并非“重用TIME_WAIT端口”,而是允许将处于TIME_WAIT的socket用于新的OUTBOUND连接(即客户端角色),前提是时间戳严格递增。它对INBOUND连接(服务端)无效。这是很多工程师混淆的点。
4. ARP协议:局域网里的“姓名查户口”与缓存污染实战
题目原文(模拟某网络认证考试题):
主机A(192.168.1.10)与主机B(192.168.1.20)在同一子网。A要向B发送数据,但A的ARP缓存中无B的MAC地址。请描述A的ARP请求过程,并分析:若此时有一台恶意主机C(192.168.1.30)向A发送伪造的ARP响应(声称B的IP对应C的MAC),A将如何响应?此攻击称为什么?
ARP(Address Resolution Protocol)是网络层与数据链路层的翻译官,它解决的问题极其朴素:“我知道你要找192.168.1.20,但我不知道它的‘门牌号’(MAC)是多少,得去街上喊一嗓子问问。” 这个“喊一嗓子”,就是ARP请求(ARP Request)。
4.1 ARP请求的“广播-单播”双阶段本质
ARP请求不是简单的“全网广播”,而是精确的二层广播+三层单播匹配:
- A构造ARP请求包:硬件类型=1(以太网),协议类型=0x0800(IPv4),硬件地址长度=6,协议地址长度=4,操作码=1(Request),源MAC=A的MAC,源IP=A的IP,目标MAC=00:00:00:00:00:00(未知),目标IP=B的IP;
- 此包以以太网广播帧(目的MAC=FF:FF:FF:FF:FF:FF)发送,确保同一物理网段所有设备都能收到;
- 每台设备收到后,检查“目标IP”字段是否与自己IP匹配。只有B会响应,A和其他设备(包括C)都会丢弃该请求包;
- B构造ARP响应:操作码=2(Reply),源MAC=B的MAC,源IP=B的IP,目标MAC=A的MAC,目标IP=A的IP;
- 此响应以单播帧(目的MAC=A的MAC)直接发给A,不广播。
这个设计精妙之处在于:广播只发生在请求阶段,响应是点对点的,极大减少了网络噪声。我在某高校机房部署监控系统时,曾因误将ARP请求包设置为“混杂模式捕获”,导致交换机端口流量激增,原因就是ARP请求本不该被大量复制。
4.2 ARP欺骗(ARP Spoofing):缓存更新的“无条件信任”漏洞
当恶意主机C发送伪造ARP响应(声称192.168.1.20的MAC是CC:CC:CC:CC:CC:CC)给A时,A的行为是:无条件更新ARP缓存。RFC 826明确规定,ARP缓存条目是“最新优先”,收到任何ARP响应,无论来源是否可信,都立即覆盖旧条目。这是为了应对合法的MAC地址变更(如服务器网卡更换),但成了安全软肋。
A更新缓存后,所有发往192.168.1.20的数据包,目的MAC都被设为CC:CC:CC:CC:CC:CC,即发给了C。C可选择:
- 窃听(Sniffing):将数据包转发给B(透明代理),同时复制一份给自己;
- 篡改(Man-in-the-Middle):修改数据包内容(如注入JS脚本)后再转发;
- 阻断(Denial of Service):收到包后不转发,导致A与B通信中断。
防御ARP欺骗的实践方案,绝不是“教用户别信ARP”,而是:
- 交换机层面:启用端口安全(Port Security)或动态ARP检测(DAI),后者要求所有ARP响应必须通过DHCP Snooping绑定表验证;
- 主机层面:静态ARP绑定(
arp -s 192.168.1.20 BB:BB:BB:BB:BB:BB),但管理成本高; - 网络架构层面:划分VLAN,缩小广播域,使C与A/B不在同一VLAN,物理隔离。
我曾协助某金融机构加固内网,发现其核心业务区与办公区共用一个VLAN,一台被黑的办公电脑即可ARP欺骗核心数据库服务器。整改方案是:用三层交换机划分为DB-VLAN和OFFICE-VLAN,DB-VLAN内启用DAI,OFFICE-VLAN出口部署基于NetFlow的异常ARP流量检测规则(如单台主机1分钟内发送ARP响应>100次即告警)。
4.3 ARP缓存老化:300秒的“健忘症”与手动刷新技巧
Linux系统ARP缓存默认老化时间为300秒(5分钟),超时后条目自动删除。这既是安全机制(限制欺骗影响时间),也是资源管理(避免缓存无限增长)。但有时你需要强制刷新:
ip neigh flush dev eth0:清空eth0接口所有ARP条目;arp -d 192.168.1.20:删除指定IP条目;arping -c 3 -I eth0 192.168.1.20:向目标IP发送3个ARP请求,强制更新缓存(即使已有条目,也会被新响应覆盖)。
一个关键经验:当遇到“能ping通IP但SSH连不上”的诡异问题,第一步不是查SSH服务,而是ip neigh show看ARP缓存。我曾处理过一起案例:某Docker容器网络异常,ping容器IP通,但curl超时。ip neigh show显示该IP的MAC是incomplete(不完整),意味着ARP请求已发,但无响应。最终定位是容器网络插件(Calico)的BGP路由未同步,导致ARP响应被丢弃。ARP缓存状态是网络连通性的第一道“健康快照”,比任何高层协议诊断都快。
5. ICMP重定向:路由器的“善意提醒”与现代网络的失效逻辑
题目原文(模拟某云网络架构师面试题):
主机A(192.168.1.10/24)默认网关为R1(192.168.1.1)。A要访问10.0.0.10,R1发现A与10.0.0.10在同一子网(R1直连10.0.0.0/24),于是向A发送ICMP重定向报文,建议A直接将10.0.0.10的流量发给R2(192.168.1.2)。请分析:A收到此报文后,是否会更新其路由表?现代操作系统对此类报文的默认处理策略是什么?
ICMP重定向(Type 5)是IP协议中一个充满理想主义色彩的设计:当路由器发现主机把本该直连的流量发给了自己,它会“好心提醒”主机:“嘿,你不用绕路,直接找隔壁老王(R2)就行!” 但这个“好心”在现代网络中,几乎成了安全隐患。
5.1 ICMP重定向的原始逻辑:优化局域网路由
RFC 792定义ICMP重定向的触发条件极为苛刻:
- 报文必须由入口接口和出口接口在同一子网的路由器发出;
- 被重定向的目标IP必须是主机路由(非网络路由),即目标是单个IP,而非整个网段;
- 发送者(R1)必须是报文的下一跳(即A的默认网关);
- 重定向的目标路由器(R2)必须与A在同一子网(即R2的IP在192.168.1.0/24内)。
满足以上,R1才会向A发送ICMP重定向,其中包含:
- 目标网络地址(10.0.0.10);
- 推荐的下一跳地址(192.168.1.2);
- 原始IP报文的前8字节(用于识别被重定向的流)。
A收到后,应在其本地路由表中添加一条主机路由:10.0.0.10 via 192.168.1.2 dev eth0,优先级高于默认路由。
5.2 现代操作系统的“免疫”策略:从默认开启到默认关闭
然而,ICMP重定向存在严重风险:
- 路由劫持:恶意主机冒充路由器发送伪造重定向,将所有流量导向自己;
- 拒绝服务:发送大量重定向报文,填满主机路由表,导致路由查找失败;
- 策略冲突:与企业防火墙、SD-WAN等策略路由系统冲突。
因此,主流操作系统已默认禁用ICMP重定向处理:
- Linux:
net.ipv4.conf.all.accept_redirects = 0(默认),net.ipv4.conf.eth0.accept_redirects = 0; - Windows:注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableICMPRedirect= 0(默认); - macOS:
sysctl net.inet.icmp.rediraccept = 0(默认)。
这意味着,即使A收到合法ICMP重定向,内核也会直接丢弃,不更新路由表。这不是“不支持”,而是“主动拒绝”——一种安全基线配置。在云环境中,这种策略更为严格。例如,AWS EC2实例的网络ACL和安全组默认阻止所有ICMP Type 5流量;阿里云VPC路由表不支持主机路由的动态学习,所有路由必须显式配置。
5.3 云原生网络下的替代方案:BGP与服务网格的“智能路由”
既然ICMP重定向失效,现代数据中心如何实现“最优路径”?答案是:用更可控、更可审计的协议替代。
- BGP(Border Gateway Protocol):在大型IDC中,服务器通过BGP与ToR(Top of Rack)交换机宣告自己的IP地址。ToR学习到后,直接下发主机路由到所有相关交换机,无需依赖终端主机的ARP或ICMP。这种方式路由收敛快、策略灵活、可监控;
- 服务网格(Service Mesh):在Kubernetes集群中,Envoy Sidecar代理接管所有进出流量。它通过xDS协议从控制平面(如Istio Pilot)获取实时服务发现和路由规则,根据负载、延迟、错误率动态选择后端Pod,完全绕过传统IP路由。
我参与过一个混合云项目,客户要求“跨云低延迟访问”,最初方案是用ICMP重定向引导流量,被安全团队一票否决。最终采用BGP+Anycast:在公有云和私有云的边界路由器上宣告同一Anycast IP(如203.0.113.100),BGP根据AS路径和MED值自动选择最优出口,延迟从200ms降至15ms,且全程路由可追踪、可审计。习题里的“路由器提醒”,在今天已进化为“全网协同决策”。
6. 实战复盘:一道综合题的故障树推演与抓包验证
题目原文(模拟某网络攻防演练赛题):
某公司内网,主机A(192.168.10.10)无法访问Web服务器S(192.168.20.20),但A能ping通S的IP。S的Web服务(端口80)在本地curl localhost正常。请列出可能的故障点,并说明每种情况下Wireshark抓包的特征。
这道题是典型的“网络分层诊断”训练。它逼迫你抛弃“ping通就没事”的惯性思维,用OSI模型一层层向上排查。我们构建一个故障树(Fault Tree),并标注每层对应的抓包证据。
6.1 故障树第一层:网络层可达性(IP层)
- 现象:A能ping通S → 证明IP层双向可达,ICMP Echo Request/Reply正常。
- 抓包特征:在A或S上抓包,能看到
ICMP type=8 code=0(Echo Request)和type=0 code=0(Echo Reply)成对出现,TTL值合理(如64或128),无超时。 - 排除项:物理链路中断、IP地址配置错误、子网掩码错误、默认网关缺失、ACL阻止IP协议。
- 遗留风险:ICMP可能被单独放行,而TCP被阻断。这是最常见的“假阳性”。
6.2 故障树第二层:传输层连通性(TCP层)
- 关键动作:在A上执行
telnet 192.168.20.20 80或nc -zv 192.168.20.20 80。 - 若连接失败:
- 抓包特征(在A上):
- 只看到
SYN包发出,无SYN-ACK返回 → 问题在S的防火墙(DROP)或S未监听80端口; - 看到
SYN发出,收到RST→ S的防火墙(REJECT)或S上无服务监听80端口(netstat -tuln | grep :80为空); - 看到
SYN发出,收到ICMP port unreachable→ S的防火墙(REJECT)且策略为ICMP反馈。
- 只看到
- 验证:在S上
tcpdump -i any port 80,若无SYN包到达,说明问题在中间设备(如ACL、安全组);若有SYN但无SYN
- 抓包特征(在A上):