ip route命令只是简单地将数据包根据目标网络进行路由,而策略路由ip rule允许你根据多种条件(如源IP地址、出站设备、TOS值等)来选择使用哪张路由表。
策略路由的设置流程如下:
flowchart TD
A[数据包流出] --> B{“ip rule 策略规则<br>匹配条件?”}
B -- 匹配成功 --> C[查询对应的路由表]
C --> D[执行该路由表中的路由规则]
B -- 不匹配默认规则 --> E[查询main路由表]
E --> D
subgraph Pre [策略路由三要素]
F[rt_tables<br>定义路由表别名]
G[route-<interface><br>定义各路由表规则]
H[ip rule<br>定义查询路由表的策略]
end
H --> B
F -- 为表ID提供易记名称 --> G
G --> C
1. 规划:确定你的需求(如基于源IP分流、基于目的IP分流等)。
假设你有两张网卡:
- eth0: 连接公司内网,IP 192.168.1.100,网关 192.168.1.1
- eth1: 连接互联网,IP 10.0.0.100,网关 10.0.0.1
目标:让来自 192.168.1.100的流量走 eth0的网关,来自 10.0.0.100的流量走 eth1的网关。
2. 路由表标识数据库/etc/iproute2/rt_tables
Linux 内核支持多达 255 张路由表,每张表都有自己的ID。系统预定义了几张:
- 255local: 本地路由表,由内核自动维护,包含本地地址和广播地址的路由,不可修改。
- 254main: 主路由表,传统的 route命令和 ip route(不加 table参数)操作的就是这张表。
- 253default: 默认路由表,通常为空。
可以在这个文件里添加自己的表。例如:
#
# reserved values
#
255 local
254 main
253 default
#
# custom tables
#
100 mynet
200 vpntunnel
这样,在后续的 ip route和 ip rule命令中,你就可以使用 mynet或 vpntunnel来代替难记的数字 100或 200。
3. 使用命令测试:ip rule和 ip route命令
这是直接与内核交互的命令行工具,配置会立即生效,但重启后丢失,持久化见下面的第4节。
a. 向自定义路由表添加路由:
# 向 mynet 表添加默认路由
$ ip route add default via 192.168.1.1 dev eth0 table mynet
# 向 vpntunnel 表添加默认路由
$ ip route add default via 10.0.0.1 dev eth1 table vpntunnel
b. 添加策略规则,指定何时查询这些表:
# 添加规则:如果数据包的源IP是 192.168.1.100,就查询 mynet 表
$ ip rule add from 192.168.1.100 lookup mynet
# 添加规则:如果数据包的源IP是 10.0.0.100,就查询 vpntunnel 表
$ ip rule add from 10.0.0.100 lookup vpntunnel
c. 验证配置:
# 查看所有策略规则(数字越小优先级越高)
$ ip rule show
# 查看某张路由表的路由条目
$ ip route show table main
$ ip route show table mynet
$ ip route show table vpntunnel
d. 测试网络连通性是否符合预期。
其他常用策略规则示例:
- 基于目的地址的路由:
ip rule add to <目标网段> lookup <表名> - 强制特定网卡发出的包使用指定表(基于出站设备):
ip rule add iif <设备名> lookup <表名>(注意是 iif,入站接口,常用于本机产生的流量,可视为来自 lo设备)。 - 数据包标记:结合 iptables给数据包打标记,然后基于标记路由:
ip rule add fwmark <标记> lookup <表名>
4. 使用nmcli来持久化
# 创建 mynet 路由配置
$ sudo nmcli connection add type ethernet con-name "mynet-routing" ifname eth0 \
ipv4.method disabled \
ipv4.routes "0.0.0.0/1 192.168.1.1, 128.0.0.0/1 192.168.1.1" \
ipv4.routing-rules "priority 1000 from 192.168.1.100 lookup 1000"
# 创建 vpntunnel 路由配置
$ sudo nmcli connection add type ethernet con-name "vpntunnel-routing" ifname eth1 \
ipv4.method disabled \
ipv4.routes "0.0.0.0/0 10.0.0.1 table=2000" \
ipv4.routing-rules "priority 2000 from 10.0.0.100 lookup 2000"
或者,使用配置文件
$ sudo tee /etc/NetworkManager/dispatcher.d/99-custom-routes << 'EOF'
#!/bin/bash
if [ "$1" = "eth0" ] && [ "$2" = "up" ]; then
# 为 mynet 表添加默认路由
ip route add default via 192.168.1.1 dev eth0 table mynet 2>/dev/null
# 添加策略路由规则
ip rule add from 192.168.1.100 lookup mynet 2>/dev/null
fi
if [ "$1" = "eth1" ] && [ "$2" = "up" ]; then
# 为 vpntunnel 表添加默认路由
ip route add default via 10.0.0.1 dev eth1 table vpntunnel 2>/dev/null
# 添加策略路由规则
ip rule add from 10.0.0.100 lookup vpntunnel 2>/dev/null
fi
EOF
$ sudo chmod +x /etc/NetworkManager/dispatcher.d/99-custom-routes
验证配置:
# 重启 NetworkManager
sudo systemctl restart NetworkManager
# 或者重新加载连接
sudo nmcli connection reload
# 激活连接
sudo nmcli connection up "mynet-routing"
sudo nmcli connection up "vpntunnel-routing"
# 验证路由表
ip route show table mynet
ip route show table vpntunnel
# 验证路由规则
ip rule show
附录A NetworkManager 和 systemd-networkd 的区别
NetworkManager: “智能"的网络管理,能够自动处理复杂的、变化的网络环境。
- 配置文件位置:/etc/NetworkManager/
- 命令行工具: nmcli
- 图形化工具: nmtui
- 判断是否启用的NetworkManager:
nmcli device status
# 配置有线连接
sudo nmcli connection add type ethernet con-name office ifname eth0 ip4 192.168.1.100/24 gw4 192.168.1.1
# 配置Wi-Fi连接
sudo nmcli device wifi connect "MyWiFi" password "mypassword"
systemd-networkd:简单、可靠、可预测的网络配置,深度集成到 systemd 生态中。
- 配置文件位置:/etc/systemd/network/
- 命令行工具: networkctl
- 查看命令属于哪个包:
- 在基于RPM的系统:
rpm -qf $(which networkctl) - 在基于Debian的系统:
dpkg -S $(which networkctl)
- 在基于RPM的系统:
- 判断是否启用的systemd-networkd:
networkctl list
# 配置文件:/etc/systemd/network/50-wired.network
[Match]
Name=eth0
[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=8.8.8.8
附录B 检查 /etc/sysconfig/network-scripts 目录是否可用的脚本
在新版本的 RHEL/CentOS 8+ 和大多数现代 Linux 发行版中,传统的 /etc/sysconfig/network-scripts/方式可能不再被默认支持。
#!/bin/bash
echo "=== 检查 /etc/sysconfig/network-scripts 是否可用 ==="
# 1. 检查目录是否存在
if [ ! -d "/etc/sysconfig/network-scripts" ]; then
echo "❌ 目录不存在 - 完全不可用"
exit 1
fi
echo "✅ 目录存在"
# 2. 检查网络服务
if systemctl status network.service &>/dev/null; then
echo "✅ network.service 存在"
else
echo "⚠️ network.service 不存在(可能已弃用)"
fi
# 3. 检查 NetworkManager
if systemctl is-active NetworkManager &>/dev/null; then
echo "✅ NetworkManager 正在运行"
# 检查插件支持
if grep -q "ifcfg-rh" /etc/NetworkManager/NetworkManager.conf 2>/dev/null; then
echo "✅ NetworkManager 支持 ifcfg-rh 插件"
else
echo "⚠️ NetworkManager 可能不使用 ifcfg-rh 插件"
fi
fi
# 4. 检查包状态
if rpm -q network-scripts &>/dev/null || dnf list installed network-scripts &>/dev/null; then
echo "✅ network-scripts 包已安装"
else
echo "❌ network-scripts 包未安装 - 功能受限"
fi
# 5. 检查是否有实际配置文件
if ls /etc/sysconfig/network-scripts/ifcfg-* &>/dev/null; then
count=$(ls -1 /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | wc -l)
echo "✅ 找到 $count 个 ifcfg 配置文件"
else
echo "⚠️ 没有找到 ifcfg 配置文件"
fi
echo ""
echo "=== 判断结果 ==="
if systemctl is-active NetworkManager &>/dev/null && \
! systemctl status network.service &>/dev/null && \
! rpm -q network-scripts &>/dev/null; then
echo "❌ /etc/sysconfig/network-scripts 基本不可用"
echo " 建议使用 nmcli 或系统默认网络配置方法"
elif [ -f "/etc/sysconfig/network-scripts/ifcfg-*" ] && \
systemctl status network.service &>/dev/null; then
echo "✅ /etc/sysconfig/network-scripts 可用"
else
echo "⚠️ /etc/sysconfig/network-scripts 功能受限"
echo " 可能存在兼容性问题,建议逐步迁移到新方法"
fi
或者:
# 1. 备份现有配置(如果有)
sudo cp /etc/sysconfig/network-scripts/ifcfg-* /tmp/backup/ 2>/dev/null || true
# 2. 创建一个测试配置(如果不存在eth0,换成你的实际接口名)
sudo tee /etc/sysconfig/network-scripts/ifcfg-testeth0 << 'EOF'
DEVICE=testeth0
BOOTPROTO=none
ONBOOT=no
TYPE=Ethernet
IPADDR=192.168.99.99
NETMASK=255.255.255.0
EOF
# 3. 尝试重启网络服务
sudo systemctl try-restart network 2>/dev/null || sudo nmcli connection reload
# 4. 检查配置是否被加载
nmcli connection show | grep testeth0
ip addr show | grep 192.168.99.99
# 5. 清理测试配置
sudo rm -f /etc/sysconfig/network-scripts/ifcfg-testeth0
sudo systemctl try-restart network 2>/dev/null || sudo nmcli connection reload
传统配置持久化 /etc/sysconfig/network-scripts/ 的相关文件:
ifcfg-<interface>: 如 ifcfg-eth0,定义网卡的基本配置(IP、网关等)。这里的网关会被写入 main表。route-<interface>: 如 route-eth0,用于向 main路由表添加静态路由。rule-<interface>: 用于为特定网卡定义策略路由规则。route-<interface>-<table_name>: 这是关键文件。用于为自定义路由表(如 mynet)添加路由规则。
-
创建自定义路由表规则: 将成功的
ip route ... table ...命令写入/etc/sysconfig/network-scripts/route-<interface>-<table_name>文件。$ cat /etc/sysconfig/network-scripts/route-eth0-mynet default via 192.168.1.1 dev eth0 table mynet $ cat /etc/sysconfig/network-scripts/route-eth1-vpntunnel default via 10.0.0.1 dev eth1 table vpntunnel -
创建策略规则:将成功的
ip rule ...命令的条件部分写入/etc/sysconfig/network-scripts/rule-<interface>文件。$ cat /etc/sysconfig/network-scripts/rule-eth0 from 192.168.1.100 lookup mynet $ /etc/sysconfig/network-scripts/rule-eth1 from 10.0.0.100 lookup vpntunnel -
重启网络服务 systemctl restart network,以加载配置并自动生成相应的 ip rule和 ip route命令。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 极客油画 」找到我。

