多网卡配置路由策略可以简称为“源进源出”策略,顾名思义就是指从哪个网卡上进来就从哪个网卡上出去,这样做的目的是为了达到更好的访问效果。例如:配置实现三层内网和外网的同时访问、国内三线访问、国内外线路访问等。
CentOS 7.9
网卡配置
vi /etc/sysconfig/network-scripts/ifcfg-xxx
网卡1:访问互联网(默认路由)
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.20.10.10
NETMASK=255.0.0.0
#IPADDR1=10.20.10.11
#NETMASK1=255.0.0.0
GATEWAY=10.20.10.254
DNS1=223.6.6.6
#DNS2=114.114.114.114
DEFROUTE=yes
NAME=ens192
DEVICE=ens192
网卡2:访问三层局域网(换成其他公网一样配置)
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.123.2
NETMASK=255.255.255.0
#GATEWAY=192.168.123.254
DNS1=xxx.xxx.xxx.xxx
DEFROUTE=yes
NAME=ens160
DEVICE=ens160
NETMASK 可以用 PREFIX 代替,例如:PREFIX=8 表示 255.0.0.0
需要注意的是,网关只配置其中一个,作为默认路由。最后重启网络服务生效。
service network restart
添加路由表并配置路由策略
255 local、254 man、253 default 和 0 unspec 是已定义的路由表 ID 和对应的路由表名,理论上 linux 可以配置超过 255 个路由表,路由表 ID 数字命名除了已定义之外,也是可以命名 255 之外的数字的,只不过太巨大的话也会引发溢出问题。路由表名称以字母(大小写)、数字和下划线组成。虽然可以直接以纯数字命名,但缺乏可读性,建议还是根据路由表意义来命名。
cat << EOF >>/etc/iproute2/rt_tables
251 localnet
EOF
如果这里的网卡2是二层网络,则可以忽略这一步配置。
cat << EOF >>/etc/rc.local
ip route flush table localnet
ip route add default via 192.168.123.254 dev ens160 src 192.168.123.2 table localnet
ip rule add from 192.168.123.2 table localnet
EOF
生效
chmod 777 /etc/rc.local
/etc/rc.local
这里一定要添加执行权限,确保每次开机后自动执行生效。
优化版本
启用非默认路由的网卡
sed -i 's/^ONBOOT=.*/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-ens192
ifup ens192
创建开机执行脚本
chmod +x /usr/local/bin/pbr-chinanet.sh
nano /usr/local/bin/pbr-chinanet.sh
#!/bin/bash
TABLE_NAME=chinanet
TABLE_ID=251
# 如果路由表不存在,则添加
grep -qE "^[[:space:]]*$TABLE_ID[[:space:]]+$TABLE_NAME" /etc/iproute2/rt_tables || \
echo "$TABLE_ID $TABLE_NAME" >> /etc/iproute2/rt_tables
# 获取默认出口网卡
DEFAULT_DEV=$(ip route | grep default | awk '{print $5}')
# 找非默认网卡
CHINA_DEV=$(ip -o link show | awk -F': ' '{print $2}' | grep -v lo | grep -v "$DEFAULT_DEV" | head -n1)
# 获取IP
CHINA_IP=$(ip -4 addr show "$CHINA_DEV" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
# 网关默认 .1
CHINA_GW=$(echo "$CHINA_IP" | awk -F. '{print $1"."$2"."$3".1"}')
# 调试输出
echo "CHINA_DEV=$CHINA_DEV"
echo "CHINA_IP=$CHINA_IP"
echo "CHINA_GW=$CHINA_GW"
# 清理旧规则(避免重复)
ip rule del from "$CHINA_IP" table "$TABLE_NAME" 2>/dev/null
# 清空路由表
ip route flush table "$TABLE_NAME"
# 添加路由
ip route add default via "$CHINA_GW" dev "$CHINA_DEV" src "$CHINA_IP" table "$TABLE_NAME"
# 添加策略路由(指定优先级)
ip rule add from "$CHINA_IP" table "$TABLE_NAME" priority 100
添加到 systemd 管理
cat << EOF >/etc/systemd/system/pbr-chinanet.service
[Unit]
Description=Policy Routing for ChinaNet
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/pbr-chinanet.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
生效
systemctl daemon-reexec
systemctl daemon-reload
systemctl enable pbr-chinanet
systemctl start pbr-chinanet
Ubuntu 20.04
安装
apt install iproute2
添加路由表
cat << EOF >> /etc/iproute2/rt_tables
800 amazon_hk
EOF
网卡配置
# This is the network config written by 'subiquity'
network:
ethernets:
ens160:
addresses:
- 172.18.0.57/24
- 172.18.0.58/24
match:
macaddress: 00:50:56:aa:28:1f
mtu: 1500
nameservers:
addresses:
- 8.8.8.8
search: []
set-name: ens160
routes:
- to: 0.0.0.0/0
via: 172.18.0.254
table: 800
routing-policy:
- from: 172.18.0.57
table: 800
priority: 33300
ens192:
addresses:
- 192.168.111.94/24
match:
macaddress: 00:50:56:aa:37:79
mtu: 1500
gateway4: 192.168.111.65
nameservers:
addresses:
- 1.1.1.1
search: []
set-name: ens192
version: 2
优先级问题
出站路由
这里需要注意的是给路由表设置了优先级,这里是 33300,数字越小优先级越高。有时候配置好后网络仍然不可达,问题就出在优先级,我将优先级数字缩小到32000,网络就通了,猜测可能跟已定义的路由表优先级有关。
root@noc:~# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
33300: from 172.18.0.57 lookup amazon_hk
修改方法,先手动删除出站路由
ip rule del from 172.18.0.57
然后再去 netplan 配置文件将对应的priority: 33300修改为priority: 32000,修改完netplan apply一下就可以了。不明确添加这条优先级的话,默认为 0 最高,但是为了稳定和可维护性,尽量避免用 0 作为自定义规则的优先级。
优先级 0 是系统保留的规则优先级,新增可能导致:
本地套接字通信异常
某些守护进程依赖的回环解析被打断
行为不一致(尤其在绑定本地 IP 时)
通常建议 priority > 10000
明细路由
还有一种情况是当多个路由表匹配目标地址时,系统会选择最长前缀的路由,也就是 CIDR 前缀最大的那个。
路由表801:
routes:
- to: 1.1.1.0/24
via: 172.18.0.254
table: 801
routing-policy:
- from: 172.18.0.57
table: 801
priority: 32000
路由表802:
routes:
- to: 1.1.1.0/30
via: 172.18.0.254
table: 802
routing-policy:
- from: 172.18.0.57
table: 802
priority: 32000
毫无疑问,如果目标是去 1.1.1.1 的话,系统会选择路由表802。
配置静态路由
静态路由里面的 metric 表示优先级,较低的值同样表示较高的优先级。如果没有指定路由表,则添加的静态路由通常属于主路由表。
routes:
- to: 1.1.1.1
via: 172.18.0.254
metric: 0
配置生效
netplan generate && netplan apply


评论区