通过iptables与iproute2协同实现根据应用的策略路由
2011-01-19 16:01:58 阿炯

(前提:了解多路由表、策略路由的概念、熟悉iptables和iproute2工具包)

假设网络中有两个外部接口,IP地址分别为eth0:172.16.1.1/24,eth1:10.0.0.1/24,连接内部网络的接口为eth2:192.168.1.1。现在设计这样一个策略,将所有来自内部网络的web服务的数据,走向172.16.1.1这个出口,而其它的数据走向 10.0.0.1 这个出口。

#接口设置
ifconfig eth0 172.16.1.1 netmask 255.255.255.0
ifconfig eth1 10.0.0.1 netmask 255.255.255.0
ifconfig eth2 192.168.1.1 netmask 255.255.255.0
echo 1 >/proc/sys/net/ipv4/ip_forward

#将web服务类的数据包打上标示100
#这一步很关键,用于实现策略路由的是iproute2工具包,但是iproute2工具包是无法根据端口来进行匹配的,因此需要借助iptables来配合
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 100

#增加多路由表,假设172.16.1.1这一出口的网关是172.16.1.254
ip route add 0/0 via 172.16.1.254 table 100

#设置路由策略:凡是数据包标记位上是100的数据,查询100号路由表
ip rule add fwmark 100 table 100

#NAT 如果需要的话,进行NAT,不需要的话,就直接路由
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

这里主要是说明了把iptables和iproute2协同以后可以做出很多很强的应用,你可以利用iptables强劲的对数据报的识别能力来将不同类型的数据包打上你自己定义的标示,然后利用iproute2的策略路由的功能来进行路由。

关于策略性路由(iproute2)

策略性是指对于IP包的路由是以网络管理员根据需要定下的一些策略为主要依据进行路由的。例如我们可以有这样的策略:“所有来直自网A的包,选择X路径;其他选择Y路径”,或者是“所有TOS为A的包选择路径F;其他选者路径K”。Cisco 的网络操作系统 (Cisco IOS) 从11.0开始就采用新的策略性路由机制。而Linux是在内核2.1开始采用策略性路由机制的。策略性路由机制与传统的路由算法相比主要是引入了多路由表以及规则的概念。

多路由表(multiple Routing Tables)

传统的路由算法是仅使用一张路由表的。但是在有些情形底下,我们是需要使用多路由表的。例如一个子网通过一个路由器与外界相连,路由器与外界有两条线路相连,其中一条的速度比较快,一条的速度比较慢。对于子网内的大多数用户来说对速度并没有特殊的要求,所以可以让他们用比较慢的路由;但是子网内有一些特殊的用户却是对速度的要求比较苛刻,所以他们需要使用速度比较快的路由。如果使用一张路由表上述要求是无法实现的,而如果根据源地址或其它参数,对不同的用户使用不同的路由表,这样就可以大大提高路由器的性能。

规则(rule)

规则是策略性的关键性的新的概念。我们可以用自然语言这样描述规则,例如我门可以指定这样的规则:
规则一:“所有来自192.16.152.24的IP包,使用路由表10, 本规则的优先级别是1500”
规则二:“所有的包,使用路由表253,本规则的优先级别是32767”

我们可以看到,规则包含3个要素:
什么样的包,将应用本规则(所谓的SELECTOR,可能是filter更能反映其作用);
符合本规则的包将对其采取什么动作(ACTION),例如用那个表;
本规则的优先级别。优先级别越高的规则越先匹配(数值越小优先级别越高)。

策略性路由的配置方法

传统的linux下配置路由的工具是route,而实现策略性路由配置的工具是iproute2工具包。这个软件包是由Alexey Kuznetsov开发的。这里简单介绍策略性路由的配置方法,详细的使用方法请参考Alexey Kuznetsov写的 ip-cfref文档。策略性路由的配置主要包括接口地址的配置、路由的配置、规则的配置。

