Linux下策略性路由的实现
时间:2006-11-27 来源:tomcent_2006
Linux下策略性路由的实现
Routing Based on Policy under Linux
(胡正银 中科院成都文献情报中心)
摘要:
本文描述了策略性路由的概念,并详细解释了在Linux操作系统中与策略性路由实现相关的策略路由数据库RPDB及RPDB包含的路由定义规则,规则包含的键值。通过设定不同的规则及改变这些规则的查找顺序与优先级,可以根据需要定义不同的功能强大的策略路由。本文并根据实际应用情况,由简单到复杂给出了五个策略路由应用的例子。
Abstract:
This article interprets the concept of policy routing and the policy routing database of linux. Under linux with above kernel 2.2 ,the article introduce how to get powerful and user-defined routing policy through setting different
Rules of PRDB , its priors and changing the sequences of these rules. And the
Article also gives some actual examples to help apply.
关键词:
策略性路由,策略路由数据库(RPDB),多路由表,路由选择
Keywords:
Policy routing, RPDB, multiple routing tables, routing choosing
一.概述
目前在计算机网络中使用的传统路由算法都是根据IP包目的地址进行路由选择.然而在现实应用中经常有这样的需求:进行路由选择时不仅仅根据数据报的目的地址,而且根据数据报的其他一些特性如:源地址、IP协议、传输层端口,甚至是数据包的负载部分内容,这种类型的路由选择被称作基于策略的路由。基于策略的路由为网络管理者提供了比传统路由协议对报文的转发和存储更强的控制能力,传统上,路由器用从路由协议派生出来的路由表,根据目的地址进行报文的转发。基于策略的路由比传统路由强,使用更灵活,它使网络管理者不能够根据目的地址而且能够根据,报文大小,应用或IP源地址来选择转发路径。策略可以定义为通过多路由器的负载平衡或根据总流量在各线上进行转发的服务质量(QOS)。策略路由使网络管理者能根据它提供的机定一个报文采取的具体路径。而在当今高性能的网络中,这种选择的自由性是很需要的。
Cisco 的网络操作系统 (Cisco IOS) 从11.0开始就采用新的策略性路由机制。而Linux是在内核2.1开始采用策略性路由机制的。策略性路由机制与传统的路由算法相比主要是引入了多路由表以及规则的概念。
二.Linux下策略路由的实现
Linux策略性路由是由RPDB实现的(routing policy database),RPDB通过包含的一些规则来选定合适的IP路由。这些规则可能会包含很多各种不同类型的健值(key),因此这些规则没有默认的特定次序,规则查找次序或规则优先级都是由网络或系统管理员设定的。Linux的RPDB是一个由数字优先级值进行排序的线性规则列表。RDPB主要由多路由表和规则组成。路由表以及对其的操作和其对外的接口是整个RPDB的核心部分。路由表主要由table,zone,node这些主要的数据结构构成。对路由表的操作主要包含物理的操作以及语义的操作。路由表除了向IP层提供路由寻找的接口以外还必须与几个元素提供接口:与用户的接口(即更改路由)、proc的接口、IP层控制接口、以及和硬件的接口(网络接口的改变会导致路由表内容的改变)。处在RDPB的中心的规则,由规则选取表。IP层并不直接使用路由表,而是通过一个路由适配层,路由适配层提供为IP层提供高性能的路由服务。 RPDB能匹配数据报源地址、目的地址、TOS、进入接和fwmark值等。每个路由策略规则由一个选择器和一个动作指示组成。RPDB按照优先级递增的顺序被扫描,RPDB包含的每条规则的选择器被应用于数据报的源地址、目的地址、进入接口、TOS和fwmark值。若数据报匹配该规则对应于该规则的动作被执行。若动作成功返回,则规则输出将是一个有效的路由或是路由查找失败指示;否则查找RPDB的下一条规则。
Linux,启动时内核将包含一个由三条策略规则组成的默认的RPDB,察看这些默认规则的一个方法是使用命令来列出系统的所有规则:
root@netmonster ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
默认规则在对于理解启动复杂路由系统是非常重要的。
首先是最高级别的优先级规则,规则策略0:
规则0: 优先级 0 选择器 = 匹配任何数据报, 动作=察看本地路由表(routing table local),ID为255。local表是保留路由表,包含了到本地和广播地址的路由。规则0是特殊的规则,不可被删除或修改。
规则 32766: 优先级 32766 选择器 = 匹配所有数据报, 动作 = 察看主路由表(routing table main), ID为254。 main路由表是默认的标准路由表,其包含所有非策略路由,main表是存放旧的路由命令(route命令)创建的路由。而且任何由ip route命令创建的没有明确指定路由表的路由都被加入到该路由表中。该规则不能被删除和被其他规则覆盖。
规则 32767: 优先级 32767 选择器 = 匹配所有数据报, 动作 = 察看默认路由表(routing table default),ID为253。default路由表是空的,为最后处理(post-processing)所预留,若前面的默认规则没有选择该数据报时保留用作最后的处理。该规则可以被删除。
Linux策略规对应的动作除了指向一个路由表以外还能是若干种不同的动作。当创建一个策略规则,有如下类型的动作可以选择:
unicast -- 在该规则指向的路由表中进行标准的路由查找。当一个路由表被指定,这是默认的动作。
blackhole -- 规则动作将仅仅直接丢弃该数据报。
unreachable -- 规则动作产生一条网络不可达错误信息,一个类型为3,代码为0的ICMP消息被返回给发送者。
prohibit -- 规则动作产生一个通信被禁止的错误消息,一个类型为3,代码为13的ICMP消息被返回给发送者。
在讨论了命令语法以后,下面是一些具体实施示例。
例 1:拒绝访问Internet
假设有一个防火墙连接本地局域网和Internet,你希望禁止局域网的一个子网访问Internet。当然这可以通过Linux数据报过滤防火墙来实现。但是下面我们将介绍另外一种实现方法。首先我们来假设有如下的网络配置:
内部网络地址 192.168.0.0/16
被拒绝访问的子网 192.168.2.0/24
root@netmonster# ip route list table 254
default via 192.168.254.254 dev eth0 proto static
下面将针对该子网创建一条策略路由规则:
ip rule add from 192.168.2.0/24 priority 5000 prohibit
现在任何从192.168.2.0/24子网发送来的数据报将得到一个类型为3,代码为13的ICMP消息,同时该数据报将被丢弃。
应该注意的是,在运行任何这些命令都需要发送“ip route flush cache"命令来刷新路由缓冲,否则命令在一段时间以后才会生效,这段时间的长短依赖于路由表结构的大小和负载。
将上面的例子需要的命令放在一起就如下所示:
ip rule del priority 5000
ip rule add from 192.168.2.0/24 priority 5000 prohibit
ip route flush cache
这个命令流通过首先删除5000号规则来确保当前系统没有该规则然后再添加新的5000号规则。如果系统本来不存在5000号的规则则会返回一个错误信息。然后添加5000号规则并通过清空运行时的路由缓存来重置RPDB,则新规则将马上产生作用。
例 2:创建多个路由表
通过为路由表命名,就可以使用表数字ID或表名来引用路由表。例如下面两个命令将对同一个路由表进行操作:
ip route list table 1
ip route list table goodnet1
通过表名可以更好的理解在对哪个路由表进行操作。如果已经创建了如上所示的rt_table信息,可以通过下面的命令来察看各个路由表的内容:
ip route list table <name>
当然即使没有定义rt_table文件同样可以使用数字来引用所有的0-255个路由表,因为它们都是存在的,只是其中大部分没有路由信息数据罢了。
下面的例子是向定义的每个路由表都添加一条路由:
ip route add 10.10.10.0/24 via 192.168.1.2 table goodnet1
ip route add 10.10.11.0/24 via 192.168.1.2 table goodnet2
ip route add 10.10.12.0/24 via 192.168.1.2 table badnet1
ip route add 10.10.13.0/24 via 192.168.1.2 table badnet1
ip route add default via 192.168.1.254 table internet
然后再通过ip rouite list talbe <name>命令就可以察看路由表中的各个路由。
例3:多路由表和IP地址
Linux内核路由代码最强大的特色就是基于策略的路由和使用多地址、多路由表的结合使用。下面的示例讨论的是一个充当路由器的连接三个不同的网络的系统。
screen.width-333)this.width=screen.width-333" border=0>
,可核心系统的外部接口连接了三个外部网络。每个网络都有自己的路由器和自己的IP地址空间。但是其中的两个地址空间是重叠的,因此增加了情况的复杂性。这里我们设置如下规则的路由表来实现互联:
从任何内部网络到Inetent的数据流都是允许的。
从内部网B到网络A的数据流是允许的。
从内部网A到网络C的数据流是允许的。
内部网A的地址为33-62的主机允许访问网络A。
内部网B的地址为65-78的主机允许访问网络C。
首先,配置两个外部IP地址-在DMZ以太网接口eth0的两个地址:
ip addr add 10.254.254.2/30 dev eth0
ip addr add 172.17.1.128/24 dev eth0
下一步将讨论创建哪些路由表,解决这个问题的最好办法是想到基于策略的路由能实现根据源地址来决定使用哪个路由表。策略规则具有划分内部网络的能力,因此首先可以在路由表中添加基于目的的路由,在示例中我们将使用前面创建的新的路由表。
当在路由表中添加路由时下面的方法有助于澄清应该采取的步骤。假设你配置的是只有两个接口的路由器,外接口直接连接Interet出口路由器,而内接口直接连接内部网络。配置这样的路由器是非常简单的,操作如下: ip route add 10.10.0.0/16 via 10.254.254.2 table goodnet1 proto static
ip route add default via 172.17.1.254 table goodnet1 proto static
对于goodnet2进行配置则是:
ip route add 172.18.0.0/16 via 172.17.1.1 table goodnet2 proto static
ip route add default via 172.17.1.254 table goodnet2 proto static
可以看到对三个目标网络只需要两个路由表,这里对于连接Internet的默认路由在两个表中都进行了设置。为什么不将默认路由存放在第三个路由表中呢?首先应该考虑到规则和路由表之间的交互,而且规则是实现对基于策略路由的定义。多条规则可以指向同一个路由表。然而,一旦进入某个路由表以后,则只能是匹配一条路由或返回一条路由链。如果匹配到一条规则则就认为你已经拥有一条正确的策略匹配,则该规则指向的路由表包含了该数据报所有的路由可能。
如果有三个路由表,则需要添加一条规则来察看数据报目的。而检查数据报目的地址是标准路由的功能。为什么要对每种源、目的的组合都需要一个规则呢?通过使用路由表,可以实现定义尽量少的规则来达到目的。当然 系统的灵活性允许通过多条方法来实现这样的路由。
ip rule add from 192.168.1.32/27 to 172.18.0.0/16 pref15000 table goodnet1 ip rule add from 192.168.2.64/28 to 10.10.0.0/16 pref 15001 table goodnet2
ip rule add from 192.168.1.0/24 pref 15002 table goodnet1
ip rule add from 192.168.2.0/24 pref 15003 table goodnet2
上面的例子中使用了优先级参数设定来定义数据报匹配规则的顺序。现在来看看当一个数据报从内部网络经过路由系统时会发生什么情况。首先,它会通过优先级为0的规则检查;随后会遇到优先级为15000的规则,若匹配则会被goodnet1这个路由表进行操作,否则将会分别经过15001、15002、15003的规则。它肯定会被15000-15003几个规则中的一个所匹配。
下面为了说明定义路由结构的灵活性,我们将从另外一个角度来解决这个问题。Linux路由器的详细情况如下:
eth0 - DMZ ethernet - addresses: 10.254.254.2/30, 172.17.1.128/24
eth1 - Internal A - addresses: 192.168.1.254/24
eth2 - Internal B - addresses: 192.168.2.254/24
首先假设重新开始,将重新定义路由和规则,首先编辑/etc/iproute2/rt_tables:
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# Local Tables
#
1 int1
2 int2
创建路由和规则:
ip route add 10.10.0.0/16 via 10.254.254.1 table int1 proto static
ip route add throw 0/0 table int1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 table int2 proto static
ip route add throw 0/0 table int2 proto static
ip route add 0/0 via 172.17.1.254 table main proto static
ip rule add pref 15000 table int1 iif eth1
ip rule add pref 15001 table int2 iif eth2
ip rule add pref 15002 to 10.10.0.0/16 table int1
ip rule add pref 15003 to 172.18.0.0/16 table int2
例 3:简单基于fwmard的策略路由
在指定策略规则时可以使用的一个选项就是允许通过fwmark值来匹配某个规则。fwmark是一个数字标签,数据报过滤工具iptables能将fwmark值附加给某个数据报。例如上例多路由表,希望实现来自内部网B的、目的端口为80的数据发送到Internet,但是来自内部网A的、目的端口为80的数据则被禁止。首先清空这些路由表:
ip route flush table goodnet1
ip route flush table goodnet2
ip route flush table badnet1
ip route flush table badnet2
ip route flush table internet
ip route flush cache
而目前删除策略规则的方法就是将其一一列出来然后将其手工删除,也就是首先通过ip rule list命令将策略规则列出来然后使用ip rule del priority <#>将其删除。但这里假设当前没有任何规则并且路由表也是空的。
为了使用fwmark标记,首先应该指定希望使用iptables标记的数据报,然后使用标记值来指定一条策略规则来处理该数据报。应该设定ipchians自动将十进制的标记转化为十六进制。ip rule希望输入为一个十六值。
首先配置iptables规则使用合适的值标记输入数据报。假设当前没有其他防火墙规则:
iptables -I input -p tcp -s 192.168.2.0/24 -d 0/0 80 -m 2
iptables -I input -p tcp -s 192.168.1.0/24 -d 0/0 80 -m 16
现在设立策略规则,在上面为内部网A的标记值为十机制的16,下面定义相关的策略:
ip rule add fwmark 2 table goodnet1
ip rule add fwmark 10 prohibit
最后为路由表goodnet1定义如下的路由:
ip route add default via 172.17.1.254 table goodnet1
策略路由和IP伪装之间交互,在转发链之前对路由表进行查询。这意味着如果使用IP伪装,则路由选择器返回的任何源地址都将被作为进行IP伪装的地址。
例4: IP地址的IP伪装
使用上面的网络配置,我这里将对到三个网络的连接进行伪装处理,希望从系统中得到如下的输出:
从内部网A到网络C的数据报被伪装为10.254.254.2
从内部网络B到网络A的数据报被伪装为172.17.1.2
内部网到互联网的数据报都被伪装为172.17.1.128
eth0配置有如下地址:
10.254.254.2/30
172.17.1.128/24
因此为了满足条件2,给eth0添加地址:
ip addr add 172.17.1.2/32 dev eth0
假设系统被设置为对所有的输出数据报都进行IP伪装。首先清空旧的策略规则,然后创建新的规则如下:
ip route add 10.10.0.0/16 via 10.254.254.2 src 10.254.254.2
table goodnet1 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table goodnet1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.2
table goodnet2 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table goodnet2 proto static
ip rule add from 192.168.1.0/24 pref 15000 table goodnet2
ip rule add from 192.168.2.0/24 pref 15001 table goodnet1
例5:综合实例
假设上述例中的路由、规则和地址仍然在起作用,而希望实现下面的需求:
Internal A Hosts 33-62 to Network A Masq as 172.17.1.3
Internal A Hosts 65-78 to tcp port 80 on Network A Masq as 172.17.1.4
Internal B Hosts 33-62 to tcp port 80 on Network A Deny Access
Internal B Hosts 65-78 to tcp port 80 on Network C Masq as 10.254.254.2
下面就是解决方案:
ip addr add 172.17.1.3/32 dev eth0
ip addr add 172.17.1.4/32 dev eth0
ip route del default table goodnet1
ip route del default table goodnet2
ip route add throw 0/0 table goodnet1 proto static
ip route add throw 0/0 table goodnet2 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table internet proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.3
table badnet1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.4
table badnet2 proto static
ip rule add from 192.168.1.32/27 to 172.18.0.0/16 pref 14999 table badnet1
ip rule add fwmark 1 pref 14998 table badnet2
ip rule add fwmark 2 pref 14997 table goodnet1
ip rule add fwmark 3 pref 14996 blackhole
ip rule add pref 15003 table internet
iptables -I input -p tcp -s 192.168.1.64/28 -d 172.18.0.0/16 80 -m 1
iptables -I input -p tcp -s 192.168.2.64/28 -d 10.10.0.0/16 80 -m 2
iptables -I input -p tcp -s 192.168.2.32/27 -d 172.18.0.0/16 80 -m 3
其实有很多的有效方法,上述路由规则设置只是其一而已。
三.策略性路由的应用
基于源地址选路( Source-Sensitive Routing)
如果一个网络通过两条线路接入互联网,这样的话,网络管理员既可以提供无差别的路由服务,也可以根据源地址的不同,使一些特定的地址使用较快的线路,而普通用户则使用较慢的线路,即基于源址的选路。
根据服务级别选路(Quality of Service)
网络管理员可以根据IP报头的服务级别域,对于不同的服务要求可以分别对待对于传送速率、吞吐量以及可靠性的有不同要求的数据报根据网络的状况进行不同的路由。
节省费用的应用
网络管理员可以根据通信的状况,让一些比较大的阵发性通信使用一些带宽比较高但是比较贵的路径一段短的时间,然后让基本的通信继续使用原来比较便宜的基本线路。例如,管理员知道,某一台主机与一个特定的地址通信通常是伴随着大量的阵发性通信的,那么网络管理员可以安排一些策略,使得这些主机使用特别的路由,这些路由是按需拨号,带宽比较高的线路,通信完成以后就停止使用,而普通的通信则不受影响。这样既提高网络的性能,又能节省费用。
负载平衡(Load Sharing)
根据网络交通的特征,网络管理员可以在不同的路径之间分配负荷实现负载平衡。
四.小结
Linux具有强大路由功能,它提供的路由功能是很多路由器产品都是难以匹敌的, 如果考虑到它的免费性,它的性能价格比更是没有任何产品可以相比。
参考文献:
1. Policy Routing in Linux
http://www.samag.com/documents/s=1169/sam0001f/0001f.htm
2. Linux策略性路由应用及深入分析
http://www.yesky.com/20021212/1644092.shtml
Routing Based on Policy under Linux
(胡正银 中科院成都文献情报中心)
摘要:
本文描述了策略性路由的概念,并详细解释了在Linux操作系统中与策略性路由实现相关的策略路由数据库RPDB及RPDB包含的路由定义规则,规则包含的键值。通过设定不同的规则及改变这些规则的查找顺序与优先级,可以根据需要定义不同的功能强大的策略路由。本文并根据实际应用情况,由简单到复杂给出了五个策略路由应用的例子。
Abstract:
This article interprets the concept of policy routing and the policy routing database of linux. Under linux with above kernel 2.2 ,the article introduce how to get powerful and user-defined routing policy through setting different
Rules of PRDB , its priors and changing the sequences of these rules. And the
Article also gives some actual examples to help apply.
关键词:
策略性路由,策略路由数据库(RPDB),多路由表,路由选择
Keywords:
Policy routing, RPDB, multiple routing tables, routing choosing
一.概述
目前在计算机网络中使用的传统路由算法都是根据IP包目的地址进行路由选择.然而在现实应用中经常有这样的需求:进行路由选择时不仅仅根据数据报的目的地址,而且根据数据报的其他一些特性如:源地址、IP协议、传输层端口,甚至是数据包的负载部分内容,这种类型的路由选择被称作基于策略的路由。基于策略的路由为网络管理者提供了比传统路由协议对报文的转发和存储更强的控制能力,传统上,路由器用从路由协议派生出来的路由表,根据目的地址进行报文的转发。基于策略的路由比传统路由强,使用更灵活,它使网络管理者不能够根据目的地址而且能够根据,报文大小,应用或IP源地址来选择转发路径。策略可以定义为通过多路由器的负载平衡或根据总流量在各线上进行转发的服务质量(QOS)。策略路由使网络管理者能根据它提供的机定一个报文采取的具体路径。而在当今高性能的网络中,这种选择的自由性是很需要的。
Cisco 的网络操作系统 (Cisco IOS) 从11.0开始就采用新的策略性路由机制。而Linux是在内核2.1开始采用策略性路由机制的。策略性路由机制与传统的路由算法相比主要是引入了多路由表以及规则的概念。
二.Linux下策略路由的实现
Linux策略性路由是由RPDB实现的(routing policy database),RPDB通过包含的一些规则来选定合适的IP路由。这些规则可能会包含很多各种不同类型的健值(key),因此这些规则没有默认的特定次序,规则查找次序或规则优先级都是由网络或系统管理员设定的。Linux的RPDB是一个由数字优先级值进行排序的线性规则列表。RDPB主要由多路由表和规则组成。路由表以及对其的操作和其对外的接口是整个RPDB的核心部分。路由表主要由table,zone,node这些主要的数据结构构成。对路由表的操作主要包含物理的操作以及语义的操作。路由表除了向IP层提供路由寻找的接口以外还必须与几个元素提供接口:与用户的接口(即更改路由)、proc的接口、IP层控制接口、以及和硬件的接口(网络接口的改变会导致路由表内容的改变)。处在RDPB的中心的规则,由规则选取表。IP层并不直接使用路由表,而是通过一个路由适配层,路由适配层提供为IP层提供高性能的路由服务。 RPDB能匹配数据报源地址、目的地址、TOS、进入接和fwmark值等。每个路由策略规则由一个选择器和一个动作指示组成。RPDB按照优先级递增的顺序被扫描,RPDB包含的每条规则的选择器被应用于数据报的源地址、目的地址、进入接口、TOS和fwmark值。若数据报匹配该规则对应于该规则的动作被执行。若动作成功返回,则规则输出将是一个有效的路由或是路由查找失败指示;否则查找RPDB的下一条规则。
Linux,启动时内核将包含一个由三条策略规则组成的默认的RPDB,察看这些默认规则的一个方法是使用命令来列出系统的所有规则:
root@netmonster ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
默认规则在对于理解启动复杂路由系统是非常重要的。
首先是最高级别的优先级规则,规则策略0:
规则0: 优先级 0 选择器 = 匹配任何数据报, 动作=察看本地路由表(routing table local),ID为255。local表是保留路由表,包含了到本地和广播地址的路由。规则0是特殊的规则,不可被删除或修改。
规则 32766: 优先级 32766 选择器 = 匹配所有数据报, 动作 = 察看主路由表(routing table main), ID为254。 main路由表是默认的标准路由表,其包含所有非策略路由,main表是存放旧的路由命令(route命令)创建的路由。而且任何由ip route命令创建的没有明确指定路由表的路由都被加入到该路由表中。该规则不能被删除和被其他规则覆盖。
规则 32767: 优先级 32767 选择器 = 匹配所有数据报, 动作 = 察看默认路由表(routing table default),ID为253。default路由表是空的,为最后处理(post-processing)所预留,若前面的默认规则没有选择该数据报时保留用作最后的处理。该规则可以被删除。
Linux策略规对应的动作除了指向一个路由表以外还能是若干种不同的动作。当创建一个策略规则,有如下类型的动作可以选择:
unicast -- 在该规则指向的路由表中进行标准的路由查找。当一个路由表被指定,这是默认的动作。
blackhole -- 规则动作将仅仅直接丢弃该数据报。
unreachable -- 规则动作产生一条网络不可达错误信息,一个类型为3,代码为0的ICMP消息被返回给发送者。
prohibit -- 规则动作产生一个通信被禁止的错误消息,一个类型为3,代码为13的ICMP消息被返回给发送者。
在讨论了命令语法以后,下面是一些具体实施示例。
例 1:拒绝访问Internet
假设有一个防火墙连接本地局域网和Internet,你希望禁止局域网的一个子网访问Internet。当然这可以通过Linux数据报过滤防火墙来实现。但是下面我们将介绍另外一种实现方法。首先我们来假设有如下的网络配置:
内部网络地址 192.168.0.0/16
被拒绝访问的子网 192.168.2.0/24
root@netmonster# ip route list table 254
default via 192.168.254.254 dev eth0 proto static
下面将针对该子网创建一条策略路由规则:
ip rule add from 192.168.2.0/24 priority 5000 prohibit
现在任何从192.168.2.0/24子网发送来的数据报将得到一个类型为3,代码为13的ICMP消息,同时该数据报将被丢弃。
应该注意的是,在运行任何这些命令都需要发送“ip route flush cache"命令来刷新路由缓冲,否则命令在一段时间以后才会生效,这段时间的长短依赖于路由表结构的大小和负载。
将上面的例子需要的命令放在一起就如下所示:
ip rule del priority 5000
ip rule add from 192.168.2.0/24 priority 5000 prohibit
ip route flush cache
这个命令流通过首先删除5000号规则来确保当前系统没有该规则然后再添加新的5000号规则。如果系统本来不存在5000号的规则则会返回一个错误信息。然后添加5000号规则并通过清空运行时的路由缓存来重置RPDB,则新规则将马上产生作用。
例 2:创建多个路由表
通过为路由表命名,就可以使用表数字ID或表名来引用路由表。例如下面两个命令将对同一个路由表进行操作:
ip route list table 1
ip route list table goodnet1
通过表名可以更好的理解在对哪个路由表进行操作。如果已经创建了如上所示的rt_table信息,可以通过下面的命令来察看各个路由表的内容:
ip route list table <name>
当然即使没有定义rt_table文件同样可以使用数字来引用所有的0-255个路由表,因为它们都是存在的,只是其中大部分没有路由信息数据罢了。
下面的例子是向定义的每个路由表都添加一条路由:
ip route add 10.10.10.0/24 via 192.168.1.2 table goodnet1
ip route add 10.10.11.0/24 via 192.168.1.2 table goodnet2
ip route add 10.10.12.0/24 via 192.168.1.2 table badnet1
ip route add 10.10.13.0/24 via 192.168.1.2 table badnet1
ip route add default via 192.168.1.254 table internet
然后再通过ip rouite list talbe <name>命令就可以察看路由表中的各个路由。
例3:多路由表和IP地址
Linux内核路由代码最强大的特色就是基于策略的路由和使用多地址、多路由表的结合使用。下面的示例讨论的是一个充当路由器的连接三个不同的网络的系统。
screen.width-333)this.width=screen.width-333" border=0>
,可核心系统的外部接口连接了三个外部网络。每个网络都有自己的路由器和自己的IP地址空间。但是其中的两个地址空间是重叠的,因此增加了情况的复杂性。这里我们设置如下规则的路由表来实现互联:
从任何内部网络到Inetent的数据流都是允许的。
从内部网B到网络A的数据流是允许的。
从内部网A到网络C的数据流是允许的。
内部网A的地址为33-62的主机允许访问网络A。
内部网B的地址为65-78的主机允许访问网络C。
首先,配置两个外部IP地址-在DMZ以太网接口eth0的两个地址:
ip addr add 10.254.254.2/30 dev eth0
ip addr add 172.17.1.128/24 dev eth0
下一步将讨论创建哪些路由表,解决这个问题的最好办法是想到基于策略的路由能实现根据源地址来决定使用哪个路由表。策略规则具有划分内部网络的能力,因此首先可以在路由表中添加基于目的的路由,在示例中我们将使用前面创建的新的路由表。
当在路由表中添加路由时下面的方法有助于澄清应该采取的步骤。假设你配置的是只有两个接口的路由器,外接口直接连接Interet出口路由器,而内接口直接连接内部网络。配置这样的路由器是非常简单的,操作如下: ip route add 10.10.0.0/16 via 10.254.254.2 table goodnet1 proto static
ip route add default via 172.17.1.254 table goodnet1 proto static
对于goodnet2进行配置则是:
ip route add 172.18.0.0/16 via 172.17.1.1 table goodnet2 proto static
ip route add default via 172.17.1.254 table goodnet2 proto static
可以看到对三个目标网络只需要两个路由表,这里对于连接Internet的默认路由在两个表中都进行了设置。为什么不将默认路由存放在第三个路由表中呢?首先应该考虑到规则和路由表之间的交互,而且规则是实现对基于策略路由的定义。多条规则可以指向同一个路由表。然而,一旦进入某个路由表以后,则只能是匹配一条路由或返回一条路由链。如果匹配到一条规则则就认为你已经拥有一条正确的策略匹配,则该规则指向的路由表包含了该数据报所有的路由可能。
如果有三个路由表,则需要添加一条规则来察看数据报目的。而检查数据报目的地址是标准路由的功能。为什么要对每种源、目的的组合都需要一个规则呢?通过使用路由表,可以实现定义尽量少的规则来达到目的。当然 系统的灵活性允许通过多条方法来实现这样的路由。
ip rule add from 192.168.1.32/27 to 172.18.0.0/16 pref15000 table goodnet1 ip rule add from 192.168.2.64/28 to 10.10.0.0/16 pref 15001 table goodnet2
ip rule add from 192.168.1.0/24 pref 15002 table goodnet1
ip rule add from 192.168.2.0/24 pref 15003 table goodnet2
上面的例子中使用了优先级参数设定来定义数据报匹配规则的顺序。现在来看看当一个数据报从内部网络经过路由系统时会发生什么情况。首先,它会通过优先级为0的规则检查;随后会遇到优先级为15000的规则,若匹配则会被goodnet1这个路由表进行操作,否则将会分别经过15001、15002、15003的规则。它肯定会被15000-15003几个规则中的一个所匹配。
下面为了说明定义路由结构的灵活性,我们将从另外一个角度来解决这个问题。Linux路由器的详细情况如下:
eth0 - DMZ ethernet - addresses: 10.254.254.2/30, 172.17.1.128/24
eth1 - Internal A - addresses: 192.168.1.254/24
eth2 - Internal B - addresses: 192.168.2.254/24
首先假设重新开始,将重新定义路由和规则,首先编辑/etc/iproute2/rt_tables:
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# Local Tables
#
1 int1
2 int2
创建路由和规则:
ip route add 10.10.0.0/16 via 10.254.254.1 table int1 proto static
ip route add throw 0/0 table int1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 table int2 proto static
ip route add throw 0/0 table int2 proto static
ip route add 0/0 via 172.17.1.254 table main proto static
ip rule add pref 15000 table int1 iif eth1
ip rule add pref 15001 table int2 iif eth2
ip rule add pref 15002 to 10.10.0.0/16 table int1
ip rule add pref 15003 to 172.18.0.0/16 table int2
例 3:简单基于fwmard的策略路由
在指定策略规则时可以使用的一个选项就是允许通过fwmark值来匹配某个规则。fwmark是一个数字标签,数据报过滤工具iptables能将fwmark值附加给某个数据报。例如上例多路由表,希望实现来自内部网B的、目的端口为80的数据发送到Internet,但是来自内部网A的、目的端口为80的数据则被禁止。首先清空这些路由表:
ip route flush table goodnet1
ip route flush table goodnet2
ip route flush table badnet1
ip route flush table badnet2
ip route flush table internet
ip route flush cache
而目前删除策略规则的方法就是将其一一列出来然后将其手工删除,也就是首先通过ip rule list命令将策略规则列出来然后使用ip rule del priority <#>将其删除。但这里假设当前没有任何规则并且路由表也是空的。
为了使用fwmark标记,首先应该指定希望使用iptables标记的数据报,然后使用标记值来指定一条策略规则来处理该数据报。应该设定ipchians自动将十进制的标记转化为十六进制。ip rule希望输入为一个十六值。
首先配置iptables规则使用合适的值标记输入数据报。假设当前没有其他防火墙规则:
iptables -I input -p tcp -s 192.168.2.0/24 -d 0/0 80 -m 2
iptables -I input -p tcp -s 192.168.1.0/24 -d 0/0 80 -m 16
现在设立策略规则,在上面为内部网A的标记值为十机制的16,下面定义相关的策略:
ip rule add fwmark 2 table goodnet1
ip rule add fwmark 10 prohibit
最后为路由表goodnet1定义如下的路由:
ip route add default via 172.17.1.254 table goodnet1
策略路由和IP伪装之间交互,在转发链之前对路由表进行查询。这意味着如果使用IP伪装,则路由选择器返回的任何源地址都将被作为进行IP伪装的地址。
例4: IP地址的IP伪装
使用上面的网络配置,我这里将对到三个网络的连接进行伪装处理,希望从系统中得到如下的输出:
从内部网A到网络C的数据报被伪装为10.254.254.2
从内部网络B到网络A的数据报被伪装为172.17.1.2
内部网到互联网的数据报都被伪装为172.17.1.128
eth0配置有如下地址:
10.254.254.2/30
172.17.1.128/24
因此为了满足条件2,给eth0添加地址:
ip addr add 172.17.1.2/32 dev eth0
假设系统被设置为对所有的输出数据报都进行IP伪装。首先清空旧的策略规则,然后创建新的规则如下:
ip route add 10.10.0.0/16 via 10.254.254.2 src 10.254.254.2
table goodnet1 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table goodnet1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.2
table goodnet2 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table goodnet2 proto static
ip rule add from 192.168.1.0/24 pref 15000 table goodnet2
ip rule add from 192.168.2.0/24 pref 15001 table goodnet1
例5:综合实例
假设上述例中的路由、规则和地址仍然在起作用,而希望实现下面的需求:
Internal A Hosts 33-62 to Network A Masq as 172.17.1.3
Internal A Hosts 65-78 to tcp port 80 on Network A Masq as 172.17.1.4
Internal B Hosts 33-62 to tcp port 80 on Network A Deny Access
Internal B Hosts 65-78 to tcp port 80 on Network C Masq as 10.254.254.2
下面就是解决方案:
ip addr add 172.17.1.3/32 dev eth0
ip addr add 172.17.1.4/32 dev eth0
ip route del default table goodnet1
ip route del default table goodnet2
ip route add throw 0/0 table goodnet1 proto static
ip route add throw 0/0 table goodnet2 proto static
ip route add default via 172.17.1.254 src 172.17.1.128
table internet proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.3
table badnet1 proto static
ip route add 172.18.0.0/16 via 172.17.1.1 src 172.17.1.4
table badnet2 proto static
ip rule add from 192.168.1.32/27 to 172.18.0.0/16 pref 14999 table badnet1
ip rule add fwmark 1 pref 14998 table badnet2
ip rule add fwmark 2 pref 14997 table goodnet1
ip rule add fwmark 3 pref 14996 blackhole
ip rule add pref 15003 table internet
iptables -I input -p tcp -s 192.168.1.64/28 -d 172.18.0.0/16 80 -m 1
iptables -I input -p tcp -s 192.168.2.64/28 -d 10.10.0.0/16 80 -m 2
iptables -I input -p tcp -s 192.168.2.32/27 -d 172.18.0.0/16 80 -m 3
其实有很多的有效方法,上述路由规则设置只是其一而已。
三.策略性路由的应用
基于源地址选路( Source-Sensitive Routing)
如果一个网络通过两条线路接入互联网,这样的话,网络管理员既可以提供无差别的路由服务,也可以根据源地址的不同,使一些特定的地址使用较快的线路,而普通用户则使用较慢的线路,即基于源址的选路。
根据服务级别选路(Quality of Service)
网络管理员可以根据IP报头的服务级别域,对于不同的服务要求可以分别对待对于传送速率、吞吐量以及可靠性的有不同要求的数据报根据网络的状况进行不同的路由。
节省费用的应用
网络管理员可以根据通信的状况,让一些比较大的阵发性通信使用一些带宽比较高但是比较贵的路径一段短的时间,然后让基本的通信继续使用原来比较便宜的基本线路。例如,管理员知道,某一台主机与一个特定的地址通信通常是伴随着大量的阵发性通信的,那么网络管理员可以安排一些策略,使得这些主机使用特别的路由,这些路由是按需拨号,带宽比较高的线路,通信完成以后就停止使用,而普通的通信则不受影响。这样既提高网络的性能,又能节省费用。
负载平衡(Load Sharing)
根据网络交通的特征,网络管理员可以在不同的路径之间分配负荷实现负载平衡。
四.小结
Linux具有强大路由功能,它提供的路由功能是很多路由器产品都是难以匹敌的, 如果考虑到它的免费性,它的性能价格比更是没有任何产品可以相比。
参考文献:
1. Policy Routing in Linux
http://www.samag.com/documents/s=1169/sam0001f/0001f.htm
2. Linux策略性路由应用及深入分析
http://www.yesky.com/20021212/1644092.shtml
相关阅读 更多 +
排行榜 更多 +