策略路由
策略路由,顾名思义就是根据一定的策略做的路由转发。普通的路由转发只根据报文的目的IP查找路由表,根据最长匹配来转发。策略路由,是根据一定的策略来确定转发下一跳,策略可以匹配报文的五元组,QOS标记等信息,通过策略路由可以更精确的指定转发路径。
如上图,左边的PC01和PC02要访问右边的Server,如果通过路由转发,会有两种情况:两台PC都走一条路径,两台PC根据负载分担机制随机走上面或者下面的路径(人工不可干预)。如果要实现精确的路径控制,即PC01的流量走上面,PC02的流量走下面,就要通过策略路由来实现。
Linux策略路由
Linux策略路由,依赖三个组件实现:nftables,ip rule,路由表。下面根据Linux转发流程图来分析:
报文进入Linux时,首先通过prerouting链,在该链中为报文设置meta mark,报文在Linux内部的整个转发过程都会携带这个标识,后续的Rouing模块,或者forward等其它链都可以看到这个标识并把他作为一个匹配条件。在本实验中,把PC01发出的报文标识成0x01,把PC02发出的报文标识成0x02:
//创建链,以根据源IP设置meta mark
nft add chain ip tb_0 meta_mark '{ type filter hook prerouting priority -150; }'
//针对来PC01的报文设置meta mark为0x1
nft add rule ip tb_0 meta_mark ip saddr 10.0.0.1 meta mark set 0x1
//针对来PC02的报文设置meta mark为0x1
nft add rule ip tb_0 meta_mark ip saddr 10.0.0.2 meta mark set 0x2
报文出prerouting链后进入Routing模块,Routing模块首先查找ip rule规则,由ip rule规则确定查找哪个路由表,默认的ip rule规则有三条,分别对应三个路由表:
ip rule的优先级数值越小,优先级越高。在查找ip rule的过程中,依次进入匹配规则对应的路由,如果查到对应路由就直接转发,不再继续匹配其它ip rule规则;如果在一个路由表没有查到对应的路由,就进入下一个规则对应的路由表,直到全部路由表都查找完。
默认优先级为0的ip rule不能删除及修改,它对应的路由表为local,由系统自动产生并更新,local表中有四种目的地址,本机接口的IP,本机接口的IP所属的网段,本机接口的IP所属的网段广播地址,环回地址(127.0.0.0/8)。即所有报文在Routing模块中都是首先查找一下,是否为上送本机的报文,不是上送本机的报文就进入下一个路由表继续查找。
系统缺省的ip rule规则中,local路由表之后就是main路由表,也是我们缺省的路由表,优先级为32766(优先级倒数第二),在本实验中,我们添加两条优先级高于32766的ip rule,匹配条件为prerouting链中设置的meta mark:
//PC01发出的报文,meta mark已经设置成0x1,在这里指定查找路由表pc01
ip rule add fwmark 0x1 table pc01 priority 3
//PC02发出的报文,meta mark已经设置成0x2,在这里指定查找路由表pc02
ip rule add fwmark 0x2 table pc02 priority 4
Linux系统通过 /etc/iproute2/rt_tables 文件维护路由表,默认只有三张路由表(和默认的ip rule对应):local,main和default。我们需要修改rt_tables 文件,在里面添加路由表pc01和pc02,每个路由表要有一个唯一的ID,修改之后的文件如下:
报文在转发过程中通过ip rule规则进入路由表查找路由,所以我们需要在对应路由表中添加对应的路由:
//进入路由表pc01的报文全部转发到Router1
ip route add default via 30.0.0.1 table pc01
//进入路由表pc02的报文全部转发到Router1
ip route add default via 40.0.0.1 table pc02
此至,Linux系统的策略路由就配置完成,PC01发出的报文走Router1,PC02发出的报文走Router2。在本实验中,prerouting链设置meta mark时,只匹配了源IP,在实际运用中,可以根据需求灵活设置匹配条件,以及满足实际的需求。