默认路由、静态路由、策略路由

By | 2023年5月11日

基础知识

默认路由是一种特殊的静态路由,目的网段为 0.0.0.0/0,当不确定你的目的地址时(如互联网访问)可以配置一条默认路由。

路由器在选择路由条目时,如果有两条去往相同目的网络的路由,会比较路由条目的优先级,选择优先级高的进行转发(值越小,优先级越高)。默认优先级举例:直连路由优先级0;静态路由优先级60;OSPF路由优先级10。

当路由表中有多条目的地址相同的路由时,会选择子网掩码最长的进行转发,若子网掩码相同,就根据优先级(metric)进行选路。

在配置静态路由时一定要注意它的单向性, 也就是要使双方能相互访问,须同时配置往返路径的两条静态路由,也就是通常所说的必须同时有回程路由。

双网卡,指定应用走哪个网卡

如果PC主机上插了两块物理网卡且都启用状态,那么就会生成两条默认路由:

default via 192.168.4.1 dev enp4s0 proto static metric 100
default via 192.168.3.1 dev enp3s0 proto static metric 101 

由于目的地址相同且第一条优先级高,因此主机上的所有应用都会走 192.168.4.1 网卡出去。

此时如何给主机内不同的应用分配不同的网卡?咨询了下网工,说控应用层要用专门的负载设备。后来结合具体场景发现不需要购买额外设备,设置下静态路由就好了。

配静态路由前,要先分析自己的场景,假设双网卡的服务器部署了2个Docker应用(A和B),A应用不对外提供服务只与阿里云固定IP的服务器通信(如访问数据库),B应用暴露服务器接口需要对外提供服务。

解决办法:由于A应用只会与固定外网IP通信,因此配置一条静态路由即可,无需用默认路由,将目的地址指向阿里云固定IP,网关地址两张网卡里随便选一个,配好后必须删除选择的那张网卡的默认路由(如果不删除,一旦另一张网卡的默认路由优先级低于这张时,数据包永远无法出去了,因为永远会选择这张错误的网卡的网关出去),这点很重要。对于B应用来说,由于要提供服务,因此目的地址是不固定的,数据可能会发送给任何互联网上的人,因此必须使用默认路由。

这种方式其实有个弊端,若A应用访问的固定IP改用CDN加速,或A应用有到第三方带域名的服务时(如OSS上传),由于CDN和OSS服务的IP不是固定的,也咨询了阿里云说没有一个大范围固定网段的,因此静态路由不适合这两种情况。解决办法就是使用策略路由,它可以根据源地址来选路

静态路由的添加删除

# 1. 添加到主机的路由
route add –host 192.168.1.10 dev eth0
route add –host 192.168.1.10 gw 192.168.1.1
route add -host 192.168.1.3 gw 172.16.0.1 dev eth0  # 其中dev eth0可以省略,但 gw 不能省,省了测试下来会无法路由的

# 2. 添加到网络的路由
route add –net 192.168.1.0/24 gw 192.168.1.1
route add –net 192.168.1.0/24 dev eth1
route  del  -net 192.168.32.7/32  gw 172.18.0.200  # 删除路由

# 3. 添加默认路由
route add default gw 192.168.1.1

# 4. 删除路由
route del –host 192.168.1.10 dev eth0
route del default gw 192.168.1.1
route  del  -net 192.168.32.7/32  gw 172.18.0.200  # 删除路由

# 5. 第一种查看路由
route -n
# 6. 第二种查看路由(结果可放 /etc/sysconfig/network-scripts/route-ethx 里,格式一样)
ip route

小提示:静态路由配置好后,测试是否生效可以分别用 traceroute xxxtraceroute yyy 两个命令来测试对比,其中 xxx 是静态路由的目的地址,yyy则不是,看他们经过的网关有何区别即可。

策略路由

对比传统的基于数据包目的地址的路由算法,基于策略的路由算法更加灵活。Linux是在内核2.1开始采用策略性路由机制的。

策略路由算法引入了多路由表以及规则的概念,支持按数据报属性(源地址、目的地址、协议、端口、数据包大小、内容等规则)选择不同路由表。