基于策略的路由比传统路由在功能上更强大,使用更灵活,它使网络管理员不仅能够根据目的地址而且能够根据报文大小、应用或IP源地址来选择转发路径。在/etc/iproute2/rt_tables的这个文件存有linux系统路由表,默认表有255 254 253三张表:
255  local 本地路由表存有本地接口地址,广播地址,已及NAT地址,local表由系统自动维护,管理员不能操作此表。
254  main 主路由表 传统路由表,ip route若没指定表亦操作表254,一般存所有的路由。
注:平时用ip ro sh查看的亦是此表设置的路由。

253  default 默认路由表一般存放默认路由。
注:rt_tables文件中表以数字来区分表0保留最多支持255张表 。

再看路由表默认的所有规则:
# ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default

规则0,它是优先级别最高的规则,规则规定,所有的包,都必须首先使用local表(254)进行路由。本规则不能被更改和删除。
规则32766,规定所有的包,使用表main进行路由。本规则可以被更改和删除。
规则32767,规定所有的包,使用表default进行路由。本规则可以被更改和删除。

在默认情况下进行路由时,首先会根据规则0在本地路由表里寻找路由,如果目的地址是本网络,或是广播地址的话,在这里就可以找到合适的路由;如果路由失败,就会匹配下一个不空的规则,在这里只有32766规则,在这里将会在主路由表里寻找路由;如果失败,就会匹配32767规则,即寻找默认路由表。如果失败,路由将失败。从这里可以看出,策略性路由是往前兼容的。

策略性路由的应用

基于源地址选路(Source-Sensitive Routing)
如果一个网络通过两条线路接入互联网,一条是比较快的ADSL,另外一条是比较慢的普通的调制解调器。这样的话,网络管理员既可以提供无差别的路由服务,也可以根据源地址的不同,使一些特定的地址使用较快的线路,而普通用户则使用较慢的线路,即基于源址的选路。

根据服务级别选路(Quality of Service)
网络管理员可以根据IP报头的服务级别域,对于不同的服务要求可以分别对待对于传送速率、吞吐量以及可靠性的有不同要求的数据报根据网络的状况进行不同的路由。

节省费用的应用
网络管理员可以根据通信的状况,让一些比较大的阵发性通信使用一些带宽比较高但是比较贵的路径一段短的时间,然后让基本的通信继续使用原来比较便宜的基本线路。例如,管理员知道,某一台主机与一个特定的地址通信通常是伴随着大量的阵发性通信的,那么网络管理员可以安排一些策略,使得这些主机使用特别的路由,这些路由是按需拨号,带宽比较高的线路,通信完成以后就停止使用,而普通的通信则不受影响。这样既提高网络的性能,又能节省费用。

负载平衡(Load Sharing)
根据网络交通的特征,网络管理员可以在不同的路径之间分配负荷实现负载平衡。

Linux系统IPv4/IPv6双栈接入优先使用IPv4设置


根据RFC3484协议Linux默认情况下IPv6优先级高于IPv4,应用程序优先使用IPv6地址。因部分场景下IPv6的使用不一定畅通,可以参照如下方式设置IPv4作为默认的连接方式。

1.使用IPv4连接优先,不禁用IPv6。需要修改gai.conf配置文件使其生效。编辑如下文件:
 /etc/gai.conf
 
查找如下配置,将前面的 # 去掉并保存,如果前面没有 # 号表示已经更改过设置了。如果没有查找到该行直接在文件末尾添加。
precedence ::ffff:0:0/96 100

Redhat默认没有 /etc/gai.conf  该文件,可以执行如下命令,拷贝该文件后修改:
cp -p /usr/share/doc/glibc-common-2.17/gai.conf /etc/

BC-linux执行如下命令:
cp -p /usr/share/doc/glibc-common/gai.conf /etc/

修改完成保存生效。采用此方式,双栈情况下优先使用IPv4,同时不影响IPv6的使用。

说明
::ffff:0:0/96 为IPv4/IPv6转换地址 (IPv4-mapped IPv6 address)。
 
2.如果确实不需要IPv6,可以采用如下方式禁用IPv6。
echo "1" > /proc/sys/net/ipv6/conf/all/disable_ipv6

如需恢复,删除掉 /proc/sys/net/ipv6/conf/all/disable_ipv6 文件即可。