本机 192.168.50.22 可以 ping 通 192.168.50.25,但 50.25 ping 不通本机。
两台机器明明在同一个 /24 网段里,问题却绕了一圈才显形:Clash TUN 改写了 macOS 路由,导致本机给 50.25 的 ICMP reply 没有直接发给 50.25,而是发给了网关 ImmortalWrt。
现象
网络环境:
1 | 本机: 192.168.50.22/24 |
本机地址看起来没问题:
1 | ifconfig en0 |
1 | inet 192.168.50.22 netmask 0xffffff00 broadcast 192.168.50.255 |
防火墙也不是主因:
1 | Firewall is disabled. (State = 0) |
真正反常的是路由。
第一处异常:同网段流量进了 TUN
查本机到 50.25 的路由:
1 | route -n get 192.168.50.25 |
最初看到的是:
1 | destination: 128.0.0.0 |
192.168.50.25 是同网段地址,正常应该走 en0 直连,不应该进 utun1024。
再看 Clash Verge / mihomo:
1 | tun: |
第一层原因很清楚:Clash TUN 的 auto-route 接管了不该接管的 LAN 路由。
第二处异常:排除 TUN 后仍然走网关
把 LAN 网段排除出去:
1 | route-exclude-address: |
此后 50.25 不再走 utun1024,但仍然不对:
1 | destination: default |
这表示回包会从 en0 出去,但二层目标会是网关,而不是 50.25。
同网段直连时,应该能 ARP 到对端:
1 | arp -n 192.168.50.25 |
异常时却是:
1 | 192.168.50.25 -- no entry |
到这里基本可以怀疑:本机缺少正常的 192.168.50.0/24 -> en0 直连路由。
关键证据:看二层 MAC
普通抓包只能说明本机收到了 request,也发出了 reply:
1 | sudo tcpdump -ni en0 'icmp and host 192.168.50.25' |
1 | 192.168.50.25 > 192.168.50.22: ICMP echo request |
但这还不够。它只说明三层 IP 是对的,没说明二层 MAC 发给了谁。
要看 MAC,加 -e:
1 | sudo tcpdump -eni en0 'icmp and host 192.168.50.25' |
关键形态是:
1 | 1a:22:18:7f:6e:d5 > bc:24:11:78:02:22 |
这里:
1 | 1a:22:18:7f:6e:d5 本机 50.22 |
破案点就在这一行:
1 | IP 目的地: 192.168.50.25 |
也就是说,本机确实回包了,但回包在二层发错了人。
ImmortalWrt 只是佐证
在网关上也能看到同样的包:
1 | tcpdump -eni eth0 'icmp and host 192.168.50.25 and host 192.168.50.22' |
1 | 1a:22:18:7f:6e:d5 > bc:24:11:78:02:22 |
网关知道 50.25 在同一个接口上:
1 | ip route get 192.168.50.25 from 192.168.50.22 iif eth0 |
1 | 192.168.50.25 from 192.168.50.22 dev eth0 |
但它只看到了 reply,没有看到对应的 request。对 conntrack 来说,这类包是 invalid,于是被 fw4 丢掉:
1 | ct state invalid counter packets 44 bytes 2592 drop |
所以不要去改网关防火墙兜底。真正该修的是本机路由。
根因
正常情况下,macOS 应该有这条直连路由:
1 | 192.168.50 link#12 UCSc en0 |
异常时,这条路由缺失或被 Clash TUN 的自动路由刷新打乱。结果是:
1 | 三层: 192.168.50.22 -> 192.168.50.25 |
看起来像“本机回了包”,实际是“包回错了二层目的地”。
修复
临时补回直连路由:
1 | sudo route -n add -net 192.168.50.0 -netmask 255.255.255.0 -interface en0 |
验证:
1 | route -n get 192.168.50.25 |
期望看到:
1 | interface: en0 |
长期保留 Clash TUN 排除项:
1 | tun: |
如果重启 Clash、切换 Wi-Fi 后又复现,继续检查 mihomo 的 auto-route 刷新行为;必要时关闭 auto-route,或写一个登录后自动补路由的小脚本。
以后怎么查
遇到“同网段单向 ping 不通”,不要只看 IP 层。按这个顺序查:
1 | ifconfig en0 |
核心问题只有一个:
这个包在三层发给谁?在二层又发给谁?
这两个答案一旦不一致,根因通常就离你很近了。