使用策略路由来配置双网卡的主机,让不同的Docker应用走不同的网卡,实在太有用了。

policy-route.sh:

#!/bin/bash

# 配置策略路由,让 172.18.0.0/16 网段的 Docker 应用走 enp4s0 这张网卡

# 第一步:先在路由表 30000 上添加一条默认路由,指向 enp4s0 网关
ip route add 0/0 via 192.168.3.1 dev enp4s0 table 30000
ip route list table 30000

# 第二步:配置规则,172.18.0.2 是 Docker应用的IP,让它的包走路由表 30000,优先级设置的高于 main 表,设为 30001 吧
ip rule add from 172.18.0.2/32 table 30000 pref 30001
ip rule

#注意:
#(1)重启电脑后,策略路由的规则和 路由表 30000 都会丢失!
#(2)添加、删除规则后,必须重启下Docker应用,否则Docker应用网络会出问题,若此脚本在Docker应用起来前执行就不需要重启了。
#(3)设好后,主机直连拨号路由器的Wifi似乎没有出现卡的现象了,若连作为交换机的二级路由器的Wifi网络就特别卡,把Wifi_5G关了仅保留Wifi_2.4G就好了。

ip rule:

删除策略路由:

# 删除路由表中的路由项:
ip route del default table 30000
ip route del 192.168.8.0/24 table 30000

# 删除策略路由规则:
ip rule del prio 30001
ip rule del from 172.18.0.0/16
ip rule del table 30000
ip rule del from 172.18.0.0/16 table 30000 prio 10

策略路由参考:
(1)Linux策略路由–原理、配置和应用
(2)Linux系列—策略路由、ip rule、ip route

路由重启持久化

个人推荐写一个开机启动服务,调用上面的 policy-route.sh 脚本即可实现持久化。

以 Ubuntu 22 为例,下面创建一个 rc-local.service 服务:

1. 创建 rc-local.service 文件

sudo cp /lib/systemd/system/rc-local.service /etc/systemd/system

然后修改 /etc/systemd/system/rc-local.service,在文件最下方添加如下两行:

[Install]   
WantedBy=multi-user.target   
Alias=rc-local.service

2. 创建 rc.local 文件

创建 /etc/rc.local,里边写自己想要运行的命令,例:

#!/bin/sh

#echo "This is test" > /tmp/my.log
/home/service/install/policy-route.sh

exit 0

/etc/rc.local 加上可执行权限:sudo chmod +x /etc/rc.local
然后就可以重启电脑,此时输入 ip rule 就已经创建出策略路由规则了。
systemctl status rc-local.service 命令检查服务运行是否报错了:

命令参考:

systemctl enable rc-local.service
systemctl start rc-local.service
systemctl status rc-local.service

traceroute

# 安装 traceroute
apt install traceroute

# 查找到 baidu.com 的路由
traceroute baidu.com

traceroute 命令将跟踪发往远程系统的 IP 包所经过的路由。可以使用这个命令查找所有的路由配置错误以及路由路径错误。如果无法到达特定的主机,则可以使用 traceroute 来查看发往远程主机的包所经由的路径以及可能出现故障的位置。

traceroute 命令还显示在通向目标主机的路径上每个网关的往返时间。此信息对于分析两个主机之间何处出现通信缓慢非常有用。

参考

网络工程师入门,如何配置静态路由?
简析静态路由下一跳和出接口区别
Linux系统添加永久静态路由的方法
Linux 双网卡双IP配置

FAQ

在为接口分配IP地址时,为什么需要指定子网掩码?

(1)路由器使用接口上配置的IP地址和掩码来确定该接口所连接的网络。主机将使用掩码来确定目标地址是否与主机位于同一网络上。如果它在其他网络上,则主机必须将第2层的流量发送到配置的网关,而不是直接发送到目的地。例如接口地址 192.168.203.82/24 属于 192.168.203.0/24 这个网络(网段)。

(2)子网掩码可以分离出IP地址中的网络地址和主机地址,那为什么要分离呢?因为两台主机要通信,首先要判断是否处于同一网段,即网络地址是否相同。如果相同,那么可以把数据包直接发送到目标主机,否则就需要路由网关将数据包转发送到目的地。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注