You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何模拟ICMP Type 3 Code 4(需要分片但已设置不分片)场景?

如何模拟ICMP Type 3 Code 4(需要分片但已设置不分片)场景?

这事儿我太懂了!你现在的困惑我完全能get——按道理发一个大于路径MTU且带DF(不分片)位的包,应该收到ICMP 3/4错误,但在AWS的两个子网实例上却没触发。其实这是AWS VPC的默认特性在搞鬼:VPC子网之间的内部路由器默认MTU就是9001,和你的实例A的MTU完全一致,数据包在传输路上根本没碰到MTU更小的节点,自然不会触发错误。至于实例B的MTU设成1500,那是接收端的配置,Linux内核接收时其实能扛住比自身MTU大的包(只要内存够),所以也不会返回ICMP错误。

下面给你两个亲测有效的模拟方案,随便选一个都能搞定:

方案一:加个MTU更小的中间路由器(最贴近真实场景)

这是最直观的方法,相当于在两个实例之间人为加了个“瓶颈”节点:

    1. 先启动第三个Linux实例C,把它当中间路由器用。第一步先开启IP转发功能:
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    1. 给实例C的网卡改MTU,设成一个比9001小的值,比如1400(如果C有多个网卡,要分别设置连接A和B的那两个网卡):
    ip link set dev eth0 mtu 1400
    
    1. 回到实例A,加一条静态路由,让发往B的流量必须经过C的内网IP:
    ip route add <B的内网IP> via <C的内网IP> dev <A的网卡名,比如eth0>
    
    1. 现在再执行你原来的ping命令:
    ping <B的内网IP> -M dont -s 9001
    

这时候中间路由器C的MTU只有1400,你的数据包9001字节还设了DF位,C既不能分片又没法完整转发,只能返回你要的ICMP Type 3 Code 4错误啦!

小提醒:别忘了在AWS的安全组和NACL里放开ICMP Type 3 Code 4的入站/出站权限,不然这个错误包可能被安全规则拦下来,你就收不到了。

方案二:用tc流量控制模拟瓶颈(不用额外实例)

要是不想多开实例费钱,就在实例A上用tc工具整个虚拟瓶颈:

    1. 先装tc工具(大部分Linux发行版默认有,没有的话就装):
    apt install iproute2  # Debian/Ubuntu系
    # 或者 yum install iproute2  # RHEL/CentOS系
    
    1. 给实例A的网卡加流量控制规则,把发往B的包的MTU限制在1400:
    # 先清掉旧规则(避免冲突)
    tc qdisc del dev eth0 root 2>/dev/null
    # 建根队列
    tc qdisc add dev eth0 root handle 1: htb
    # 加一个分类,限速(这里设1000mbit只是占位,重点是后面的MTU限制)
    tc class add dev eth0 parent 1: classid 1:1 htb rate 1000mbit
    # 过滤出发往B的流量,走上面的分类
    tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst <B的内网IP> flowid 1:1
    # 最后加MTU限制,超过就触发错误
    tc qdisc add dev eth0 parent 1:1 handle 10: netem mtu 1400
    
    1. 现在再跑你的ping命令,就能成功触发ICMP 3/4错误了。

这个方案不用额外实例,但tc的配置稍微绕一点,适合想省资源的情况。

备注:内容来源于stack exchange,提问作者Azize

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 08:58:20