ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Linux环境下基于策略的路由

Linux环境下基于策略的路由

原创 Linux操作系统 作者:coolwinds 时间:2005-03-16 00:13:49 0 删除 编辑
Linux环境下基于策略的路由
[@more@]

Linux环境下基于策略的路由
原文作者:Matthew G. Marsh
原文出处:
http://www.sysadminmag.com/linux/articles/v09/i01/a3.htm
    译:ideal ideal@linuxaid.com.cn

    
目前在计算机网络中使用的传统路由算法都是根据IP包目的地址进行路由选择.然而在现实应用中经常有这样的需求:进行路由选择时不仅仅根据数据报的目的地址,而且根据数据报的其他一些特性如:源地址、IP协议、传输层端口,甚至是数据包的负载部分内容,这种类型的路由选择被称作基于策略的路由。 

    
Linux中,从2.1版本的内核开始就实现了对基于策略的路由的支持,它是通过使用路由策略数据库(RPDBrouting policy database)替代传统的、基于目的地址的路由表来实现的。RPDB通过包含的一些规则来选定合适的IP路由。这些规则可能会包含很多各种不同类型的健值(key),因此这些规则没有默认的特定次序,规则查找次序或规则优先级都是由网络或系统管理员设定的。


    Linux
RPDB是一个由数字优先级值进行排序的线性规则列表。RPDB能匹配数据报源地址、目的地址、TOS、进入接和fwmark值等。每个路由策略规则由一个选择器和一个动作指示组成。RPDB按照优先级递增的顺序被扫描,RPDB包含的每条规则的选择器被应用于数据报的源地址、目的地址、进入接口、TOSfwmark值。若数据报匹配该规则对应于该规则的动作被执行。若动作成功返回,则规则输出将是一个有效的路由或是路由查找失败指示;否则查找RPDB的下一条规则。

    
当选择器和一个数据报匹配成功,会执行哪些动作呢?路由软件的标准动作一般是选择下一跳地址和输出接口,可以称这种动作为“匹配&设置”类型动作。然而Linux采取了更加灵活的方法,在Linux中有多种动作可供选择。默认的动作是查询特定的基于目的地址的路由表。因此“匹配&设置”动作就成为Linux路由选择的最简单情况。Linux支持多个路由表,每个路由表都包含多条路由信息。也就是Linux的每个路由表都相当于其他操作系统的系统路由表。Linux支持多达255个路由表。(Linux 2.2.12 支持255个路由表,255个汇聚域和232个策略规则优先级 (4294967296 decimal) 

对于Linux2.1/2.2,启动时内核将包含一个由三条策略规则组成的默认的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)ID255
 

local
表是保留路由表,包含了到本地和广播地址的路由。规则0是特殊的规则,不可被删除或修改。
 

规则 32766: 优先级 32766     选择器 = 匹配所有数据报
 

动作 = 察看主路由表(routing table main) ID254
 

main
路由表是默认的标准路由表,其包含所有非策略路由,main表是存放旧的路由命令(route命令)创建的路由。而且任何由ip route命令创建的没有明确指定路由表的路由都被加入到该路由表中。该规则不能被删除和被其他规则覆盖。
 

规则 32767: 优先级 32767 选择器 = 匹配所有数据报
 

动作 = 察看默认路由表(routing table default)ID253
 

default
路由表是空的,为最后处理(post-processing)所预留,若前面的默认规则没有选择该数据报时保留用作最后的处理。该规则可以被删除
 

不要将路由表和规则混淆,规则是指向路由表的。也许会出现多个规则指向同一个路由表,而有些路由表可能并不被任何规则指向。如果删除了指向某个路由表的所有规则,则该表将不发生作用,但是表将仍然存在。一个路由表只有在其中包含的所有路由信息被删除才会消失。 


前面提到,Linux策略规对应的动作除了指向一个路由表以外还能是若干种不同的动作。当创建一个策略规则,有如下类型的动作可以选择: 

unicast -- 
在该规则指向的路由表中进行标准的路由查找。当一个路由表被指定,这是默认的动作。 


blackhole -- 
规则动作将仅仅直接丢弃该数据报。 

unreachable -- 
规则动作产生一条网络不可达错误信息,一个类型为3,代码为0ICMP消息被返回给发送者。
 

prohibit -- 
规则动作产生一个通信被禁止的错误消息,一个类型为3,代码为13ICMP消息被返回给发送者。
 

其他类型的动作也可以被使用,但是都和策略路由没有关系。它们被用来在内核中实现其他高级流控制和数据报操作。因为只有一个工具命令:ip,所有的这些类型都是可运用于该命令,但我们仅仅使用和上面有关的部分,可以是返回一条路由或其他若干个动作。
 

在解释示例以前,首先看看ip工具命令的语法。ip命令可以用在很多地方,这里仅仅讨论和策略路由相关的部分。都是由root在命令行直接运行的。


首先,看ip addr命令语法:

root@netmonster# ip addr help
Usage: ip addr {add|del} IFADDR dev STRING
       ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]
                            [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]
IFADDR := PREFIX | ADDR peer PREFIX
          [ broadcast ADDR ] [ anycast ADDR ]
          [ label STRING ] [ scope SCOPE-ID ]
SCOPE-ID := [ host | link | global | NUMBER ]
FLAG-LIST := [ FLAG-LIST ] FLAG
FLAG  := [ permanent | dynamic | secondary | primary |
           tentative | deprecated ]

