之前有配置过一些基本的策略路由,常见的应用场景都是基于 源/目的IP、网络接口、或者是在多接口或IP的情况下,实现数据包从哪个路径访问进来,就自动从原路网关返回的路由场景,比如服务器同时拥有多线接入时,智能响应从不同线路访问过来的请求;

今天刚好碰到一个新的场景,服务器单网卡,单IP配置,但网络中有两个 gateway 分别是走不同的出口线路,客户要求按应用服务类别区分,走不同的线路出口,比如用户访问http服务则必须从gateway1返回数据包,如果服务器要对外发送邮件,请求外部IP的SMTP服务,则必须通过gateway2出站访问,这是应用需求,必须要这样;因此就涉及到需要看应用协议类别,或者说是按请求的目的端口来进行路由选择;

本来是只想记录一下按应用端口进行策略路由的配置方法的,但发现现在记忆力是越来越差了,索性就把几种经常会用到策略路由模式都记录一下,也免得下一次要用到时又去满世界搜索资料;

基本概要

Linux 的策略路由是可以按需求建立多个路由表table来分类管理的,也就是我们可以根据不同的需求来建立对应的专用路由表,如果某个数据包符合相应的条件,则就根据对应的路由表中的具体路由条目来进行路由传输;
系统默认会建立有3个基本的table,这是在配置完系统基本的网路设定后就自动生成的,保证系统可以进行基本的网络通讯;使用ip rule show命令就可以列出系统当前所有的路由 table

#ip rule show
0:        from all lookup local
32766:    from all lookup main
32767:    from all lookup default

local路由表
保存的是所有跟本机IP地址地址相关的路由表条目,比如我们在本机直接访问127.0.0.1时要用到的路由表;

main路由表
保存的是本机与外界通讯的基本路由表条目,比如默认路由;通常我们用 route add 等命令添加的路由信息都是保存在这个路由表中的,用 route -n查看的路由信息也是这个表中保存的内容,可以理解为系统默认的基本路由表;

default路由表
默认是空的,通常不会用到,

查看某一个表中的具体路由条目:

#ip route show table main
192.168.2.0/24 dev eth0  proto kernel  scope link  src 192.168.2.100
169.254.0.0/16 dev lo  scope link
default via 192.168.2.254 dev eth0

除了系统默认的3个表以外,要配置策略路由我们就需要建立额外专用的路由表来保存我们自定义的特殊路由条目,同时也要定义好哪些符合条件的数据包是要根据这个路由表的条目来进行路由的;当一个数据包匹配了对应的条件,内核就会根据对应的路由表中所存储的路由条目来处理传输这个数据包;下面分别以举例的方式说明每一种不同条件的路由表建立方法:

基于Source IP的策略路由

#ip rule add from 192.168.200.0/24 table route1 prio 10
//来源为指定网段的数据包就按 route1 路由表中的条目处理,路由表优先级为10

#ip rule add from 192.168.66.10 table route2 prio 11
//来源为指定ip的数据包就按 route2 路由表中的条目处理,路由表优先级为11

#ip route add 202.101.77.13 via 192.168.2.1 table route1
//在route1路由表中添加一条到目的IP的路由条目使用192.168.2.1 这个下一跳网关

#ip route add default via 192.168.2.1 table route2
//在route2路由表中添加一笔默认路由,所有经过 route2 这个路由表处理的数据包,默认都通过192.168.2.1网关传输 

使用场景:
1,Linux作为路由或网关,针对内网不同的来源IP或来源网段,可以分别定义走不同的出口路由规则,划分流量,比如公司内部财务和行政部门网段的来源IP网段要上网,则使用电信线路的网关出去,其它部门及普通员工的IP或网段上网,则使用联通线路的网关出去;
2,对于Linux服务器本机网卡上有绑定多不同的IP地址对应到不同上网线路的场景时,可以根据本机响应回包的不同源IP地址定义策略路由,从指定线路的网关路由出去,实现一个IP一条线路专用;(这是基于在单个网卡上配置多IP的场景,如果是多网卡多IP的场景,那么可以直接以设备接口 dev 作为条件来配置策略路由,后面介绍)

基于Destination IP的策略路由

#ip rule add to 192.168.66.10 table route3 prio 12
#ip rule add to 192.168.200.0/24 table route4 prio 13
//原理跟基于 Source IP 的设定一样,只不过是根据数据包`to`的目标地址或网段来决定要依据哪一个路由表的规则来处理

使用场景:
1,要访问不同分公司的网段或服务器IP,则可以单独制定独立的路由表来处理
2,访问国内,或国外网段的目标网络或IP时,可以制定由不同的路由表来进行路由处理

基于网络设备dev的策略路由

#ip rule add dev eth0 table route5 prio 14
#ip rule add dev eth1 table route6 prio 15
//当数据包是从 eth0 进入时,则用 route5 路由表进行处理;从 eth1 接口进入的数据包则用 route6 路由表进行处理

使用场景:
最常用的场景就是,当服务器多网卡,多线路接入时,可保证从哪个网卡收到的请求,就从原路的路由进行返回;
当然我们也可以实现一些比较奇怪的需求,比如让所有从 eth0 进入的数据包,都从 eth1 接口转发出去等等;

基于数据包标记fwmark的策略路由

现在才是本文要写的重点,前面的都很好理解,基于数据包的源IP,目标IP,网卡设备dev来作为判断依据进行路由表的选择;那么fwmark 则是基于数据包的特征标记来作为判断依据进行路由表的选择;

那么如何给我们需要的数据包打上标记呢,这就要用到 Netfilter也就是iptables 的管理表 mangle 中的 mark 功能来实现,具体配置如下:

 #iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark 1
 //为本机发出的所有访问目标端口为25的数据包都设置 mark 值为 1

 #iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 2
 //为本机发出的所有访问目标端口为80的数据包都设置 mark 值为 2

 #ip rule add fwmark 1 table smtp-out prio 16
 //路由判断如果数据包的 mark 值为1,则依据路由表 smtp-out 中定义的路由规则来处理

 #ip rule add fwmark 2 table http-out prio 17
 //路由判断如果数据包的 mark 值为2,则依据路由表 http-out 中定义的路由规则来处理

我们知道 iptables 对于数据包的匹配是非常灵活的,因此我们就可以非常灵活的基于数据包的任何特征来进行分类 mark 标记,然后根据不同的 mark 值来灵活选择我们所希望的路由规则,因此就可以实现按应用协议,或是端口来进行策略路由的选择了;至于应用场景,文章开头有写,这里就不重复阐述了;

Last modification:March 10, 2019
如果觉得我的文章对你有用,请随意赞赏