应使用 if-up.d 目录下的可执行脚本添加静态路由,因其在物理网卡 ifup 完成、IP 配置完毕后按字典序执行;需校验接口名、避免重复添加,并注意 systemd-networkd 会绕过该机制。

ifup-post 脚本不是标准网络服务的执行入口,真正生效、可控且被 network 服务(RHEL/CentOS 系列)或 ifupdown(Debian/Ubuntu)调用的是 ifup 链式脚本机制中的 if-up.d 目录下可执行文件 —— 你想要的“物理网卡启动后自动加路由”,靠写 if-up.d 脚本最稳妥。
if-up.d 脚本里加静态路由的正确姿势
if-up.d 下的脚本会在每个网卡 ifup 完成、IP 地址已配置、接口已 UP 后按字典序执行。它天然满足「物理网卡启动后」这个时序要求。
- 脚本必须是可执行文件(
chmod +x),且以#!/bin/bash开头 - 接收两个参数:
$1是接口名(如eth1),$2是可选的“配置段名”(通常忽略) - 判断是否为你要操作的物理网卡,避免对
lo、docker0等误操作:if [ "$1" = "eth1" ]; then ip route add 10.20.0.0/16 via 10.20.1.1 dev eth1 fi
- 不要用
route命令:它不支持 IPv6、不输出错误码、已被标记为 legacy;统一用ip route - 检查路由是否已存在再添加,防止重复执行报错(比如多次
ifup eth1):if ! ip route show | grep -q "10.20.0.0/16.*via.*10.20.1.1"; then ip route add 10.20.0.0/16 via 10.20.1.1 dev eth1 fi
为什么不用 /etc/rc.local 或 ifup-post
-
/etc/rc.local在所有服务启动末尾运行,此时网卡可能尚未完成 DHCP 或多 IP 绑定,ip route add很容易因接口未就绪而失败 -
ifup-post并非所有发行版都启用,且 RHEL 系统中它只是ifup内部调用的一个钩子函数,不对外暴露为可编辑脚本路径 -
if-up.d是跨发行版兼容性最好的方案:RHEL/CentOS/Fedora 使用network服务时会调用;Debian/Ubuntu 的ifupdown也原生支持
注意网卡命名与 systemd-networkd 的冲突
如果你的系统启用了 systemd-networkd(常见于较新 Ubuntu Server、Fedora CoreOS 或手动启用场景),if-up.d 将完全不触发 —— 因为 systemd-networkd 不走传统 ifup/ifdown 流程。
- 查看当前网络管理器:运行
ls /run/systemd/network/或systemctl is-active systemd-networkd - 若
systemd-networkd活跃,则应改用.network文件的[Route]段:[Route] Destination=10.20.0.0/16 Gateway=10.20.1.1 Interface=eth1
- 否则,坚持用
if-up.d,但确保你的网卡配置文件(如/etc/sysconfig/network-scripts/ifcfg-eth1)中设置了ONBOOT=yes,否则ifup不会自动触发它
真正容易被忽略的是:路由添加时机依赖于接口状态,而接口状态又依赖于底层驱动加载和 udev 重命名规则。比如 enp0s31f6 这类预测性命名,在老旧脚本里硬写 eth0 会导致路由永远加不上。务必用 ip link show 确认真实接口名,并在脚本里做精确匹配。











