不同网段IP通信全过程:网关、ARP与回程路由排障
经常有人拿着一条 ping 不通的记录来问:两台机器明明都配了地址、网线也通,为什么就是不通?再一追问,往往就是两个不同网段的 IP 地址通信过程没搞明白。这个话题听起来基础,但它是整个网络排错的地基——不管是排查跨机房访问、容器网络不通、云上安全组放不通,还是家里光猫下面挂了两台路由器导致上下级设备互访失败,根子上都是同一套逻辑。我打算用一个最朴素的场景,把两个不同网段的 IP 地址通信过程从头到尾走一遍,把每一跳上"谁在看什么、谁在改什么"讲清楚,然后再说怎么用命令行和抓包去验证,最后给一份能直接照着查的故障速查表。刚接触网络的朋友可以当作一条完整的链路来读;做过几年运维的朋友,建议重点看回程路径、ARP 和路由表那几节,很多"单向通"的问题就藏在那里。
1. 先把问题拆开:跨网段通信到底难在哪
1.1 一个被问了很多遍的提问场景
最常见的提问形式大概是这样:A 机地址是 192.168.1.10,掩码 255.255.255.0;B 机地址是 192.168.2.20,掩码同样是 255.255.255.0;中间放了一台路由器,两个接口分别是 192.168.1.1 和 192.168.2.1。问题来了——A 发给 B 的数据,到底是直接送到 B 手里,还是先交给路由器?如果交给路由器,路由器又凭什么知道 B 在哪一边?
这个问题之所以值得单独拎出来讲,是因为它同时踩中了三个容易混淆的概念:同网段判定、默认网关、逐跳转发。很多人把这三个东西混成一团,结果就是配置的时候凭感觉填网关,出问题的时候凭运气换线序。我见过不少现场,网关填错一个数字,整栋楼的设备就上不了外网;也见过掩码写成 255.255.0.0,导致本该隔离的两个部门直接互通,安全策略全部失效。
所以下面我不打算一上来就讲协议栈分层,而是先回答"为什么需要路由器"这个最原始的问题,再一层层往上叠。这样你在配任何一台设备的时候,脑子里都有一个清晰的画面:这个包现在在谁手上,下一步它会被交给谁。
1.2 为什么同网段能直连、跨网段必须找中间人
要理解这件事,得先接受一个事实:以太网这一层,只认 MAC 地址,不认 IP 地址。同一根线、同一个广播域里的设备,互相发帧的时候,帧头里写的是目的 MAC。至于这个 MAC 对应的 IP 是多少,交换机完全不关心,它只看 MAC 表转发。
那问题就来了:A 想发给 192.168.2.20,它怎么知道对方的 MAC?如果 B 就在同一个广播域里,A 可以吼一嗓子(ARP 广播)"谁是 192.168.2.20",B 回一句"我是,我的 MAC 是这个",然后 A 就能封装帧发出去了。这是一条完整的闭环,走得通。
但如果 B 在另一个网段,A 就算吼破嗓子,广播帧也过不了路由器——路由器默认不转发广播。这是设计上的硬性约束,不是配置问题。广播域被路由器切开,这是"网段"这个概念存在的物理意义。所以 A 永远不可能通过 ARP 直接拿到 B 的 MAC,它必须找一个"广播域内、又认识外面世界"的设备当代言人,这个代言人就是默认网关。
这里可以打个生活化的比方。你住在某个小区,想给隔壁小区的人送东西。你知道对方住在哪个小区几号楼(IP 地址),但你进不去那个小区(跨广播域)。你能做的是把东西交给小区门口的快递驿站(网关),驿站负责送到对方小区门口,再由对方小区的驿站送到收件人手里。你全程只跟自家门口的驿站打交道,你根本不需要知道对方小区门朝哪开。
这个类比里有两个关键点值得记住:第一,你交给驿站的是一件"寄往某地"的包裹,包裹上的收件地址(目的 IP)从头到尾不会变;第二,每经过一个驿站,外层的运输单据(源/目的 MAC)都会换一张。这两条是理解整个转发过程的钥匙,后面还会反复用到。
2. 判断这一步:子网掩码到底在算什么
2.1 与运算:一个不用背公式的判断方法
在发包之前,主机做的第一件事是判断"目的地跟我是不是一家人"。判断方法就是把双方的 IP 分别和自己的掩码做按位与运算,结果相同就是同网段,不同就跨网段。
拿前面的例子算一遍。A 的地址 192.168.1.10,掩码 255.255.255.0,与运算之后网络号是 192.168.1.0;B 的地址 192.168.2.20,同样用 255.255.255.0 运算,网络号是 192.168.2.0。两个网络号不一样,结论就是跨网段,需要走网关。
如果你不想记"与运算"这个词,有个更土但更好用的办法:看掩码决定了前多少位是"楼号",剩下的位是"房间号"。255.255.255.0 意味着前三段是楼号,最后一段是房间号。A 是 1 号楼,B 是 2 号楼,楼号不同,自然不是一个院里的。255.255.0.0 就意味着前两段是楼号,这时候 192.168.1.10 和 192.168.2.20 就变成同一栋楼里的不同房间了,能直连。
这里必须强调一个高频错误:判断是用发送方自己的掩码来算的,不是用对方的。主机 A 只知道自己配了什么掩码,它不知道 B 配的是什么。所以如果 A 配 /24、B 配 /16,两边算出来的结论可能完全相反,就会出现"我能 ping 通你、你 ping 不通我"这种单向故障。这个坑我后面会专门在故障章节展开。
2.2 掩码配错会引发什么连锁反应
掩码错误是现场事故里性价比最高的一类问题——改动一个数字,影响一大片。举两个真实感很强的场景。
第一个场景:某办公网本来规划的是 192.168.10.0/24,一共 254 个可用地址。后来设备增加到 300 台,有人图省事,直接把掩码从 255.255.255.0 改成 255.255.254.0,地址池扩到 510 个。表面上看问题解决了,实际上 192.168.10.x 和 192.168.11.x 现在被判定为同一个网段,原本应该经过防火墙的策略流量,现在直接在二层互通了。安全设备形同虚设,而且这种问题极难被发现,因为业务全都正常,只是"不该通的地方通了"。
第二个场景更常见:网关地址填错。A 机地址 192.168.1.10/24,网关本该是 192.168.1.1,结果填成了 192.168.1.254,而那台设备根本不存在。这时候 A ping 同网段的机器一切正常,一 ping 外网就超时。原因很直接——A 要把包交给 192.168.1.254,于是发 ARP 问"谁是 192.168.1.254",没人应答,包在本地就发不出去,连路由器的门都没摸到。
还有一种更隐蔽的:网关填成了另一个网段的地址,比如 192.168.2.1。这时候 A 会认为网关跟自己不同网段,于是又要去找"访问 192.168.2.1 的网关",形成逻辑死循环,系统通常会直接报"网络不可达"。看到这个报错,第一反应就该去核对网关和掩码,而不是怀疑网线。
提示:配置完地址后,先别急着测业务。用一条最简单的命令确认本机的路由表里默认路由指向的是你以为的那个网关,这一步能省掉后面大量无意义的排查。
3. 通信全过程逐跳拆解:从 A 到 B 到底发生了什么
3.1 主机侧第一步:查表、选路、定出口
现在假设 A 已经算明白 B 不在自己网段,接下来它要做的不是马上发包,而是查自己的路由表决定从哪个口出去、下一跳是谁。
绝大多数终端上,路由表里会有这么几类条目:一条是本地网段直连路由,比如 192.168.1.0/24 走本地接口,不带下一跳;一条是默认路由 0.0.0.0/0,指向网关 192.168.1.1。A 拿目的地址 192.168.2.20 去匹配,直连路由匹配不上,最后落到默认路由上,于是决定:下一跳是 192.168.1.1。
这里有个细节很多人不知道:路由器选路遵循最长前缀匹配。如果表里同时存在 192.168.0.0/16 和 192.168.2.0/24 两条路由,去往 192.168.2.20 的包会选 /24 那条,因为它的前缀更长、描述更精确。这跟"先匹配到的先赢"没关系,是纯粹的精度优先。理解这一点,你在做多线路由或者策略路由的时候就不会被"为什么它走了备用线路"这类问题困住。
选定下一跳之后,A 还需要一个东西才能封装帧:下一跳的 MAC 地址。注意,这里要的不是 B 的 MAC,而是网关 192.168.1.1 的 MAC。这是整条链路上最容易搞混的一点——目的 IP 是最终收件人,目的 MAC 只是"这一跳的下一站"。
3.2 ARP:为什么必须先问网关的 MAC
A 查本机的 ARP 缓存表,如果里面已经有 192.168.1.1 对应的 MAC,直接用;如果没有,就发一个 ARP 请求。
这个 ARP 请求长这样:以太网帧头的目的 MAC 是全 F(FF:FF:FF:FF:FF:FF),也就是广播,意思是"这个广播域里所有设备都请看一眼";帧里的内容写着"谁拥有 192.168.1.1,请把你的 MAC 告诉我,我的地址是 192.168.1.10"。同网段的所有设备都会收到这个广播,但只有 192.168.1.1 会回应,其他设备看一眼发现不是问自己,直接丢弃。
网关收到后单播回一个 ARP 应答,A 把它记进 ARP 缓存,通常有几分钟的老化时间,然后就可以封装数据帧了。
这里有三个实操要点值得记牢。第一,ARP 缓存是有寿命的,所以你会看到抓包里隔一段时间就出现一次 ARP 请求,这是正常现象,不是故障。第二,ARP 只在广播域内有效,跨网段的 ARP 请求路由器不会转发,所以你不能指望通过 ARP 直接解析到远端主机的 MAC。第三,ARP 表是可以被静态绑定的,在一些对稳定性要求高的环境里,把网关的 IP-MAC 做成静态条目,能避免 ARP 欺骗导致的间歇性断网,但代价是网关换了设备必须手动改,属于典型的两难取舍。
顺带说一句,IPv6 里没有 ARP,对应功能由 NDP(邻居发现)承担,逻辑类似但不完全一样。如果你只关心 IPv4,这段可以跳过;如果同时管双栈环境,心里要有个数,别拿 ARP 的思路去套 IPv6。
3.3 数据帧逐跳变化:MAC 每跳换、IP 始终不变
封装完成之后,A 发出的是一个这样的帧:
| 字段 | 源 | 目的 |
|---|---|---|
| 源 MAC | A 的网卡 MAC | — |
| 目的 MAC | — | 网关接口 192.168.1.1 的 MAC |
| 源 IP | 192.168.1.10 | — |
| 目的 IP | — | 192.168.2.20 |
网关收到这个帧,做几件事:检查目的 MAC 是不是自己(是),剥掉以太网帧头,把 IP 包交给自己的路由转发模块。路由模块拿目的 IP 192.168.2.20 去查路由表,发现 192.168.2.0/24 这个网段直连在自己的另一个接口上,于是决定从那个接口发出去。
发出去之前还有几步不能漏:TTL 减 1(防止环路里的包永远转下去),重新计算首部校验和(因为 TTL 变了),然后在新接口上重新做一次 ARP,问"谁是 192.168.2.20"。B 应答之后,网关重新封装一个帧:
| 字段 | 源 | 目的 |
|---|---|---|
| 源 MAC | 网关出口接口的 MAC | — |
| 目的 MAC | — | B 的网卡 MAC |
| 源 IP | 192.168.1.10 | — |
| 目的 IP | — | 192.168.2.20 |
对比这两张表你会发现,MAC 全换了,IP 一个都没变。这就是前面那个快递类比里说的"外层单据每站都换、收件地址始终不变"。理解这一条,你就明白为什么抓包时在不同位置看到的源 MAC 不一样,但源 IP 是一样的;也就明白为什么 NAT 设备会破坏这个规律——NAT 改的不只是 MAC,连 IP 和端口都改了,那是另一套逻辑,本文只讨论纯路由转发场景。
还有一点常被忽略:路由器不转发广播和组播(除非专门配置)。所以 A 发起的 ARP 广播到网关这里就终止了,不会传到 B 那边的网段。这也是为什么跨网段发现类协议经常需要额外配置中继。
3.4 回程路径:单向通往往栽在这里
到这一步,A 到 B 的方向已经走通了。但通信是双向的,B 收到包之后要回一个应答,而回程路径经常被人忽略。
B 收到 A 的包,看到源 IP 是 192.168.1.10,它要回包,于是做同样的判断:用自己的掩码 255.255.255.0 去算 192.168.1.10,得出网络号 192.168.1.0,跟自己 192.168.2.0 不同,所以也要走网关。于是 B 查自己的路由表找 192.168.2.1,ARP 解析它的 MAC,把回包交给它,网关再转发回 A。
问题就出在这里:如果 B 没有配置网关,或者网关配错了,去程通、回程断。表现出来就是 A ping B 超时,但在 B 上抓包能看到请求包确实收到了,只是没有应答发出去。这种"能收到不能回"的现象,是判断单向故障最直接的证据。
更隐蔽的一种情况:B 的网关是对的,但网关设备上没有回程路由。比如 A 网段是 192.168.1.0/24,B 网段是 192.168.2.0/24,中间的设备只配了去往 192.168.2.0 的路由,没有配回 192.168.1.0 的路由。包到了 B,B 回包给网关,网关一查表发现不知道怎么回 192.168.1.0,直接丢掉。表现在外就是"目标能收到请求但源端一直超时"。
所以在任何跨网段排障里,我都会强调一句话:先确认双向,再怀疑中间。别一上来就怀疑中间链路丢包,先把两端各自的网关、掩码、路由表核对一遍,能解决八成问题。
4. 实验验证:用命令行和抓包把过程跑一遍
4.1 环境准备与地址规划
光看文字容易飘,最好自己搭一遍。最省事的做法是用虚拟化平台起两台轻量系统加一台软路由,或者直接用三台虚拟机做静态路由实验。地址规划如下:
| 设备 | 接口/角色 | 地址 | 掩码 | 网关 |
|---|---|---|---|---|
| 主机 A | 单一网卡 | 192.168.1.10 | 255.255.255.0 | 192.168.1.1 |
| 路由器 | 接口 1 | 192.168.1.1 | 255.255.255.0 | 无 |
| 路由器 | 接口 2 | 192.168.2.1 | 255.255.255.0 | 无 |
| 主机 B | 单一网卡 | 192.168.2.20 | 255.255.255.0 | 192.168.2.1 |
路由器上要确认转发表里两条直连网段都在,并且没有开启任何防火墙拦截。这一步很关键,很多实验失败不是路由问题,是被本机防火墙静默丢包了,排查半天以为是配置错。
如果手头没有虚拟化环境,用两台机器直连、其中一台开启路由转发也能做,但要额外配地址和静态路由,麻烦一些。我更推荐虚拟化方案,随时能重置,改坏了不留痕迹。
4.2 关键命令与现象观察
先看 A 的路由表,确认默认路由指向正确:
# Linux ip route show # 期望看到类似 # default via 192.168.1.1 dev eth0 # 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10 # Windows route print然后清一次 ARP 缓存,这样能看到完整的解析过程:
# Linux ip neigh flush all # Windows arp -d *接着发起一次 ping,同时抓包。抓包建议同时开两处:A 的网卡和路由器的两个接口。如果只能在 A 上抓,也能看到前半个过程。
ping -c 4 192.168.2.20ping 通之后立刻看 ARP 表:
ip neigh show # 应该能看到 192.168.1.1 对应某个 MAC,状态是 REACHABLE 或 STALE你会观察到一个很有说服力的现象:ARP 表里只有网关的条目,没有 B 的条目。因为这整条链路里,A 从来没跟 B 直接做过二层通信。这一条足以证明"跨网段通信靠网关代劳"这件事是真的,不是书上说说而已。
再用 traceroute 看路径:
traceroute 192.168.2.20结果里应该会列出中间那一跳 192.168.1.1,然后到终点。traceroute 的原理就是靠逐次加大 TTL、让沿途设备回"超时"消息来探测路径,所以它天然能看到每一跳——这也侧面说明了 TTL 在转发过程中确实在被递减。
4.3 从抓包结果里读出门道
在 A 的网卡上抓包,过滤条件用host 192.168.2.20,你会按时间顺序看到:先是一个广播的 ARP 请求问 192.168.1.1,然后是网关的单播应答,接着是 ICMP 请求出去,再是 ICMP 应答回来。
点开 ICMP 请求那一帧,重点看两个地方。一是以太网层的目的 MAC,是网关的 MAC;二是IP 层的源地址是 192.168.1.10、目的地址是 192.168.2.20。这两处信息放在一起,就把"二层地址逐跳变化、三层地址端到端不变"这件事钉死了。
如果能在路由器出口侧再抓一次,对比同一个包在两个位置的样子,效果更直观:IP 头里的源和目的完全一样,TTL 少了 1,帧头的 MAC 全换了一遍。我在带新人的时候最喜欢用这个方法,讲十遍不如让人自己看一眼。
还可以做一个小实验来加深理解:把 B 的网关删掉,再 ping。你会发现 A 侧抓包能看到请求正常发出去了,但一直等不到应答。这时候在 B 上抓包,能看到请求进来了,但 B 因为没有网关,回包根本发不出去。这个实验花不了五分钟,但对"回程路径"的理解帮助极大,比看十篇文章都管用。
注意:做实验时最好把两端的防火墙临时关掉,或者明确放行 ICMP。很多"ping 不通"根本不是网络层的问题,是被主机防火墙拦在了上面。
5. 常见故障与排查实录
5.1 一张按现象定位的速查表
跨网段问题表现形式不多,但成因很杂。下面这张表是我这些年排障时总结的对照关系,按"看到什么现象"去反推"该查什么",比从头捋一遍协议栈高效得多。
| 现象 | 最可能的原因 | 优先检查项 |
|---|---|---|
| 同网段通,跨网段全不通 | 网关未配置或配置错误 | 本机默认路由、网关地址是否正确 |
| ping 网关通,ping 远端超时 | 对端无回程路由,或中间设备未配回程 | 对端网关配置、中间设备路由表 |
| 一端能通一端不通 | 双方掩码不一致,判定结果相反 | 两端掩码是否统一 |
| 刚开机通,过一会儿断 | ARP 缓存老化后解析失败 | ARP 表状态、是否存在 ARP 欺骗 |
| 小包通、大包不通 | MTU 不匹配,分片被丢弃 | 链路 MTU 设置、是否禁用了分片 |
| 能 ping 通 IP,域名访问失败 | DNS 配置问题,不是路由问题 | 本机 DNS 设置、DNS 可达性 |
| 偶发超时、时通时不通 | 链路质量、双网关冲突、环路 | 是否存在多个默认网关、MAC 表是否有震荡 |
表格里最后一行值得多说一句。一台主机配了两个默认网关是很常见的错误来源,尤其是在笔记本从有线切到无线、或者虚拟机克隆之后。系统往往只认其中一条,但另一条残留在表里,造成路由行为的随机性。看到"时通时不通",先去看路由表是不是有两条 default。
5.2 我的排障顺序,以及为什么是这个顺序
排障这件事,顺序比技巧重要。我的一般顺序是:先看本机地址和掩码,再看默认路由,再看 ARP 表,再看对端,最后才怀疑中间。
为什么把中间放最后?因为中间设备通常是最稳定的,配置变更频率最低;而两端主机的配置被改动的概率高得多。按概率从高到低排,能少走很多弯路。很多人一上来就怀疑交换机、怀疑线缆、怀疑路由器掉电,结果折腾半天发现是本机掩码少写了一个 255。
具体动作上,我会按这几步走:
第一步,在源端执行地址查询命令,确认 IP、掩码、网关三项都对。特别注意掩码,别只看 IP。
第二步,看路由表,确认默认路由指向的下一跳就是你配的那个网关,且没有多余的默认路由。
第三步,ping 网关。这一条能通,说明二层到网关没问题,ARP 也正常;不通,问题就锁定在本网段内,不用往远处想。
第四步,在源端 ping 目的地址,同时在目的端抓包。如果目的端能收到请求但没回应,问题在回程;如果目的端根本收不到,问题在中间转发或者去程路由。
第五步,确认目的端的网关、掩码,以及它能不能 ping 通自己的网关。这一步经常被跳过,但它恰恰是"单向通"问题的答案所在。
第六步,如果以上都正常,才去看中间设备的转发表和策略。这时候再去查路由表里有没有对应网段、有没有被 ACL 拦掉、接口状态是不是 up。
还有一个经验:抓包位置决定你能不能看到真相。只在源端抓,你只能知道包发出去了;在目的端抓,才知道包到没到;两端都抓,才能判断丢在中间还是丢在回程。三个位置的信息量差别很大,别省这一步。
提示:如果怀疑是 MTU 问题,用带分片禁止标志的 ping 去试,逐步加大包长度找到临界值。这个方法比翻配置快得多,尤其是在跨运营商的场景里。
6. 几个容易被忽略但很关键的细节
6.1 TTL 不只是防环,也是判断路径的抓手
TTL 的官方作用是防止包在环路里永远打转,每经过一个三层设备减 1,减到 0 就丢弃并回一个超时消息。但从排障的角度看,它还有一个更实用的价值:通过 TTL 的初值和剩余值,可以粗略推断经过了几个三层设备。
比如你从本机 ping 一个远端地址,收到的应答里 TTL 是 62,而常见系统的初始 TTL 是 64,那中间大概率经过了 2 跳三层转发。如果某天这个值突然变成 60,说明路径变了,多绕了两跳,这时候就该去看看是不是某条链路挂了、路由发生了切换。这种"用 TTL 变化发现网络拓扑变动"的方法,在没法登录中间设备的场景下特别好用。
要注意的是,不同系统的初始 TTL 不一样,有的是 64,有的是 128,有的是 255,所以不能拿绝对值去判断,只能做相对比较。同一条路径反复测,看数值是否稳定,才是有意义的用法。
另外,有些设备出于各种考虑会不回应超时消息,这会导致 traceroute 出现星号。看到星号不代表路径断了,只代表那一跳不回应,后面的跳数如果还能显示,说明链路是通的。这一点在排障时容易误判,别看到星号就断定故障。
6.2 非对称路由:去和回走的不是同一条路
最后说一个进阶但很现实的话题。前面默认的假设是去程和回程走同一条路径,但实际网络里经常不是这样——去的时候走 A 线路,回来的时候走 B 线路,这叫非对称路由。
非对称路由本身不一定是故障。很多多出口网络就是这么设计的,只要两端都能正确转发,通信照样正常。但它会带来两个麻烦:一是抓包变得很反直觉,你在一条链路上只能看到单向流量,容易误判成丢包;二是有状态设备会出问题,比如防火墙只看到了去程没看到回程,就会把回包当成非法连接丢掉。
遇到"能出去但回不来"、而且中间有防火墙的情况,先别急着改路由,先确认去回路径是否一致。如果确实是非对称的,处理方式有两种:要么调整路由让流量对称,要么在有状态设备上关闭相关的严格检查。前者更稳妥,后者见效快但有安全代价,得看具体场景权衡。
我在实际环境里见过一次特别典型的案例:两条出口线路,去程按目的地址选路走了线路一,回程因为线路二的默认路由优先级更高走了线路二,结果防火墙把回包全丢了。表现是"偶尔能通、大部分超时",因为两条线路的负载分担比例不一样。这种问题靠 ping 是查不出来的,必须两端同时抓包对比路径才能定位。
所以再强调一遍前面那句话的升级版:跨网段排障,永远要问两个方向。光看去的方向,你永远只能看到一半的真相。
提示:条件允许的话,在做任何跨网段配置变更之前,先把当前的地址、掩码、路由表、ARP 表各截一份存着。出问题时能立刻对比出改了什么,比凭记忆复盘可靠得多。
我个人在这些年的实际操作中的体会是,跨网段通信这件事,知识点其实就那么几个,难的不是理解原理,而是在出问题时能按顺序把可能性一个个排除掉。原理是地图,排障顺序是路线,两者缺一不可。把今天这套"判断网段—选网关—解析 MAC—逐跳转发—核对回程"的流程走熟,再遇到任何"不通"的问题,你至少知道自己第一步该敲什么命令,而不是对着一堆线发呆。