资讯动态

Linux route命令详解:路由表查看/添加/删除/排障实战

发布时间:2026/10/19 14:47:01 来源:尧图企业网站定制
凌晨两点半被电话叫醒这件事干运维的应该都不陌生。某天值班同事打过来说机房一台服务器访问公网时断时续远程上去第一件事就是敲route -n确认默认路由到底走的哪张网卡。这种时候你会意识到route 命令虽然在 Linux 里已经算“老一辈”的命令但它在存量系统、自动化脚本、以及各种被改过无数遍的服务器上依然大量存在。对刚接触网络配置的新手来说它是理解“数据包从哪张网卡出去”的最直观入口对老手来说它也是最省事的排障工具之一。这篇文章我会把 route 命令的查看、添加、删除、修改全部过一遍结合真实的故障场景讲清楚为什么一条路由写错会导致整个网络瘫痪以及当 route 命令失灵时你应该往哪个方向排查。文章面向的是正在学 Linux 网络配置的同学也适合那些平时主要用ip route、偶尔在老系统上需要靠 route 命令兜底的运维同行。1. 路由选择的基础逻辑route命令操作的对象到底是什么1.1 路由表不是一张简单的“目的地-下一跳”二维表很多人第一次看route -n的输出时会觉得它就是一列“目的地址”、一列“网关”、一列“网卡”的表格。这个理解没错但不够。路由表本质上是一套转发决策规则内核拿到一个数据包后要看它的目的 IP然后在这套规则里找出“最长匹配”的那一条再把包交给对应的网关和网卡。拿快递来打比方你要寄一个包裹到某个城市快递公司不会为每个收件人单独规划一条线路而是根据收件地址所在的区、街道去匹配运输线路。目的地址落在哪个区就走那条线路匹配不到任何具体线路的就走“总部默认线路”。Linux 路由表里那个0.0.0.0/0的默认路由干的正是“总部默认线路”的活。route 命令查看和修改的就是内核里这份规则。它本身不负责持久化配置你敲进去的路由是即时生效、重启即失的。这一点很多新手会忽略在测试环境里用 route 加了一条静态路由一切正常重启服务器后却发现网络不通了其实就是因为当时没有把路由写进配置文件。1.2 最长前缀匹配与默认路由看懂选路顺序路由表里可能同时存在很多条记录比如192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.8.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0如果一个数据包的目的 IP 是192.168.1.100它会匹配第一条192.168.1.0/24不会去走默认路由。如果目的 IP 是8.8.8.8前两条都匹配不上最终落到0.0.0.0/0这条默认路由交给网关192.168.1.1处理。选路规则叫“最长前缀匹配”谁的子网掩码更长、覆盖范围更精确谁优先。/32的主机路由永远比/24的网段路由优先/24又比/0的默认路由优先。理解这个逻辑后再看route命令的输出就不会一头雾水了。1.3 route输出里那些常被忽略的字段route -n的输出列分别是 Destination目的网络、Gateway网关、Genmask子网掩码、Flags标志、Metric度量值、Ref引用计数、Use使用次数、Iface出口网卡。其中 Ref 和 Use 在 Linux 上基本没什么参考价值但 Metric 非常关键。Metric 可以理解为“优先级数值”数值越小越优先。当路由表里存在两条同样目的的记录时内核会优先选 Metric 更小的那条。例如双网卡服务器同时配了两个默认网关一个 Metric 100一个 Metric 200正常情况会走 100 的那个。很多“时断时续”“经常绕路”的故障都是因为两条路由 Metric 相同或接近导致内核没有明确的优先顺序。这里建议你养成一个习惯不管用 route 还是ip route查看路由先看三件事——默认路由是否存在、默认路由的网关和网卡是否匹配、有没有意外重复的路由条目。2. 查看路由表route -n 与 Flags 的逐位拆解2.1 为什么生产环境一定用 route -n 而不是 routeroute 命令不带任何参数也能查看路由表但问题在于它会尝试做反向域名解析。也就是说内核把路由表里的 IP 地址交给 DNS 或/etc/hosts去反查主机名这一步在网络环境异常时会非常慢甚至卡住几秒十几秒。我曾经在一台 DNS 配置错误的机器上执行裸的route等了将近半分钟才出结果而同样操作换成route -n是瞬间输出。-n的意思就是“不做名字解析”直接以纯数字 IP 形式展示。生产环境里我从来不建议使用裸的route来看路由因为除了慢还有可能看到一堆被解析成主机名的条目反而干扰判断。很多排障文档里也明确要求先执行route -n这和ping用 IP 而不是域名是同一个道理。2.2 Flags标志位逐个说明Flags 那一列是 route 命令输出里信息量最大、也最容易被忽略的地方。常见的组合有U、UG、UH但完整拆开看其实还有不少标志含义解释UUp该路由当前处于启用状态HHost目标是单个主机而不是网段GGateway需要经过网关转发而不是直连RReinstate动态路由协议恢复的条目DDynamically installed由路由守护进程或重定向动态写入MModified被路由守护进程或 route change 修改过AAddrconf由地址自动配置如 IPv6 无状态配置加入CCache entry缓存条目在旧内核中可见LLocal本机地址相关的路由!Reject拒绝路由匹配到的数据包会被丢弃U和G是最常见的组合。UG表示“这是一条经网关转发的可用路由”默认路由基本都是UG。UH表示“目标是一个具体主机且需要经网关转发”。如果看到!标志说明这条路由是拒绝条目所有匹配它的流量都会在本机被丢弃这通常被用来做流量黑洞或安全隔离。2.3 一条输出行的完整解读看一个实际例子$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.10.0.0 192.168.1.254 255.255.255.0 UG 20 0 0 eth0第一条目的网段是0.0.0.0/0即全部地址网关是192.168.1.1Flags 为UG说明这是一条经过网关的可用默认路由Metric 是 100出口网卡是eth0。第二条192.168.1.0/24是直连路由网关为0.0.0.0表示不需要经过网关数据包直接从eth0发到目标主机。每条直连网段路由本质上是根据网卡 IP 和子网掩码自动算出来的。第三条去10.10.0.0/24网段需要经过192.168.1.254这是一条典型的静态路由或由路由协议写入的动态路由Metric 20优先级高于默认路由。阅读 route 输出时推荐按“先看默认路由通不通、再看目标网段在不在、最后看 Flags 与 Metric 是否符合预期”这个顺序来。3. 写路由表route add / del 的完整参数与写法变体3.1 route add的标准形态与几种目标类型route 命令写路由表的格式可以归成三种形态主机路由、网段路由、默认路由。区别就在目标地址的写法上。添加主机路由目标是单个 IProute add -host 10.0.0.5 gw 192.168.1.1 dev eth0添加网段路由目标是网络地址加子网掩码route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1 dev eth0添加默认路由可以直接用default关键字也可以写成0.0.0.0/0的形式route add default gw 192.168.1.1 dev eth0 route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.1.1 dev eth0网端掩码还有一种写法是用 CIDRroute add -net 192.168.1.0/24 gw 192.168.1.1在较新版本的 net-tools 里支持这种写法。但老一点的内核和 busybox 环境可能不认为了稳妥跨环境操作时建议写完整的netmask 255.255.255.0。3.2 gw和dev的关系什么时候必须写devgw指定下一跳网关dev指定出口网卡。多数情况下只写gw内核也能根据网段判断从哪张网卡出去但如果下一跳地址同时出现在多张网卡所在的网段里不写dev就会产生歧义。我在一台双网卡机器上就遇到过内网网段和外网网段都包含同一个网关地址时route 命令会把路由写到错误的网卡上导致数据包从内网卡发往一个根本不可达的网关。所以我的习惯是添加路由时一律把dev带上哪怕它看起来冗余。命令本身不会因此变慢但能避免很多隐性故障route add -net 10.20.0.0 netmask 255.255.0.0 gw 192.168.1.254 dev eth0另外gw地址必须是与本地网卡处于同一网段的地址。如果你指定的下一跳本身都不可达内核会直接报错下一节会讲。3.3 删除路由时常见报错与解决思路删除路由使用route del格式上尽量与添加时保持一致route del -host 10.0.0.5 route del -net 192.168.1.0 netmask 255.255.255.0 route del default gw 192.168.1.1这里有两个非常经典的坑。第一个坑是删除时报SIOCDELRT: No such process中文环境可能显示“无此文件或目录”。绝大多数情况下不是因为内核没有这条路由而是你写的掩码、网关或网卡与路由表里的记录不一致。比如添加时写的是netmask 255.255.255.0删除时写成了/24虽然语义相同但老版本 net-tools 不会帮你换算导致匹配不上。遇到这种报错先route -n把当前准确条目抄下来再用完全一致的信息删除。第二个坑是删除默认路由时只写了route del default如果表里有两条默认路由不同网关或不同 Metric这条命令只会删掉其中一条另一条依然存在。要精准删除某一条默认路由务必带上gw和devroute del default gw 192.168.1.1 dev eth0注意route del和route add都需要 root 权限普通用户执行会提示 Permission denied。这也是新手经常遇到的问题。4. 修改与排错route change、route flush 和删不掉路由的经典坑4.1 route change只适合小改动route change的作用是修改已有路由的属性比较常见的用法是把某条网段路由的下一跳改掉route change -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.254注意change不是新增目标网段必须已存在于路由表中否则会报SIOCADDRT: No such process。它适合临时切换链路的情况比如机房割接时把某个网段的流量从旧网关切到新网关。修改后马上route -n验证 Flags 和 Gateway 是否变化。但change能改的字段有限它不能改目标地址本身也不能增加一条原本不存在的路由。想着用change做“没有就新增、有就修改”的幂等操作是不行的该用 add 就 add该用 del 就 del。4.2 route flush和“删不掉”路由的处理route flush会清空整个路由表包括直连路由和默认路由执行后网络可能瞬间失联。我建议把它当作“重置内核路由表”的极端手段只在完全清楚后果的情况下使用。很多系统上 flush 后甚至连 loopback 路由都会被清掉届时你连本机都 ping 不通自己必须重启网络服务或重启用rc.local恢复。遇到“删不掉”的路由正确排查顺序是route -n里找到目标条目的完整信息注意掩码和网关是否与你记忆中的一致。确认不需要删除的是否在别的路由表里。route 命令默认操作主路由表但 Linux 可能存在多个路由表用ip route show table all查看是否条目在特定表里。检查 Flags 里是否有D或M动态路由守护进程管理的条目可能被持续重新注入就算你手动删掉过几秒又回来了。这类路由要从守护进程或 NetworkManager 侧关闭而不是靠反复执行route del。如果路由被标记为!Reject删除时同样要保证掩码和网段完全一致。我处理过一起“路由删不掉”工单最后发现是 NetworkManager 根据网卡配置文件里的静态路由配置在每次路由变更后自动重新添加。手动删除只是暂时生效得先把配置文件里的静态路由去掉再连删带重启才彻底解决。4.3 一条完整排错链路从route -n到tcpdump路由类故障的排查路径其实很固定。假设某台服务器访问内网某个网段不通我会按这个顺序来ip addr show # 确认网卡已 up且 IP/掩码正确 route -n # 确认目标网段的路由是否存在 ping -c 3 下一跳网关 # 验证到网关的连通性 ping -c 3 目标IP # 验证到目标地址的连通性 traceroute 目标IP # 定位丢包或绕路发生在哪一跳 tcpdump -i eth0 icmp # 在出口网卡抓包确认包是否真的发出这串命令能区分出问题到底出在“路由缺失”“网关不可达”还是“目标主机无响应”。曾经遇到一例路由表里明明有10.10.0.0/24的路由下一跳是192.168.1.254但 ping 网关通、ping 目标不通。抓包发现数据包到了网关网关没有回包继续排查才定位到是上游交换机的 VLAN 配置问题。如果一开始就反复改路由反而会把问题搞复杂。路由表排错有个原则先确认路由对不对再怀疑链路和防火墙。别一上来就加路由删路由把原本正常的表搞乱。5. 路由表混乱的实战复盘一次双网卡路由事故的处理过程5.1 故障现象某台服务器配了两张网卡内网网卡eth0配置192.168.1.2/24外网网卡eth1配置10.0.0.2/24默认网关应该走外网。某次维护后服务器对外访问全部超时内网访问部分正常但去其他内网网段也不通。远程上去第一件事就是route -n结果发现默认路由有两行0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth1两条默认路由的 Metric 都是 0内核没有明确的优先顺序。更麻烦的是原本应该走10.0.0.1出口的流量有一部分走了192.168.1.1。由于192.168.1.1是内网网关它根本没有去往公网的路由数据包进去就石沉大海。5.2 排查过程先确认两个网关的连通性ping -c 3 192.168.1.1 ping -c 3 10.0.0.1两个网关都能通说明问题不在链路而在路由选择。接着用ip rule show确认没有策略路由干扰再用ip route show table all查看所有路由表确认多余默认路由是从哪来的。最后定位到是维护时网络服务重启脚本把默认路由重复写入而且没有清理旧条目。5.3 用route命令临时修正这种场景下不需要重启网络服务直接改路由表就好route del default gw 192.168.1.1 dev eth0 route del default gw 10.0.0.1 dev eth1 route add default gw 10.0.0.1 dev eth1 metric 100第一条命令删掉错误的内网默认路由第二条删掉外网默认路由但为了确保接下来添加时不冲突可以一并清理第三条再把唯一正确的外网默认路由加回去并显式设置 Metric 100。执行完立刻route -n验证0.0.0.0 10.0.0.1 0.0.0.0 UG 100 0 0 eth1然后再 ping 公网地址确认恢复。整个临时修复过程不涉及重启对正在运行的业务影响最小。5.4 根治方案防止路由重启后复发临时修复只解决当下如果根因是网络服务或 NetworkManager 在启动时重复注入默认路由重启后故障还会回来。这里有两种处理思路。第一种在网卡配置文件中显式指定默认路由的 Metric例如 RHEL/CentOS 系的ifcfg-eth0和ifcfg-eth1里分别配置GATEWAY10.0.0.1 METRIC100内网网卡不配 GATEWAY或者配一个更大的 Metric。这样网络服务启动时只会得到唯一主默认路由。第二种把修复命令写入启动脚本。在很多没有 NetworkManager 管理的裸机上可以直接在/etc/rc.local或自定义 systemd unit 里执行route del和route add。但要注意执行顺序必须晚于网络服务初始化否则可能被覆盖。这个案例给我的教训是双网卡服务器上配置默认路由一定要慎之又慎多出来的默认路由比少一条路由更难查。6. route命令的边界Linux下的ip route替代与路由持久化6.1 route命令的局限它只是iproute2的“老前辈”route 命令来自 net-tools 工具包它的地位在 Linux 上已经被ip route逐渐取代。ip route支持多路由表、支持 JSON 输出、支持更精确的策略路由操作而这些 route 命令基本做不到。比如你想查看某个特定路由表ip route show table 100route 命令没有对应能力。再比如你想添加一条基于源地址的策略路由route 命令也无法表达必须用ip rule配合ip route。在较新的 Linux 发行版上net-tools 可能默认不安装你敲route会提示 command not found需要手动安装 net-tools 才能继续使用。但这不代表 route 命令没有存在价值。很多存量系统、嵌入式环境、busybox 设备里net-tools 依然是默认网络工具route 命令是唯一选择。而且 route 命令的输出格式足够直观在快速排障时反而比ip route的长格式更易读。我的处理方式是优先用ip route做精确操作和管理但在老系统和脚本兼容性要求高的场合route 命令照常使用。6.2 route与ip route写法的对照下面是几个常用操作的等价写法操作route 写法ip route 写法查看路由route -nip route show添加默认路由route add default gw 192.168.1.1 dev eth0ip route add default via 192.168.1.1 dev eth0添加网段路由route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1ip route add 192.168.1.0/24 via 192.168.1.1添加主机路由route add -host 10.0.0.5 gw 192.168.1.1ip route add 10.0.0.5/32 via 192.168.1.1删除路由route del -net 192.168.1.0 netmask 255.255.255.0ip route del 192.168.1.0/24如果你习惯了 route 命令的语义切到ip route时需要记住一个差异via就是原来的gw而且ip route对 CIDR 写法的支持更彻底没有老内核兼容性问题。用ip route删除路由时也建议把via和dev写全避免误删同网段其他路由。6.3 路由持久化不同发行版的recommended方案不管是 route 命令还是ip route直接执行的结果都是临时的。要重启后依然生效必须把路由写入系统配置。RHEL/CentOS 系的物理网卡静态路由推荐写入/etc/sysconfig/network-scripts/route-eth0ADDRESS010.10.0.0 NETMASK0255.255.255.0 GATEWAY0192.168.1.254Debian/Ubuntu 系的/etc/network/interfaces可以在网卡配置段内写up route add -net 10.10.0.0 netmask 255.255.255.0 gw 192.168.1.254 dev eth0使用 NetworkManager 的环境可以用 nmcli 的ipv4.routes属性nmcli connection modify eth0 ipv4.routes 10.10.0.0/24 192.168.1.254 nmcli connection up eth0有一点要特别提醒如果你在/etc/rc.local里加route add命令要确保它晚于网络服务初始化。生产机一般不建议这么做优先使用网络管理工具自身提供的路由配置能力。7. 双网卡与多路由场景从机房到办公桌的实战经验7.1 简单多网段与策略路由的边界判断很多人一遇到双网卡多网段的场景就条件反射地想用策略路由。其实大部分情况根本不需要。如果只是“访问 A 网段走内网卡访问 B 网段走外网卡”那属于最简单的静态路由场景直接配置两条不同目的网段的路由即可路由表会根据目的地址自动选择。什么时候必须上策略路由当数据包的转发路径取决于源地址而不是目的地址时。典型的例子是服务器有两条外网出口业务 A 的流量要求从出口 1 出去业务 B 的流量要求从出口 2 出去两边都访问同一个公网目标。这时路由表无法根据目的地址区分只能通过ip rule按源地址打标记再配合多路由表实现。而 route 命令只能操作单一路由表无法表达这种规则必须使用ip rule和ip route table。所以判断标准很直接目的地址能区分就加静态路由源地址也必须参与决策才需要策略路由。实际环境中我见过不少把简单问题复杂化的案例一台只需要两条静态路由的服务器被硬生生配了三个路由表加五六条ip rule排障时自己都被绕晕。7.2 多网关场景下的metric调整双网卡各配一个网关但业务上要求默认走某一个网关另一个只是备用这时候 Metric 就是核心手段。在两个网卡的配置里分别设置不同的默认路由 Metric让主网关的数值更小备用网关的数值更大。流量会自动走主网关只有当主网关不可达时内核才会切到备用网关。注意Metric 的切换不是实时的。内核不会因为你拔了一根网线就立刻把流量切到备用网关它需要等主路由对应的网卡 down 掉或检测到链路不可用。在某些场景下你需要结合网卡 bonding 或监控脚本才能实现自动切换单纯靠 Metric 并不能做到无缝冗余。7.3 运维习惯route命令和ip route如何搭配我的个人做法可以总结成一句话日常工作优先ip route遇老系统用 route 兜底加路由永远写全参数。“优先ip route”是因为它功能更强、更接近现代 Linux 网络栈“遇老系统用 route 兜底”是因为存量环境和脚本里 route 的兼容性更好至于“加路由永远写全参数”这个习惯救过我很多次——dev和gw都写清楚掩码和网段保持精确删除时才能精准匹配。再补充一个细节有些场景里 route 命令的输出和ip route不完全一致比如 route 会显示0.0.0.0作为本机地址或直连掩码ip route则用linkdown、src等额外信息。两种工具的字段含义有细微差别不建议把两者输出直接做字符串比较。排障时可以来回交叉验证但自动化脚本最好固定一种工具避免兼容性问题。最后一个小技巧在临时添加路由前先在测试环境或远端 VNC 会话里验证命令无误再在生产机器上执行。路由表这东西改错了比改少了难恢复得多。我自己就经历过一次想删默认路由结果把唯一的外网出口删了后面的所有操作都是靠同一机房另一台机器的带外管理完成的教训不可谓不深。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