Example - ip addr add 192.168.1.1/24 dev eth0

该命令将添加IP地址192.168.2.2/24eth0网卡上

下面看看ip route命令:
 

root@netmonster# ip route help
Usage: ip route { list | flush } SELECTOR 

ip route get ADDRESS [ from ADDRESS iif STRING ] 

[ oif STRING ] [ tos TOS ] 

ip route { add | del | replace | change | append | replace |  

monitor} ROUTE 

SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ] 

[ table TABLE_ID ] [ proto RTPROTO ] 

[ type TYPE ] [ scope SCOPE ] 

ROUTE := NODE_SPEC [ INFO_SPEC ] 

NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ] 

[ table TABLE_ID ] [ proto RTPROTO ] 

[ scope SCOPE ] [ metric METRIC ] 

INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]... 

NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS 

OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] 

[ rtt NUMBER ] [ rttvar NUMBER ] 

[ window NUMBER] [ cwnd NUMBER ] [ ssthresh REALM ] 

[ realms REALM ] 

TYPE := [ unicast | local | broadcast | multicast | throw | 

unreachable | prohibit | blackhole | nat ] 

TABLE_ID := [ local | main | default | all | NUMBER ] 

SCOPE := [ host | link | global | NUMBER ] 

FLAGS := [ equalize ] 

NHFLAGS := [ onlink | pervasive ] 

RTPROTO := [ kernel | boot | static | NUMBER ] 

Example - ip route add 192.168.2.0/24 via 192.168.1.254 

该示例将添加一条通过192.168.1.254到网络192.168.2.0/24的路由。
 

最后,看看ip rule命令:


root@netmonster# ip rule help
Usage: ip rule [ list | add | del ] SELECTOR ACTION
SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]
            [ dev STRING ] [ pref NUMBER ]
ACTION := [ table TABLE_ID ] [ nat ADDRESS ]
          [ prohibit | reject | unreachable ]
          [ realms [SRCREALM/]DSTREALM ]
TABLE_ID := [ local | main | default | NUMBER ]

Example - ip rule add from 192.168.2.0/24 prio 32777 reject
该命令将丢弃源地址属于192.168.2.0/24网络的所有数据报。 

在讨论了命令语法以后,下面是一些上面命令的示例。


 1:拒绝访问Internet
假设有一个防火墙连接本地局域网和Internet,你希望禁止局域网的一个子网访问Internet。当然这可以通过Linux数据报过滤防火墙来实现。但是下面我们将介绍另外一种实现方法。首先我们来假设有如下的网络配置:
 

内部网络地址
           192.168.0.0/16
被拒绝访问的子网
        192.168.2.0/24
当前主路由表(Routing Table Main,
254): 
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,代码为13ICMP消息,同时该数据报将被丢弃。
 

应该注意的是,在运行任何这些命令都需要发送“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,则新规则将马上产生作用。
 

多路由表和IP地址

为了完全理解基于策略路由的使用,就需要学会使用Linux多路由表和IP地址,这包括多个方面的知识,下面通过示例来加以说明。 

当获得ip工具,你可能会注意到在发布中有一个名为etc的子目录,其中有一个名为iproute2的子目录。应该拷贝该子目录到/etc目录下或在/etc目录下创建iproute2子目录。该目录包含用来命名路由表及策略路由结构的其他方面的文件。在该目录中创建rt_tables文件,其中示例文件一般已经包含了某些内容,并为路由表1提供了示例名。
 

下面首先编辑该文件来创建若干在下面的示例中使用的表:


# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
1       goodnet1
2       goodnet2
3       badnet1
4       badnet2
5       internet
可以看到通过为路由表命名,就可以使用表数字ID或表名来引用路由表。例如下面两个命令将对同一个路由表进行操作:

ip route list table 1
ip route list table goodnet1
通过表名可以更好的理解在对哪个路由表进行操作。 

 2:创建多个路由表

如果已经创建了如上所示的rt_table信息,可以通过下面的命令来察看各个路由表的内容:

ip route list table 
name
当然即使没有定义rt_table文件同样可以使用数字来引用所有的0-255个路由表,因为它们都是存在的,只是其中大部分没有路由信息数据罢了。在上面的例子中通过rt_table文件来将表1定义为goodnet1 

下面的例子是向定义的每个路由表都添加一条路由:


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地址

这里的多个IP地址并不同于IP别名,在Linux2.1及更高版本中已经反对使用":#"IP别名方式。而应该用新的方式来使用多IP地址。 

假设eth0输出接口应该具有三个不同的IP地址,其中的两个应该属于同一个子网,但是应该被独立地设置,示例同样说明了在Linux2.2及以上版本的关闭自动路由添加的方法。在Linux2.2及以上版本内核的系统中,当为一个接口赋予一个IP地址时,内核将自动为该IP地址属于的网络在路由表中添加一条对应的路由。而由于这里将为同一个接口赋予属于同一个子网的两个不同的IP,所以在添加IP地址时不希望添加路由,否则会造成路由冲突,因此就需要添加该地址为一个主机地址。只需要设置该地址时指定完全主机地址掩码,然后手工添加必要的路由。
 

为接口设置如下地址:


192.168.1.1
192.168.1.128
192.168.3.1
在添加192.168.1.0/24的两个地址时需要关闭自动路由添加,而允许对

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/83980/viewspace-792888/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论