☰
双网卡默认路由冲突导致内网通外网不通的排查与修复
2026/10/19 2:30:07 网站建设 项目流程

接到报障电话的时候,我还以为是个普通的内网慢问题。某台双网卡服务器上跑的第三方业务系统突然大面积超时,同事说“内网都正常,就是从这台机器访问公网某些服务的时候不通”。双网卡、上不了网、访问外网异常——这几个词凑在一起,我第一反应不是DNS解析有问题,就是防火墙策略悄悄变了。但真正排查下来,定位到的根因却是那条没人注意过的默认路由,走到了错误的网卡上。

这篇文章我把完整的排查链路写出来,包括最终通过更改默认路由恢复网络的全过程,以及后续如何让配置在重启后依然正确。如果你手头也有多网卡机器,或者正在被“能上内网但上不了外网”这类问题折磨,这篇应该能帮你少走不少弯路。

1. 现象复盘:能通内网却出不了外网,这故障有点“反常”

1.1 机器拓扑与故障表现

先说这台机器的基本情况。它是一台双网卡服务器,装的是Linux系统,两块网卡分别接两个不同的网络:

  • eth0:办公内网,网段是 192.168.10.0/24,网关 192.168.10.1,主要用于公司内部的系统访问和运维管理。
  • eth1:业务专线,网段是 203.0.113.0/30,网关 203.0.113.1,用于这台机器对外访问第三方平台接口。

故障表现很有意思:从这台机器ping内网其他机器完全正常,SSH登录也顺畅,但ping公网上的某个IP地址就是不通,业务系统调用外部接口也一直超时。我登录上去简单敲了几个命令,发现网卡状态都是UP,IP地址也都在,DNS解析也正常——看起来一切都好,但就是出不了外网。

这个现象放在单网卡机器上,我肯定会先怀疑网关或防火墙。但放在双网卡机器上,事情就复杂了一层:机器上有两个网关,系统到底把去往公网的流量交给了哪个网关?这是整件事的核心疑问。

1.2 为什么这类故障容易误判

说实话,多网卡机器“上不了网”这类故障,最大的难点不是修,而是定位。因为表面现象和真实原因往往隔着好几层:

  • 网卡链路看起来都正常,没有报错;
  • IP地址配置正确,网关也没写错;
  • DNS能解析,防火墙规则也没人动过;
  • 可外网就是不通,业务就是在超时。

我见过不少人在这里卡住,反复去查DNS服务器、查防火墙策略、查系统代理,折腾半天毫无进展。原因就是大家潜意识里默认机器只有一块网卡、只有一条默认路由,压根没往“流量走错了出口”这个方向想。

这其实也提醒了我一件事:排查网络问题,不能只看“配置对不对”,更要看“流量实际怎么走”。配置只是静态的,路由决策才是动态的。所以接下来的重点就落在了一个问题上——这台机器里的数据包,到底是怎么选择出口的?

2. 多网卡机器的“大脑”:路由表如何决定数据包往哪走

2.1 一个容易被忽略的基本规则

在Linux系统里,数据包出去之前都要查一遍路由表。路由表里每条记录包含目标网段、网关、出接口,还有些辅助字段。系统选择路由时按优先级来,大致是三条规则:

  1. 匹配目标IP地址时,子网掩码越长(也就是前缀越长),优先级越高;
  2. 如果有多个相同前缀的路由,metric值(路由度量值)越小越优先;
  3. 如果前缀和metric都一样,先插入路由表的先命中。

打个比方,这就像你站在一个十字路口,面前有两条路都能到市中心,但你肯定会先看哪条路离目的地更近、更直,如果都差不多就挑自己更熟悉的那条走。路由表干的就是这件事。

默认路由在路由表里表示成 0.0.0.0/0,意思是“所有去往未知目标的流量都往这里走”。单网卡机器通常只有一条默认路由,没什么好纠结的;但双网卡机器一开机,如果两块网卡都配置了网关,系统就会给每块网卡都生成一条默认路由——问题从这里就开始埋下了。

2.2 双网卡为什么容易“选错路”

