一、前言
日常维护工作中,有时候会遇到单台主机多张网卡的情况,尤其云上环境,云主机多张网卡是一种常见网络配置场景,那如何让多网卡正常工作呢,本期基于此北京,回顾下Linux策略路由的相关知识;
策略路由PBR:(Policy-Based-Route),也称为源路由,它是一种比基于目标网络进行路由更加灵活的数据包路由转发机制。该技术打破了路由表的传统选路规则,可以根据管理维护人员自定义的策略条件(如源 IP 地址、源端口和协议类型)来选择性的转发数据包。Linux 使用 路由策略数据库 RPDB (Routing Policy DataBase,它是存放策略的数据库) 来实现基于策略的路由系统(policy based routing system)。RPDB 支持多个路由表RHEL 中,默认情况下的内核决定使用路由表是根据目标地址转发网络数据包,而基于策略的路由允许我们可以配置复杂的路由场景,比如当代系统网络服务NetworkManager,systemd管理的OS,比如:多网卡的情况,比如更自由灵活的网络策略需要场景,比如基于管理目的QoS需求或VPN拓扑结构中要求某些路由必须经过特定的路径的场景;但应用策略路由,须指定策略路由使用的路由图,这个路由图/表要事先定义号。
路由表/图存储关于网络的路由表信息。它们通过数值或名称标识,从Linux-2.2开始,内核把路由归纳到许多路由表中,这些表的编号数字的范围是1到255,可在 /etc/iproute2/rt_tables
文件中配置,默认情况下,所有的路由都会被插入到表main(编号254)中。在进行路由查询时,内核只使用默认路由表main。其中,一个路由图由很多条策略组成,每个策略都定义了1 个或多个的匹配规则和对应操作,规则用于根据数据包的特定属性选择路由表。当一个接口应用策略路由后,将对该接口接收到的所有包进行检查,而不符合路由图/表任何策略的数据包将按照linux内默认的路由策略转发进行处理,符合路由图中某个策略的数据包则按照该策略中定义的操作进行处理。
相关资源:RHOSP 动态路由、基于策略的路由、策略路由、Redhat KB、网络笔记、routing policy database management
二、策略路由配置应用
2.1、策略路由种类
大体上分为两种:
- 目的地址路由:根据路由的目的地址来进行的策略;
- 源地址路由:根据路由源地址来进行策略实施
策略路由规则由三部分组成:
- 优先级,也就是0 32766 32767,数字越小优先级越高
- 条件,from all或者from 172.12.16.0/24
- 操作,lookup main或者lookup 231;确定数据包应该如何处理,如转发到特定的下一跳、阻止或允许传输等
2.2、策略路由工作原理
其中主要涉及 rule(决定走策略哪个表) 和 table(策略路由的具体转发规则,至少因包含默认网关) 2个域,那rule和table又是如何协作的呢?默认定义其中的规则会根据优先级依次遍历,直到决策出下一跳;我们可以使用ip route
命令来定义基于策略的现有路由配置;其中,Rhel中支持写入对应的接口静态路由文件:/etc/sysconfig/network-scripts/rule-enp1s0 ;另外,NetworkManager 支持 policy-routing,但尚不支持规则,规则必须由运行自定义脚本的用户进行配置。系统启动过程中NetworkManager 会检查 /etc/init.d/进行网络检查,因此可配置etc/init.d/network
脚本完成特定网络配置。
例如: 一个IP报文源地址是135.105.115.180, 目的地址是155.18.49.20,路由策略显示如下:
ip rule show #或ip ru ls查看策略路由;ip rule show可以查看当前RPDB中的规则
#第一列:表示该路由表被匹配的优先顺序,数字越小,越早被匹配。范围是0~32767。默认0、32766、32767三个优先级别已被占用。
#第二列:from,这里显示的是匹配规则,当前表示的是从哪里来的数据包,其中,
#From -- 源地址
#To -- 目的地址(这里是选择规则时使用,查找路由表时也使用)
# Tos -- IP包头的TOS(type of sevice)域
# Dev -- 物理接口
# Fwmark -- 防火墙参数
#第三列:loacl/main/default, 这些都是路由表名称,表示数据包要从那个路由表送出去。local表包含本机路由及广播信息,main表就是我们route -n看到的内容,default表,默认为空。
#每条策略路由的规则由一个选择器 和一个动作 组成,RPDB按照优先级顺序进行规则匹配,优先级数字越小越优先
0: from all lookup local #第一优先级,可以通过prio 路由ID 在设置路由表时添加优先级;local表记录本地路由,它是一个特殊的路由表,包含本地地址和广播地址的高优先级控制路由, 如访问127.0.0.1就是参考的这条规则,loopback地址的路由就在local表里,另外本地接口地址,广播地址及NAT地址也都放在这个表,该路由表由系统自动维护
32765: from 135.105.115.149 lookup 231 #否则从32765往前递进分配优先级
32766: from all lookup main #主路由表,ip route等效ip route show table main,ip route打印的就是主路由表里的路由
32767: from all lookup default #FIB table((Forwarding Information Base)表),每个路由器都至少保存着一张路由表和一张FIB,通过路由表选择路由,通过FIB表指导报文进行转发。默认是一个空表
如上所示,会经过如下判断:
1、判断路由策略0, 符合条件from all, 去查找local 路由表,local表(local和broadcast)中根据目的地址,最长匹配规则找不到路由
2、进而判断路由策略路由32765, 该策略源地址是135.105.115.149的, 去查找231号表,并根据该231表中的route规则处理流程。
3、 不满足的话进而判断32766, 该路由策略的条件是from all满足。 去查找路由表main(route -n显示的,跟ip r s输出的规则一样), 其中可以找到下一跳, 进而转发IP包。
4、一般策略路由比本地路由表优先,路由会先匹配策略路由,如果匹配上了就直接按照路由策略转发,如果匹配不上才会看路由表;
cat /etc/iproute2/rt_tables
#路由表名称或编号,在这里可定义路由表,一般可以定义1-255一共255张路由表,剔除预留的三张表之后,实际上可以自由定义1-252即252张路由表。但是实际上由系统支持的路由表数量是有限的,取决于操作系统的配置和内核参数。
#
# reserved values
#
255 local
254 main
253 default
251 eth1 #比如这里自定义一个eth0的路由表
0 unspec
#
# local
#
#1 inr.ruhep
#策略路由:网卡分配单独路由表规则模版:
ip route add default via 子网网关 dev 网卡名称 table 路由表名称 #先添加路由表的默认网关
ip route add 子网网段 dev 网卡名称 table 路由表名称 #再加段路由
ip rule add from 网卡地址 table 路由表名称 #最后加源控制策略规则;做完该策略路由后,可以保证用ip作为源去通信是正常的,但是如果以eth0、eth1的网卡名称作为源访问还是不通的,因为策略路由是根据from后面的ip来匹配的。如果要以eth0、eth1的网卡名称作为源去通信,需要在路由表中添加针对 dev 的路由,执行:
route add default gw 172.18.1.1 dev eth1 metric 100 #注意要加metic,一般eth0是100或101
#验证
ip [-6] rules show table eth1 #显示策略路由规则 中引用了 表 eth2 的规则(即哪些条件会触发使用表 25 的路由),决定数据包应该查询哪张路由表
ip [-6] route show table eth1 #显示该策略路由表中的路由规则,它来决定路由,上面的只决定表选择,正常会输出如下:
default via 2409::12df:1 dev eth1 metric