在 Ubuntu 22.04 上,若需要通过 三条网卡 连接 移动、电信、联通 三个运营商,并使用不同的网卡分别走不同的出口,需要配置 策略路由 (Policy-Based Routing, PBR)。
✅ 1. 检查网卡名称
使用以下命令,确认当前系统的网卡名称:
ip link show
🛠️ 修改 Netplan 配置
假设三条线路如下:
网卡 | IP地址 | 网关 | ISP |
ens33 | 192.168.10.100 | 192.168.10.1 | 移动 |
ens34 | 192.168.20.100 | 192.168.20.1 | 电信 |
ens37 | 192.168.30.100 | 192.168.30.1 | 联通 |
编辑 /etc/netplan/00-installer-config.yaml
:
network:
version: 2
renderer: networkd
ethernets:
ens33: # 移动
dhcp4: no
addresses: [192.168.10.100/24]
routes:
- to: 0.0.0.0/0
via: 192.168.10.1
table: 100
routing-policy:
- from: 192.168.10.100
table: 100
nameservers:
addresses: [223.5.5.5, 114.114.114.114]
ens34: # 电信
dhcp4: no
addresses: [192.168.20.100/24]
routes:
- to: 0.0.0.0/0
via: 192.168.20.1
table: 200
routing-policy:
- from: 192.168.20.100
table: 200
nameservers:
addresses: [119.29.29.29, 223.6.6.6]
ens37: # 联通
dhcp4: no
addresses: [192.168.30.100/24]
routes:
- to: 0.0.0.0/0
via: 192.168.30.1
table: 300
routing-policy:
- from: 192.168.30.100
table: 300
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
✅ 2. 应用新配置
-
检查语法是否正确:
-
sudo netplan try
-
如果没有错误,永久应用:
-
sudo netplan apply
✅ 3. 验证路由是否生效
1. 查看路由表
ip route show table main # 查看主路由表
ip route show table 100 # 查看移动路由表
ip route show table 200 # 查看电信路由表
ip route show table 300 # 查看联通路由表
2. 查看策略路由
ip rule show
输出应该类似于:
0: from all lookup local
32764: from 192.168.30.100 lookup 300
32765: from 192.168.20.100 lookup 200
32766: from 192.168.10.100 lookup 100
32767: from all lookup main
✅ 4. 测试三网出口
1. 使用 ping
测试每个出口(这个测试是有问题的,不能用ping测试)
ping
ping -I ens33 baidu.com # 走移动
ping -I ens34 baidu.com # 走电信
ping -I ens37 baidu.com # 走联通
2. 验证外网 IP
curl --interface ens33 ifconfig.me # 走移动
curl --interface ens34 ifconfig.me # 走电信
curl --interface ens37 ifconfig.me # 走联通
📌 5. (可选) 设置流量分担(负载均衡)
如果希望系统自动分流,可以通过 weight
设置权重:
在每个 routes
下添加 weight
参数,示例:
routes:
- to: 0.0.0.0/0
via: 192.168.10.1
table: 100
weight: 1
-
weight: 1
表示每条链路均衡使用。 -
你可以根据需要调整权重,越大占比越高。
✅ 6. (可选) 防止 SNAT 出口错误
为防止路由回包不正确,需开启反向路径过滤(rp_filter):
临时设置:
sudo sysctl -w net.ipv4.conf.all.rp_filter=2
sudo sysctl -w net.ipv4.conf.default.rp_filter=2
永久生效:
在 /etc/sysctl.conf
文件中添加:
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
使配置立即生效:
sudo sysctl -p
🎯 总结
-
避免使用
gateway4
,改用routes
声明默认路由。 -
多出口策略路由:每个网卡使用独立的路由表。
-
验证与调试:通过
ping
和curl
检查每个运营商的连通性。 -
负载均衡(可选):通过
weight
让三网口均匀使用。
测试中遇到的问题:ping只能从默认的网卡出去,其他两个网卡不通,但是curl和traceroute正常。
🔎 为什么会出现这个问题?
-
ICMP(ping)使用系统默认路由表 (
main
表)-
默认情况下,
ping
只会走 主路由表(table main
)。 -
如果没有为其他运营商的流量设置 全局默认出口,
ping
无法通过非默认网卡出口。
-
-
TCP/UDP(curl)使用
SO_BINDTODEVICE
绑定接口-
curl
等工具可以直接绑定到某个 interface,而不依赖系统的默认路由。
-