我拿这台机器举例。打开路由表之后,正常情况下应该看到类似这样的输出:

$ ip route show default via 192.168.10.1 dev eth0 default via 203.0.113.1 dev eth1 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.10 203.0.113.0/30 dev eth1 proto kernel scope link src 203.0.113.2

看到没有,这里有两条 default 路由。如果它们的metric相同,系统就会按照插入顺序来选,通常是先初始化的网卡先命中。这台机器eth0是主板上自带网卡,启动时比后插的eth1更早参与网络初始化,所以默认路由永远优先走 eth0,也就是办公内网那个网关。

办公内网网关 192.168.10.1 本身只是个普通出口,没有公网转发能力,所有发给它的公网流量自然就石沉大海。而真正能出网的 eth1 网关虽然在路由表里也有一条default,但打不过排在它前面的那条,只能眼睁睁看着流量走错路。

2.3 路由决策验证命令

在深入排查之前,先交代几个我常用的命令,这几个命令基本能覆盖90%的路由问题定位场景:

  • ip route show:查看完整路由表;
  • ip route get <目标IP>:模拟系统为一个具体目标IP做路由决策,直接告诉我们走哪个网卡、用哪个源地址;
  • ip rule show:查看策略路由规则;
  • ping -I <网卡名> <目标IP>:强制指定从某块网卡发包,绕过默认路由决策。

尤其是ip route get这条命令,可以说是多网卡问题定位的“神器”。它能直接告诉你系统心里是怎么想的,省去一大堆猜测。

3. 完整排查链路:从链路层到路由表的逐层递进

3.1 链路层确认:先别急着怀疑配置

万事开头难,但我习惯先从最底层开始递进排查。网络出问题,第一层要确认的就是物理链路和链路层状态。

我登录机器后先看了网卡状态:

$ ip link show 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

两块网卡都是 UP,而且 RUNNING 状态在输出里也正常。接着用ethtool eth0和ethtool eth1看了一眼,速率协商正常,没有丢包计数异常,RX/TX错误计数也都是0。链路层基本可以排除。

提示:如果网卡是DOWN状态,或者物理链路根本没起来,后面看路由表就全是白搭。很多人跳过这一步直接改路由,改了半天发现插头松了,那就太尴尬了。

3.2 路由决策验证:一条命令暴露问题

链路正常,接下来看IP层。我先 ping 了两个网关,结果很有意思:

$ ping -c 3 192.168.10.1 64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.2 ms 64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.2 ms --- 192.168.10.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss $ ping -c 3 203.0.113.1 64 bytes from 203.0.113.1: icmp_seq=1 ttl=64 time=1.1 ms 64 bytes from 203.0.113.1: icmp_seq=2 ttl=64 time=1.1 ms --- 203.0.113.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss

两个网关都能通。这就有点迷惑了——如果网线、IP配置、网关都有问题,肯定有一个网关会ping不通。现在两个都通,说明链路层和IP层都没问题,问题一定出在“去往远端网络时的路径选择”上。

我随手敲了那条关键命令:

$ ip route get 198.51.100.10 198.51.100.10 via 192.168.10.1 dev eth0 src 192.168.10.10

问题一下暴露了:系统认为去往公网地址 198.51.100.10 的流量应该从 eth0 出去,经过 192.168.10.1 这个办公内网网关。可这个网关根本没有公网转发能力,流量自然就卡死在这里。

3.3 排除法验证:DNS和防火墙不是元凶

到这里,其实已经把主要矛盾锁定到路由上了。但为了严谨,我还是把DNS和防火墙也过了一遍,把可能性彻底堵死。

先看DNS解析,用nslookup查一个外网域名,返回结果正常,说明解析没问题:

$ nslookup example.com Server: 192.168.10.53 Address: 192.168.10.53#53 Non-authoritative answer: Name: example.com Address: 198.51.100.10

再看防火墙,确认 iptables 和 firewalld 的状态,规则表里都是空的,没有拦截公网流量的规则。为了进一步排除,我还用tcpdump -i eth0 host 198.51.100.10抓了一下包,确实看到请求从 eth0 发出去了,但对方没有任何回应,因为办公网网关根本不会把这种包转发到公网上去。

