策略路由介绍
为什么要用策略路由
路由有路由表,linux里面主要通过ip route查看路由表,但这个是main表,除了main表,还有通过rule、table构建的策略路由表,当服务器有多线路多出口的时候,如果仅仅依赖一个默认路由,会出现一些问题,比如从A发出去请求,回包的时候却是B收到了;源地址一般也是出口,如果源IP和出口IP不一样,数据包也可能出现丢弃的情况。策略路由的意义就是从哪儿发,就从哪儿当出口走。
常规的路由是
目标地址 -> main 表 -> 默认路由
策略路由是
源地址 / 条件 -> rule -> table -> route
它会在收到包后拆看src,然后看规则,规则下面会有一系列的table,默认的有0、32766、32767这些系统保留的表,那个32766就是咱们的main表,ip route就是查的它,然后在table里面找到路由,比如说前缀路由,默认路由,然后发包。
总结就是rule决定查什么table,route决定路由怎么走。
补充:
linux网络里面,数据包的查询其实是这个顺序,rule-table-route,但是,一般不看rule,因为它有默认三个表,主要看local和main
0: from all lookup local #local表
32766: from all lookup main #main表,最常用,ip route就是默认看这个
32767: from all lookup default #不研究,不用
多出口实验
下面简单介绍下策略路由的配置过程
假设场景:服务器静态多IP四条线路,每条线路都有自己的公网 IPv4、IPv6 和逻辑接口
vth.1@eth2 IPv4:39.152.39.24/24 IPv6:2409:8714:67b0::1ac/128 vth.2@eth3 IPv4:39.152.39.28/24 IPv6:2409:8714:67b0::1ad/128 vth.3@eth4 IPv4:39.152.39.29/24 IPv6:2409:8714:67b0::1ae/128 vth.4@eth5 IPv4:39.152.39.56/24 IPv6:2409:8714:67b0::1af/128
由于这边之前有过配置,直接执行清理rule操作
ip -6 rule flush
另外这里要说明一个边界,配置策略路由的时候,顺序可能和linux走路由不太一样rule->table->route,我们是需要先走一步,把table给配置好route,然后再用rule去绑定这个table表,因为rule不能指向空表(不存在),不是说没有route配置。
rule负责分类,查询什么表,table负责目标网段路由信息,如果rule没指定table,就默认进main表
重建表
ip -6 route flush table 1
这里之前尝试直接先加默认路由报错了
ip -6 route replace 2409:8714:67b0::/60 dev vth.1 table 1
提示 no route to host,需要先加一个到网关的直连路由再添加默认路由,这个是ipv6/128比较常见的,因为只有这一个单独地址要先加前缀路由
ip -6 route replace default via 2409:8714:67b0:: dev vth.1 src 2409:8714:67b0::1ac table 1
ip -6 route replace 2409:8714:67b0::/60 dev vth.1 table 1
table表配置完成后,再添加rule,根据src来添加
ip -6 rule add from 2409:8714:67b0::1ac/128 table 1
内核验证(route get,模拟返回,后续我尝试用tcpdump做了测试)
ip -6 route get 2400:3200::1 from 2409:8714:67b0::1ac
2400:3200::1 from 2409:8714:67b0::1ac via 2409:8714:67b0:: dev vth.1 table 1 src 2409:8714:67b0::1ac metric 1024 pref medium

其他几条线路以此类推,先创建table,写好route,然后绑定rule。
路由表
[root@CentOS764 ~]# route -6 -n Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2409:8714:67b0::/60 :: U 1024 1 0 vth.1 ::/0 2409:8714:67b0:: UG 1024 49 0 vth.1 2409:8714:67b0::/60 :: U 1024 1 0 vth.2 ::/0 2409:8714:67b0:: UG 1024 49 0 vth.2 2409:8714:67b0::/60 :: U 1024 1 0 vth.3 ::/0 2409:8714:67b0:: UG 1024 49 0 vth.3 2409:8714:67b0::/60 :: U 1024 1 0 vth.4 ::/0 2409:8714:67b0:: UG 1024 49 0 vth.4 ::/96 :: !n 1024 1 0 lo
抓包测试
以table 1的策略表来进行抓包测试
2409:8714:67b0::1ac dev vth.1 proto kernel metric 256 pref medium [root@CentOS764 ~]# ip -6 route show table 1 2409:8714:67b0::/60 dev vth.1 metric 1024 pref medium default via 2409:8714:67b0:: dev vth.1 src 2409:8714:67b0::1ac metric 1024 pref medium 提炼一下就是 src:2409:8714:67b0::1ac table:table1 接口:vth.1 网关:2409:8714:67b0:: 抓包逻辑1:-i 网卡vth.1, -nn,-vv, icmpv6(前面介绍过tcpdump) 会话1:tcpdump -ni vth.1 -e -vvv icmp6 -c 100 终端2:ping6 -I 2409:8714:67b0::1ac -c 100 2400:3200::1
如图所示:

抓包逻辑2:为验证策略路由,添加BPF限制src,dst和icmp6 tcpdump -ni vth.1 -vv -c 5 'icmp6 and src host 2409:8714:67b0::1ac and dst host 2400:3200::1' ping6 -I 2409:8714:67b0::1ac -c 5 2400:3200::1 无捕获: tcpdump -ni vth.2 -vv 'icmp6 and src host 2409:8714:67b0::1ac and dst host 2400:3200::1' tcpdump -ni vth.3 -vv \ 'icmp6 and src host 2409:8714:67b0::1ac and dst host 2400:3200::1' tcpdump -ni vth.4 -vv \ 'icmp6 and src host 2409:8714:67b0::1ac and dst host 2400:3200::1'

然后这里再啰嗦一下,那么如果全在main表里面,只放默认路由,那么依据跃点metric,内核可能根据优先级来选路,但是不能保证
源地址 ::1ac 必须走 vth.1
源地址 ::1ad 必须走 vth.2
源地址 ::1ae 必须走 vth.3
源地址 ::1af 必须走 vth.4
常用
常用检查命令 查看rule ip -6 rule show 查看路由表 ip -6 route show table x ip -6 route show table main(ip -6 route) 查看命中 ip -6 route get xxx from xxx(如果提示Network is unreachable一般是没在table里面配置好路由) 总结:策略路由不是为了让机器能上网,而是为了让指定源地址走指定出口。