
我遇到过一台双网卡的机器内网一切正常外网怎么都上不去。SSH能连内网文件能传但软件源更新、时间同步、外部API调用全部超时。排查到最后原因就是默认路由被指到了内网网卡上所有去外网的流量都被交给了根本没有转发能力的内网网关。这篇记录就从排查过程说起把现象确认、路由表诊断、默认路由修改的完整链路捋一遍。如果你手头也有一张内网卡一张外网卡的服务器或者对Linux路由表机制还比较模糊这篇文章能帮你把“默认路由”这件事彻底弄明白。实操涉及的命令主要是ip route和route -n配置文件部分我会分别给出CentOS系和Ubuntu系写法照着操作就能复现。1. 多网卡机器上不了网先搞清楚问题出在哪1.1 现象描述内网正常外网直接丢了先交代一下现场。某台服务器有双网卡一张接内网办公网段一张接外网出口。故障表现非常典型内网主机之间互通没有问题SSH连上服务器也能正常操作但服务器访问外网完全失败。具体表现是apt update或yum makecache拉不动软件源ntpdate时间同步一直超时业务日志里全是连接外部API失败的记录。因为内网是好的所以运维同学的第一反应通常是“外网线路断了”或者“上级路由器出问题了”甚至有人先去怀疑DNS配置。这类判断不能说完全没道理但在多网卡机器上更大概率的问题出在路由表里——默认路由指错了方向。内网通只能证明到内网网关的通路是好的外网流量是否真的被送往外网网关完全是另一回事。理解这个区别很重要。很多人看到“内网通”就觉得网络整体健康但多网卡场景下内网和外网是两个完全独立的转发域。内网是一套房子里的小走廊外网是大楼外面的马路默认路由才是决定你从哪个门出去的关键。这一小节想让你建立的第一认知就是内网能通和外网能不能通没有必然联系。1.2 先别急着改配置理解一下路由表要排查这类问题脑子里必须有一个模型Linux系统对外发包时不是靠“IP配置”决定走哪张网卡而是靠路由表。路由表里有若干条记录从上到下依次匹配。匹配到精确网段的走对应路由匹配不到任何精确记录时就用默认路由兜底。默认路由在route -n里的表现是 Destination 为 0.0.0.0、Gateway 指向具体IP、Genmask 全0的那一行在ip route show里则是default via开头的一行。生活化的理解很直接路由表就是一份快递转运表。内网地址是“本地小区”默认路由就是“所有其他地址”的转运中心。如果转运中心被写成了小区物业那所有省外包裹都会被送到物业办公室当然寄不出去。多网卡上不了网绝大多数情况就是这份转运表的“转运中心”一栏写错了。为什么多网卡容易出这种事因为两块网卡都可能从DHCP那里拿到网关信息也都可能被系统选为默认出口。谁先开机、谁先拿到DHCP响应、谁被网络管理服务最后接管都会影响最终默认路由落在谁头上。最终结果往往就是接了外网的网卡没有默认路由接了内网的网卡反而拿到了一条默认路由。排查的起点不是重装驱动不是换网线而是先看路由表。1.3 适合谁看的场景说明这篇文章适合两类人。第一类是刚接触Linux服务器运维对route和ip route还不熟的初学者可以把它当成一个多网卡路由排查的完整案例。第二类是已经会配IP、但遇到多网卡默认路由问题会被绕进去的准运维这里面的坑和配置细节对你更有参考价值。我要强调的是排查讲究顺序先确认现象再看路由表然后临时修改验证最后落成永久配置。如果你手里正好有一台“内网能通外网不通”的多网卡机器建议按这个顺序往下走不要跳过诊断直接改路由。2. 路由表诊断一步步确认默认路由就是罪魁祸首2.1 第一步核对网卡与IP配置排查第一步先把基本信息摸清楚。用ip addr查看所有网卡的IP信息ip addr典型的问题场景输出大概是这样的eth0inet 192.168.1.10/24接内网网关是 192.168.1.1eth1inet 10.10.10.10/24接外网网关是 10.10.10.1这里有个容易忽略的点ip addr只显示IP和掩码不显示网关。要看到网关必须看路由表。很多人在这一步看到两块网卡都有IP就觉得“配置没毛病”于是转头去折腾DNS、防火墙方向整个跑偏。如果发现某张网卡没拿到IP那问题可能就是别的原因了比如DHCP没起来、交换机网线松动、驱动没加载。但多网卡“内网能通外网不通”这个典型场景最常出现的状态其实是两块网卡都正常拿到了IP只有默认路由歪了。所以IP配置只花一分钟确认即可重点永远在下一节。2.2 第二步查看当前路由表找到那条错误的默认路由这一步是整场排查的核心。用下面任意一条命令都可以ip route show # 或者传统命令 route -n我个人更推荐ip route show输出表达更直观。排查那台机器时输出长这样default via 192.168.1.1 dev eth0 proto dhcp metric 100 10.10.10.0/24 dev eth1 proto kernel scope link src 10.10.10.10 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10问题一目了然默认路由指向 192.168.1.1也就是内网网关走的设备是 eth0。而接外网的 eth1 网卡它的路由表里只有 10.10.10.0/24 这一段自己网段的直连路由没有任何默认路由。也就是说外网网卡根本没有被当作出口使用。再看route -n的输出会是更传统的表格形式Destination 为 0.0.0.0Gateway 为 192.168.1.1Iface 为 eth0。这就把“内核把所有外网流量都交给了内网网关”这件事钉死了。2.3 第三步用ping和traceroute验证数据包走向路由表已经暴露了问题但为了不误判还是要用网络工具做交叉验证。先ping外网网关和公网地址ping -c 3 10.10.10.1 # 外网网关按实际环境调整 ping -c 3 8.8.8.8 # 公网IP按实际测试对象调整测试结果通常是这样ping外网网关通ping公网IP不通。这个结果说明外网网卡自身和它的网关链路是没问题的问题在于数据包根本没走到外网网关那一跳。用 traceroute 观察得更清楚traceroute -n 8.8.8.8实测输出里第一跳就是 192.168.1.1而不是期望的 10.10.10.1。数据包从 eth0 出去后直接进了内网网关的口外网网关连数据包的面都没见着。想再扎实一点可以直接抓包确认源头。开一个终端抓 eth0 上的ICMP包sudo tcpdump -i eth0 icmp -c 5另一个终端去ping公网IP观察 eth0 上是否有ICMP请求发出以及目标MAC地址是不是内网网关的MAC。如果抓包显示请求的下一跳MAC确实是内网网关证据链就完整了路由表指向内网网关→数据实际走向内网网关→内网网关没有外网转发能力→外网不通。2.4 诊断结论与为什么不能只改DNS诊断到这里结论非常明确这台机器不缺IP不缺网关缺的是一个正确的默认路由。内核把所有没有明确匹配的外网流量都交给了内网网关而内网网关不具备转发公网数据的能力于是所有外网数据包都死在内网网关那一跳。顺带说一个常见误区很多人遇到“能解析域名但访问不了外网”第一反应是改DNS。实际上DNS解析走的是内网DNS服务器解析成功只能说明到内网DNS的通路是好的不代表到公网的链路通。真正的外网流量还是要靠默认路由送出去。默认路由如果指错了DNS配置再正确也不会让流量自动跑到外网网卡上。所以诊断的核心永远是数据包到底交给了谁。3. 实操修改默认路由临时方案与永久配置3.1 先用临时命令验证方向和网关确认问题原因后先做一次临时修改验证“换成外网网关是否真的能通”。这一步风险低适合快速试探。执行前有个好习惯把当前路由表备份到文件万一改完不对还能快速恢复。ip route show ~/route_backup.txt然后删除错误的默认路由再添加正确的。这里有两种写法# 方式一先删除再添加过程可控 sudo ip route del default via 192.168.1.1 dev eth0 sudo ip route add default via 10.10.10.1 dev eth1 # 方式二用 replace 一步完成 sudo ip route replace default via 10.10.10.1 dev eth1两种方式我都实测过。方式一能看到中间状态更适合新手方式二效率高但如果你机器里存在两条默认路由replace可能只是替换了其中同metric的一条另一条还在。所以稳妥起见先del后add是我更推荐的做法。改完立刻验证ip route show ping -c 3 8.8.8.8正常的话default via 10.10.10.1 dev eth1出现在路由表里公网也能ping通了。到这一步网络在运行层面已经恢复。但别急着收工因为重启或网络服务重启后默认路由大概率又会变回 192.168.1.1。临时修改只是“救火”要根治必须改配置文件。3.2 为什么临时修改不持久自动配置在“抢”默认路由服务器开机时网卡通过DHCP获取IP同时DHCP会下发网关信息系统会把网关写成默认路由。多网卡环境里要是内网和外网都开了DHCP两块网卡就都有资格拿到“默认路由”这个职位。最终谁上岗取决于开机顺序、DHCP响应速度、网络管理服务的接管顺序。结果就是你想让外网网卡当出口系统却把默认路由放到了内网网卡上。要让修改持久生效核心思路就两句话外网网卡显式承担默认路由内网网卡主动放弃默认路由。少做任何一条都可能被DHCP或NetworkManager悄悄改回去。很多人的配置只改了一半只在ifcfg里写了GATEWAY忘了给内网网卡设置DEFROUTEno结果重启后问题复发就是这个原因。3.3 CentOS系ifcfg配置文件写法CentOS 7/8这类使用ifcfg文件的系统先确认网卡配置文件位置ls /etc/sysconfig/network-scripts/ifcfg-*拿上面那台机器举例。外网网卡 eth1 原来如果是DHCP改成静态并显式写网关DEVICEeth1 BOOTPROTOnone ONBOOTyes IPADDR10.10.10.10 NETMASK255.255.255.0 GATEWAY10.10.10.1 DEFROUTEyes内网网卡 eth0 保持静态或DHCP都可以但必须明确禁止接管默认路由DEVICEeth0 BOOTPROTOnone ONBOOTyes IPADDR192.168.1.10 NETMASK255.255.255.0 DEFROUTEno就算内网网卡用的是DHCP也要在ifcfg里加DEFROUTEno并且确认NetworkManager没把这项配置覆盖掉。改完以后重启网络服务sudo systemctl restart network如果系统用的是NetworkManager接管RHEL 8比较常见可以重载并重新激活连接sudo nmcli connection reload sudo nmcli connection down eth0 sudo nmcli connection up eth0重启后再看ip route show应该只剩一条default via 10.10.10.1 dev eth1。如果发现两条default并存回到配置检查哪张网卡的DEFROUTE没生效。3.4 Debian/Ubuntu系netplan配置文件写法Ubuntu 18.04 使用netplan配置文件通常在 /etc/netplan/ 下名字类似 01-netcfg.yaml 或 00-installer-config.yaml。外网网卡原来是DHCP的可以用下面的写法network: version: 2 ethernets: eth0: dhcp4: true dhcp4-overrides: use-routes: false eth1: dhcp4: false addresses: - 10.10.10.10/24 routes: - to: default via: 10.10.10.1dhcp4-overrides里的use-routes: false很关键它让内网网卡即使从DHCP拿到网关也不生成默认路由。这里有个细节use-routes: false会让DHCP下发的所有路由都不生效但直连网段路由是内核根据地址配置自动生成的不受影响所以正常场景下没问题。如果内网网卡本身就是静态配置写法更简洁network: version: 2 ethernets: eth0: addresses: - 192.168.1.10/24 # 不写routes就不会生成默认路由 eth1: addresses: - 10.10.10.10/24 routes: - to: default via: 10.10.10.1改完后执行sudo netplan applynetplan对yaml缩进非常敏感建议正式apply之前先跑一次sudo netplan try它会先解析并应用配置超时后如果没收到确认就自动回滚避免把远端SSH搞断。3.5 修改后的完整验证清单配置改完不是看一眼就能收工。我的验证顺序是先ip route show确认只有一条默认路由且指向正确再ping外网网关确认链路然后ping公网IP确认出口接着用nslookup解析一个外部域名确认DNS没有被牵连最后跑一次真实的业务依赖操作比如apt update或者yum makecache。两步验证走完才算真正修好。如果IP能ping通但域名解析失败那说明默认路由没有问题了要单独去查DNS解析配置不要把账记在默认路由头上。这听起来像废话但我见过不少人在改完路由后发现域名解析有问题又把路由一顿乱改结果越改越乱。搞清楚问题边界比多敲几条命令重要得多。注意修改网络配置前一定备份原配置。远程连接的机器尤其危险一旦默认路由被改错或清理过度SSH会直接断开远程操作没法恢复只能去机房或带外管理控制台处理。备份目录可以是/etc/sysconfig/network-scripts/或/etc/netplan/简单tar打包就行。3.6 进阶情况策略路由和容器环境如果这台机器不是普通场景而是跑了不少网络策略比如多运营商出口分流、源地址策略路由那情况会更复杂。光改main路由表不一定有用内核会根据ip rule里的策略规则把特定流量导向其他路由表。这时候建议同时检查ip rule show ip route show table all容器和虚拟化环境也要注意。如果这台机器本身是宿主机带docker0、veth接口改完宿主机默认路由后容器访问外网的能力也会跟着变化。我遇到过不止一次改完宿主机默认路由容器内访问外网从通变不通原因就是Docker NAT链路的出接口变了。所以改完默认路由后不能只验证宿主机本身还要验证业务流量链路尤其是跑在容器里的服务。4. 修改默认路由时常见的坑与排查技巧4.1 坑一重启后配置被打回原形临时用ip route命令改完后只要不重启一切正常可服务器一重启或者NetworkManager一重载默认路由又变回内网网关。我见过不少新手在这个坑里反复横跳每次故障都敲一遍ip route add下回重启又复发。要根治就得按上一节说的在网卡配置文件里显式写清楚 GATEWAY、DEFROUTE 或 use-routes。这里最容易犯的错是只配了一半给外网网卡加了网关却忘了让内网网卡放弃默认路由。结果就是重启后仍然可能被内网网卡的DHCP抢回去。所以每次改完配置文件一定要重启网络服务或整个重启一遍再确认路由表状态。只在命令行里看到路由对就以为大功告成是很容易被坑的。4.2 坑二两条默认路由并存到底走哪条如果ip route show同时出现default via 192.168.1.1 dev eth0 metric 100 default via 10.10.10.1 dev eth1 metric 0那内核的选路规则是同前缀时metric值小的优先。怎么控制metric可以临时修改sudo ip route replace default via 10.10.10.1 dev eth1 metric 50在CentOS的ifcfg里对应写法是METRIC50在netplan路由声明里写metric: 50。但我始终认为最省心的方案不是靠metric硬排队而是让内网网卡根本不生成默认路由。因为metric只能排优先级不能删掉错误路由。万一外网网关挂了内核可能自动切换到metric值稍大的那条默认路由流量又会走回内网网关排查时很容易一头雾水。4.3 坑三改完默认路由后业务还是不通这个问题的原因分两类。第一类是我上面说过的容器环境联动宿主机默认路由改变后NAT链路的出接口变了但iptables规则还绑着旧接口或旧地址导致转发包出不去。处理办法是检查iptables -t nat -L POSTROUTING确认MASQUERADE或SNAT规则覆盖了新的出口网卡。第二类更隐蔽改了默认路由但内网访问控制策略禁止服务器通过外网网卡访问某些内网IP或者路由不对称。数据包从外网网卡发出去了对端也收到了但对端的回包路径和你不一致服务器端看到的连接依然超时。遇到这种情况继续用 tcpdump 对比发包和收包。如果一直发SYN但收不到SYN-ACK优先怀疑“路由不对称”需要同时调整回包路径或加静态路由。多网卡环境的诡异之处就在这里单向通不算通要双向通畅才算真的通。4.4 排查技巧改配置前先开一个“逃生窗口”远程维护的机器改错默认路由的代价就是SSH直接断开。我现在养成的习惯是执行修改命令前先在当前SSH会话里跑screen或tmux把网络修改操作放进里面。就算改完路由导致SSH断了等网络恢复或路由被其他机制拉回来后screen会话还在可以继续执行恢复命令。没有这个习惯的人很容易遇到那种“route add 以后半路SSH断连、后续恢复命令没执行”的尴尬处境。命令已经发出去了但后面的命令没机会执行网络又断了只能干瞪眼。另外我不建议用ip route flush来清理路由表它会把main表里的所有路由清空包括直连网段。直连路由没了本机连相邻设备都ping不通非常危险。清理默认路由就老老实实用ip route del default精确删除即可。4.5 配置持久化方案对比方案持久性适用系统优势注意点ip route 命令临时所有Linux即时生效适合验证重启或重载失效ifcfg GATEWAY/DEFROUTE永久CentOS/RHEL系列稳定跟随网卡启动需重启网络服务netplan routes/dhcp4-overrides永久Ubuntu/Debian系声明式配置结构清晰yaml缩进敏感需netplan applyNetworkManager dispatcher脚本永久带NetworkManager的系统灵活能做条件判断脚本写错影响启动不推荐新手实际运维中最常见的组合就是外网网卡静态配置并指定GATEWAY内网网卡禁用默认路由。这套组合在绝大多数Linux发行版上都适用也最容易排查。5. 个人经验与最后的提醒写到最后说一些比较实际的体会。多网卡机器的默认路由问题绝大多数都不是硬件坏了也不是线路断了而是路由表里默认路由指向了一张不该当出口的网卡。诊断时先看ip route show比开一堆抓包工具都高效。判断关键就两点默认路由指向哪个网关以及那个网关有没有能力把包送到目标网络。我个人的配置习惯是内网网卡永远显式禁用默认路由外网网卡永远显式配置网关不让DHCP去猜。这样即使重启后DHCP响应顺序变了默认路由也不会漂移。如果你在维护一批服务器建议把这种固化到初始化脚本里别每台都靠人工命令临时救火。最后再分享一个小技巧如果一台机器有两张网卡但只有外网网卡需要默认路由除了在配置文件里写明白之外还可以在上层交换机或路由器上把网关地址做冗余。这样外网网卡的网关即使临时故障默认路由也不至于被切到内网去。这个属于网络规划层面的事但想清楚之后很多看似“灵异”的断网问题都能从根上解决。