到这里,结论已经很清晰:这是一次典型的多网卡默认路由冲突。流量走错了出口,仅此而已。

3.4 变化记录里的“真凶”

为什么之前好好的突然就不通了呢?翻了一下变更记录才发现,前两天有人在服务器上调整过网卡配置,给 eth0 加了一条手动网关。改完当时没测外网连通性,只看了内网能通就收工了,结果第二天业务一跑,超时告警就来了。

这种“改完没测全”的操作,我真的是见过太多回了。多网卡机器上,每次改任何一块网卡的网关或metric配置,都必须检查完整路由表,确认 default 路由是不是指向了正确的出口。

4. 关键一步:调整默认路由,让流量回到正确的出口

4.1 临时修改:一条命令恢复网络

定位到根因之后,处理方案其实很简单——把默认路由改回指向 eth1 的网关 203.0.113.1。

我先删掉那条走 eth0 的错误默认路由,再把 eth1 的默认路由提上来:

$ ip route del default via 192.168.10.1 dev eth0 $ ip route add default via 203.0.113.1 dev eth1

操作完之后再看一眼路由表:

$ ip route show default via 203.0.113.1 dev eth1 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.10 203.0.113.0/30 dev eth1 proto kernel scope link src 203.0.113.2

现在只剩一条 default,而且指向了正确的出口。接着用之前的命令验证:

$ ip route get 198.51.100.10 198.51.100.10 via 203.0.113.1 dev eth1 src 203.0.113.2 $ ping -c 4 198.51.100.10 64 bytes from 198.51.100.10: icmp_seq=1 ttl=57 time=8.3 ms 64 bytes from 198.51.100.10: icmp_seq=2 ttl=57 time=8.1 ms --- 198.51.100.10 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss

通了。业务系统的接口调用也立刻恢复,页面不再超时。到这里,故障本身算是解决了。

4.2 别高兴太早:临时修改变数很大

你要是以为删一条、加一条就万事大吉,那就太天真了。ip route命令的修改是临时的,重启网络服务、重启机器、甚至某些DHCP租约续期,都可能让路由表“恢复原样”。

尤其要小心的是:如果机器是DHCP自动获取IP,DHCP租约到期重新续约的时候,客户端会按照配置文件重新下发网关地址,把刚刚手工删掉的默认路由又加回来。到时候故障就复现了。

所以临时修改只是第一步,真正要做的是把配置固化下来,让机器每次启动、每次网络服务重载时,都保持正确的路由状态。

4.3 远程操作风险提示

这里必须提醒一句:如果这台机器是远程管理的,而你的管理流量恰好走的是 eth0,那删除默认路由的操作一定要谨慎。我在一次别的机器上就经历过:手一抖把默认路由删错了方向,SSH连接瞬间断开,整个机器变成一个“断了线的风筝”,最后只能求人帮忙去机房接显示器键盘,那叫一个丢人。

建议的做法是:操作之前先开多个SSH会话,或者确保至少有一条独立的管理通道(比如带外管理、iLO/IPMI),再动路由表。宁可多花两分钟准备,也不要赌运气。

5. 永久化方案:让路由配置在重启后依然正确

5.1 各发行版的永久配置方法

临时修改只适合应急,要想让配置在重启后依然正确,就得把配置写死在网络配置里。

在RHEL/CentOS 7这类系统上,网卡配置通常写在/etc/sysconfig/network-scripts/ifcfg-eth0和ifcfg-eth1里。这里的关键是:

  • 只给需要出公网的那块网卡(eth1)配置GATEWAY=203.0.113.1;
  • 内网网卡(eth0)只配置 IP 和掩码,不写 GATEWAY;
  • 如果一定要写 GATEWAY,就配合 metric 控制优先级。

对照一下:

# ifcfg-eth0 DEVICE=eth0 BOOTPROTO=none ONBOOT=yes IPADDR=192.168.10.10 NETMASK=255.255.255.0 # 不写 GATEWAY,避免抢占默认路由 # ifcfg-eth1 DEVICE=eth1 BOOTPROTO=none ONBOOT=yes IPADDR=203.0.113.2 NETMASK=255.255.255.252 GATEWAY=203.0.113.1

