简介:本资源是一份面向Linux系统运维人员与CentOS 7服务器管理员的静态路由配置实战指南,聚焦网络流量精准控制这一核心运维需求,系统解决临时路由添加、查看、删除及永久生效等关键问题。资源为单文件PDF文档(57KB),内容结构清晰:先以ip route命令详解动态路由操作全流程,含格式化显示技巧、多网段添加示例及连通性验证;再重点说明CentOS 7专属的永久路由配置机制——通过编辑/etc/sysconfig/network-scripts/route-接口名文件实现持久化,并涵盖重启网络服务、nmcli重连设备等生效方法,同时提示多网卡默认网关冲突等典型排错要点。目前已有6562人学习下载,内容覆盖命令实操、配置文件规范、常见异常现象分析,可直接用于生产环境部署与故障排查。
1. CentOS 7 添加静态路由:为什么ip route add一执行就失效,而/etc/sysconfig/network-scripts/route-ens33却能扛过重启?
你刚在 CentOS 7 虚拟机里配好双网卡:ens33 接内网(192.168.10.0/24),ens37 接管理网(10.0.5.0/24),现在要让内网用户能访问另一台位于 172.16.200.0/24 网段的监控服务器——它不走默认网关,必须走 ens37 的网关 10.0.5.1。你敲下ip route add 172.16.200.0/24 via 10.0.5.1 dev ens37,测试通了;可一 reboot,ip route show里干干净净,ping 172.16.200.10直接超时。更玄学的是,有人ip route add后ip route show没输出,route -n却有,还有人ip route add成功但ping不通,抓包发现回程包从 ens33 出去了——这根本不是路由没加,是回程路由和出站路由不匹配。这不是命令写错了,是 CentOS 7 的网络服务模型在“静默接管”你的手动操作。本文不讲教科书定义,只拆解真实生产环境里怎么让一条静态路由活过重启、跨服务、抗干扰:从ip route的瞬时性本质,到network-scripts的持久化机制,再到NetworkManager和systemd-networkd的冲突点,最后落到ip rule + ip route的策略路由实战。适合正在排查centos7 无法ping通百度、ip route 无输出、ensp静态路由配置对标验证失败的运维和虚拟化工程师。
2. 用ip route在本地跑通最小命令:加一条、删一条、查一条,三步闭环
ip route是 Linux 内核路由子系统的直接操作接口,它不依赖任何上层服务,只要内核活着,命令就生效。但它也正因如此,纯粹、短暂、不持久。理解它的行为边界,是避免后续所有“加了又丢”问题的前提。
2.1 加一条静态路由:ip route add的四个必填要素与两个隐含约束
ip route add 172.16.200.0/24 via 10.0.5.1 dev ens37 src 10.0.5.100172.16.200.0/24:目标网络,CIDR 格式,不可省略掩码(172.16.200.0会被当作主机路由);via 10.0.5.1:下一跳网关 IP,必须是本机直连网段可达的地址(即10.0.5.1必须能被ens37的 IP ping 通);dev ens37:出接口,强制指定数据包从哪个网卡发出。这是关键!若省略,系统会按路由表查找最优出口,可能选错网卡导致回程不一致;src 10.0.5.100:源地址,显式指定该路由产生的流量使用ens37的 IP(如10.0.5.100/24)作为源 IP。这是解决“能发不能收”的后悔药——很多centos7 无法ping通百度的案例,根源就是出包用ens33的 IP,回包却想从ens37进,被防火墙或对端策略丢弃。
提示:
via和dev不可同时省略;若只写via,系统自动推导出接口;若只写dev,则视为直连路由(onlink),需确保目标网络物理直连。
2.2 删一条静态路由:ip route del的精确匹配原则与批量清除技巧
删除必须严格匹配添加时的全部参数,否则报错RTNETLINK answers: No such process:
# ✅ 正确:参数完全一致 ip route del 172.16.200.0/24 via 10.0.5.1 dev ens37 src 10.0.5.100 # ❌ 错误:少一个 src,即使路由表里显示有,也删不掉 ip route del 172.16.200.0/24 via 10.0.5.1 dev ens37 # RTNETLINK answers: No such process # ⚠️ 批量清除:按目标网络前缀删(最常用) ip route flush 172.16.200.0/24 # ⚠️ 清除所有非默认、非本地路由(慎用!) ip route show | grep -v "^default\|^127.0.0.0\|^10\.\|^192\.168\." | awk '{print $1}' | xargs -r -I{} ip route del {}逻辑说明:ip route flush是按目标网络匹配删除,不校验via/dev/src,所以比del更鲁棒;而grep + xargs方案用于清理测试环境残留,但会误删其他业务路由,生产环境禁用。
2.3 查一条静态路由:ip route get比show更接近真实转发路径
ip route show只是 dump 当前路由表快照,而ip route get模拟内核实际查表过程,带源/目的IP,结果更可信:
# 查看去往 172.16.200.10 的完整路径(含出接口、源IP、下一跳) ip route get 172.16.200.10 from 10.0.5.100 iif ens37 # 输出示例: # 172.16.200.10 from 10.0.5.100 via 10.0.5.1 dev ens37 src 10.0.5.100 uid 0 # cachefrom 10.0.5.100:模拟源IP,验证src参数是否生效;iif ens37:指定入接口(in-interface),用于策略路由调试;- 输出中的
src值必须与你期望的一致,否则回程必然异常; cache表示命中路由缓存,若无此行,说明未命中,需检查路由优先级或策略规则。
参数说明:ip route get是诊断“为什么不通”的黄金命令。当你ping不通却ip route show看着路由存在时,90% 的情况是get返回的src或dev不符合预期——这直接暴露了路由表冲突或策略缺失。
3. 把静态路由写进文件:/etc/sysconfig/network-scripts/route-ens37的格式陷阱与加载时机
CentOS 7 默认使用network-scripts服务(/etc/init.d/network)管理网络,其持久化静态路由的唯一标准位置是/etc/sysconfig/network-scripts/route-<interface>。这个路径名里的<interface>必须与ifconfig或ip link show中的网卡名完全一致(区分大小写、含数字),且文件必须由 root 创建、权限为644。很多人卡在“文件写了但重启没生效”,90% 是栽在这三个细节上。
3.1 两种合法格式:ADDRESS0/NETMASK0vs172.16.200.0/24 via 10.0.5.1 dev ens37
格式一:传统 KEY=VALUE 风格(兼容性最好,推荐)
# 文件:/etc/sysconfig/network-scripts/route-ens37 ADDRESS0=172.16.200.0 NETMASK0=255.255.255.0 GATEWAY0=10.0.5.1ADDRESS0,NETMASK0,GATEWAY0:序号0表示第一条路由,1表示第二条,以此类推;GATEWAY0必须是直连网关(10.0.5.1必须属于ens37的子网);- 不支持
src参数,若需指定源IP,必须用格式二或策略路由。
格式二:ip route命令风格(更直观,但需注意空格)
# 文件:/etc/sysconfig/network-scripts/route-ens37 172.16.200.0/24 via 10.0.5.1 dev ens37- 每行一条路由,语法与
ip route add完全一致; - 支持
src、onlink、metric等所有ip route参数; - 关键陷阱:行尾不能有多余空格,行首不能有空格,空行会被忽略但可能干扰解析。
提示:我一般用格式二,因为
ip route add xxx测试成功后,直接复制粘贴进文件即可,零学习成本。但务必用cat -A route-ens37检查是否有^M(Windows 换行)或^I(tab),这些都会导致加载失败。
3.2 加载时机:network-scripts何时读取 route 文件?ifup和systemctl restart network的区别
route-<interface>文件只在对应网卡启动时加载,触发方式有两种:
- 手动启卡:
ifup ens37→ 自动读取/etc/sysconfig/network-scripts/route-ens37; - 重启 network 服务:
systemctl restart network→ 依次ifdown所有已启网卡,再ifup所有配置文件中ONBOOT=yes的网卡 → 仅加载这些网卡对应的 route 文件。
# ✅ 正确流程(推荐) # 1. 编辑 route-ens37 vi /etc/sysconfig/network-scripts/route-ens37 # 2. 确保 ens37 配置中 ONBOOT=yes grep ONBOOT /etc/sysconfig/network-scripts/ifcfg-ens37 # 应输出 ONBOOT=yes # 3. 重启 network 服务(等效于重载所有网卡) systemctl restart network # 4. 验证 ip route show | grep 172.16.200- ❌
systemctl restart network不会加载ONBOOT=no的网卡的 route 文件; - ❌
ifup ens37时,若ens37已处于 UP 状态,route-ens37不会重新加载(这是血泪经验!); - ✅ 最稳妥的验证方式:
systemctl restart network后,用journalctl -u network --since "1 minute ago"查看日志,搜索route-ens37,应看到Adding static routes for ens37。
3.3 多网卡多路由:route-eth0、route-eth1、route-bond0共存的加载顺序与冲突规避
当机器有多个网卡(如ens33,ens37,bond0)且都需静态路由时,文件命名必须严格匹配ifconfig输出的接口名:
# 查看真实接口名(别信 ifcfg-* 文件名!) ip link show | awk -F': ' '/^[0-9]+:/ {print $2}' | grep -v "lo$\|virbr$\|docker$\|veth" # 输出示例:ens33 ens37 bond0 # 对应创建三个文件: /etc/sysconfig/network-scripts/route-ens33 /etc/sysconfig/network-scripts/route-ens37 /etc/sysconfig/network-scripts/route-bond0- 加载顺序 =
ifup顺序 =/etc/sysconfig/network-scripts/ifcfg-*中DEVICE=值的字母序(bond0在ens33前); - 冲突点:若
route-ens33和route-ens37都配置了10.0.0.0/8,后加载的会覆盖先加载的(因路由表按 metric 和 prefix length 排序,非文件顺序); - 规避方法:为不同网卡的相同目标网络设置不同
metric(优先级),数值越小越优先:
# /etc/sysconfig/network-scripts/route-ens33 10.0.0.0/8 via 192.168.10.1 dev ens33 metric 100 # /etc/sysconfig/network-scripts/route-ens37 10.0.0.0/8 via 10.0.5.1 dev ens37 metric 200这样,当10.1.1.1同时可达ens33和ens37时,系统优先选metric 100的路径。
4. 避坑:CentOS 7 静态路由的 5 个高频翻车现场与根因修复
静态路由在 CentOS 7 上看似简单,实则深陷服务模型、内核版本、网络管理器三方博弈。以下 5 条是我在 20+ 家客户现场亲手踩过、抓包确认、日志溯源的真问题,每条都附带现象 → 原因 → 解决闭环。
4.1 现象:ip route add成功,ip route show有记录,但ping不通,tcpdump -i ens37 icmp显示请求包出去了,响应包却从ens33进来
- 原因:Linux 内核的
rp_filter(反向路径过滤)启用。当响应包进入ens33,内核检查其源IP172.16.200.10是否应从ens33的路由返回,发现172.16.200.0/24路由指向ens37,判定为“伪造包”,直接丢弃。 - 解决:临时关闭(验证用)→ 永久关闭(生产需评估安全)→ 或启用宽松模式(推荐):
# 临时关闭(立即生效) echo 0 > /proc/sys/net/ipv4/conf/ens33/rp_filter echo 0 > /proc/sys/net/ipv4/conf/ens37/rp_filter # 永久关闭(写入 sysctl.conf) echo "net.ipv4.conf.ens33.rp_filter = 0" >> /etc/sysctl.conf echo "net.ipv4.conf.ens37.rp_filter = 0" >> /etc/sysctl.conf sysctl -p # ✅ 推荐:宽松模式(允许响应包从任意接口进,只要路由存在) echo "net.ipv4.conf.all.rp_filter = 2" >> /etc/sysctl.conf echo "net.ipv4.conf.default.rp_filter = 2" >> /etc/sysctl.conf sysctl -p注意:
rp_filter=2是宽松模式,1是严格模式(默认),0是关闭。生产环境建议用2,兼顾安全与多路径。
4.2 现象:route-ens37文件内容正确,systemctl restart network后ip route show无新增路由,journalctl -u network无错误日志
- 原因:
network-scripts服务被NetworkManager抢占。CentOS 7 默认并存network和NetworkManager两个服务,后者会接管所有ONBOOT=yes的网卡,导致ifup不走network-scripts流程,route-<iface>被忽略。 - 解决:二选一:
- 方案 A(推荐):停用
NetworkManager,专一使用network-scripts:systemctl stop NetworkManager systemctl disable NetworkManager systemctl restart network - 方案 B:保留
NetworkManager,改用nmcli配置静态路由(见第 5 章)。
- 方案 A(推荐):停用
4.3 现象:ip route add后ip route show无输出,但route -n能看到,且ping通
- 原因:
route -n读取的是内核AF_INET路由表(老接口),ip route show读取的是netlink接口(新接口)。当系统存在iproute2版本过低或内核模块异常时,两者视图不一致。 - 解决:升级
iproute并重启网络:yum update iproute -y systemctl restart network # 验证 ip route show && route -n | grep -E "(172\.16\.200|10\.0\.5)"
4.4 现象:route-ens37配置了172.16.200.0/24 via 10.0.5.1,但ip route get 172.16.200.10返回dev ens33,而非ens37
- 原因:存在更高优先级的路由(如
172.16.0.0/16的直连路由或默认路由),覆盖了你的/24路由。 - 解决:用
ip route show table all查全表,定位冲突路由:ip route show table all | grep -E "(172\.16\.|default)" | sort -k1,1 # 若发现 172.16.0.0/16 via ... dev ens33,则需删除或调整 metric ip route del 172.16.0.0/16 # 或为你的路由设更低 metric(优先级更高) echo "172.16.200.0/24 via 10.0.5.1 dev ens37 metric 50" > /etc/sysconfig/network-scripts/route-ens37 systemctl restart network
4.5 现象:虚拟机中配置route-ens37,重启后路由存在,但宿主机ping虚拟机新路由网段不通
- 原因:VMware/VirtualBox 的虚拟交换机(vSwitch)未开启混杂模式(Promiscuous Mode),或宿主机防火墙拦截了非默认网段流量。
- 解决:
- VMware Workstation:右键虚拟机 → Settings → Network Adapter → NAT Settings → Advanced → Promiscuous Mode → Accept;
- VirtualBox:
VBoxManage modifyvm "VMName" --nicpromisc2 allow-all; - 宿主机 Windows:关闭 Windows Defender 防火墙,或添加入站规则放行
172.16.200.0/24。
5. 进阶:用ip rule + ip route实现策略路由,彻底解决回程路由和静态路由的区别难题
当业务要求“来自192.168.10.0/24的流量必须走ens33出,回程也必须从ens33进”,而172.16.200.0/24的流量必须走ens37出,此时普通静态路由已失效——因为内核路由决策只看目的IP,不看源IP。这就是回程路由和静态路由的区别的本质:静态路由管“去哪”,策略路由管“谁去、怎么去、怎么回”。ip rule是 Linux 策略路由的核心,它让路由表不再唯一。
5.1 策略路由三步法:建表、写规则、填路由
以“192.168.10.0/24源IP的流量走table 100,10.0.5.0/24源IP走table 200”为例:
Step 1:创建自定义路由表(写入/etc/iproute2/rt_tables)
# 追加两行,格式:ID NAME(ID 100~252 为用户可用) echo "100 table_100" >> /etc/iproute2/rt_tables echo "200 table_200" >> /etc/iproute2/rt_tablesStep 2:为每个表添加路由(ip route add ... table <ID>)
# table 100:192.168.10.0/24 的流量走 ens33 网关 ip route add default via 192.168.10.1 dev ens33 src 192.168.10.100 table 100 ip route add 192.168.10.0/24 dev ens33 scope link table 100 ip route add 127.0.0.0/8 dev lo scope link table 100 # table 200:10.0.5.0/24 的流量走 ens37 网关 ip route add default via 10.0.5.1 dev ens37 src 10.0.5.100 table 200 ip route add 10.0.5.0/24 dev ens37 scope link table 200 ip route add 127.0.0.0/8 dev lo scope link table 200Step 3:添加策略规则(ip rule),绑定源IP到表
# 规则优先级数字越小越先匹配(0~32767) ip rule add from 192.168.10.0/24 table 100 ip rule add to 192.168.10.0/24 table 100 # 回程也走 table 100 ip rule add from 10.0.5.0/24 table 200 ip rule add to 10.0.5.0/24 table 200 # 查看规则链 ip rule show # 0: from all lookup local # 32764: from 10.0.5.0/24 lookup table_200 # 32765: from 192.168.10.0/24 lookup table_100 # 32766: from all lookup main # 32767: from all lookup default逻辑说明:
ip rule是匹配引擎,ip route table X是数据平面。当包进来,内核按rule顺序匹配from/to,命中后查对应table的路由。to规则确保回程包也走同一张表,彻底解决“回程路由和静态路由的区别”——静态路由只管出,策略路由管出+回。
5.2 持久化策略路由:/etc/sysconfig/network-scripts/rule-ens33与rule-ens37
network-scripts支持策略路由持久化,文件名同route-<iface>,内容为ip rule命令格式:
# /etc/sysconfig/network-scripts/rule-ens33 from 192.168.10.0/24 table 100 to 192.168.10.0/24 table 100 # /etc/sysconfig/network-scripts/rule-ens37 from 10.0.5.0/24 table 200 to 10.0.5.0/24 table 200然后,在对应网卡的ifcfg-<iface>中添加:
# /etc/sysconfig/network-scripts/ifcfg-ens33 POSTUP="ip route add default via 192.168.10.1 dev ens33 src 192.168.10.100 table 100; ip route add 192.168.10.0/24 dev ens33 scope link table 100; ip route add 127.0.0.0/8 dev lo scope link table 100" PREDOWN="ip route flush table 100" # /etc/sysconfig/network-scripts/ifcfg-ens37 POSTUP="ip route add default via 10.0.5.1 dev ens37 src 10.0.5.100 table 200; ip route add 10.0.5.0/24 dev ens37 scope link table 200; ip route add 127.0.0.0/8 dev lo scope link table 200" PREDOWN="ip route flush table 200"重启network后,ip rule show和ip route show table 100将自动生效。
5.3 验证策略路由:ip route get+tcpdump双保险
策略路由不能只信ip route show,必须用真实流量验证:
# 从 192.168.10.100 发起 ping,看走哪张表 ip route get 172.16.200.10 from 192.168.10.100 # 抓包确认出接口 tcpdump -i ens33 -n icmp and host 172.16.200.10 & tcpdump -i ens37 -n icmp and host 172.16.200.10 & # 从本机 ping,观察哪个接口有包 ping -I 192.168.10.100 -c 3 172.16.200.10 ping -I 10.0.5.100 -c 3 172.16.200.10如果from 192.168.10.100的 ping 包只在ens33抓到,from 10.0.5.100的只在ens37抓到,说明策略路由已精准生效。
我在线上环境部署策略路由时,养成了一个铁律:每次修改rule或route table,必做三件事——ip rule show看规则链顺序、ip route get模拟源IP查表、tcpdump -i any抓全接口包验证流向。曾有一次因rule优先级写错(把32765写成32766),导致所有流量 fallback 到main表,花了 2 小时才定位。希望帮到你。
本文还有配套的精品资源,点击获取