在Ubuntu 18.04+(Netplan)上,配置写在/etc/netplan/下,语法类似这样:

network: version: 2 ethernets: eth0: addresses: [192.168.10.10/24] # 不写 gateway4/gateway eth1: addresses: [203.0.113.2/30] routes: - to: default via: 203.0.113.1 metric: 100

配置完成后netplan apply或重启网络服务,再验证一下ip route show,确保 default 路由的指向正确。

5.2 Metric方案:让某块网卡的默认路由自动胜出

如果你的场景里两块网卡都必须配置网关(比如都有业务流量要走),那单靠“不写网关”就行不通了。这时需要用 metric 来控制默认路由的优先级。

Linux 路由规则里,metric 越小越优先。所以让出公网的网卡 metric 设小一点,内网网卡 metric 设大一点,系统就会自动选择公网网卡的默认路由。

在 RHEL 系的 ifcfg 文件里可以这样写:

# ifcfg-eth0 IPADDR=192.168.10.10 NETMASK=255.255.255.0 GATEWAY=192.168.10.1 METRIC=200 # ifcfg-eth1 IPADDR=203.0.113.2 NETMASK=255.255.255.252 GATEWAY=203.0.113.1 METRIC=100

这样即使两块网卡同时配置了网关,因为 eth1 的 metric 更小,系统重启后 default 路由依然会稳定地落在 eth1 上,不会再出现“看心情选路”的尴尬。

5.3 更进一步:策略路由解决“既要又要”的复杂场景

如果你遇到的不只是“能上网就行”,而是需要同时保证某些网段走内网、某些网段走公网、两边互不干扰,那直接改默认路由就不够用了。这种场景我推荐用策略路由(Policy Routing)。

策略路由的核心思路是:给不同的流量来源或目标打上标记,让它们查不同的路由表。

具体做法也不复杂:

# 1. 新建一张自定义路由表,编号100 $ echo "100 external" >> /etc/iproute2/rt_tables # 2. 在这张表里添加默认路由,指向公网网关 $ ip route add default via 203.0.113.1 dev eth1 table external # 3. 添加策略规则:来自内网网段的流量,查external这张表 $ ip rule add from 192.168.10.0/24 table external # 4. 验证 $ ip rule show $ ip route show table external

这样内网网段的业务流量会强制走 eth1 出公网,而访问内网其他机器时仍然走 eth0 的直连路由,两边互不干扰。策略路由的写法还有很多变体,比如按目标端口、按数据包标记分流,但不展开细说了,今天的重点还是默认路由本身。

5.4 巡检建议:把路由表纳入日常检查

经过这次故障之后,我给所有多网卡服务器都加了一条巡检命令:

$ ip route get <一个公网地址> | head -n 1

专门确认系统对公网流量的路由决策是否符合预期。如果哪天结果里出现了内网网关,基本就能第一时间发现路由又走歪了。网络问题最怕的不是出故障,而是故障出了之后大家“感觉正常”,结果业务悄悄受影响。多网卡机器的路由表,跟磁盘空间、CPU负载一样,值得列入日常监控。

尾声:一次故障折腾出来的三个习惯

事后回头总结,这次默认路由的问题本身并不复杂,复杂的是把它从一堆“看似正常”的判断里挖出来。我个人的几个实操体会是:

第一,碰到多网卡机器上不了网,先用ip route get复现系统自己的路由决策,它能省掉一半以上的猜测时间。第二,任何临时路由修改完成后,一定要想想“重启之后还在不在”,不把配置固化下来就等于没修。第三,远程操作路由表之前,务必确认管理通路是否安全,这次机器是在办公室我能随时去现场,换成异地机房就得加倍小心。

这趟排查最值钱的不是那几条命令,而是让我养成了“先看流量走向,再改配置”的习惯。多网卡机器永远是大意不得的,你永远不知道下次它会在哪条路由上给你挖坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询