02 Ip命令之 Linux策略路由ip Rule IP Route
早期在管理Linux系统的网络时,常使用ifconfig及route之类的命令,不过如果你准备开始使用Linux强大的基于策略的路由机制,那么,就请不要使用这类工具了,因为这类工具根本无法用于功能强大的基于策略的路由机制,取而代之的工具是iproute。iproute这个软件在RedHat系列的Linux系统中是默认安装的,因此,你通常可以找到这个工具。如果真因为某些原因找不到这个软件,只要在使用Fedora或CentOS Linux时,在联网的情况下,用yum install iproute命令即可顺利安装;或者也可以使用ip -V命令来检查iproute软件是否已经安装,再次请注意,-V参数为大写的英语字母:
[root@localhost /]# ip -V
ip utility, iproute2-ss091226
linux 高级路由即基于策略的路由比传统路由在功能上更强大,使用也更灵活,它不仅能够根据目的地址来转发路径而且也能够根据报文大小、应用或ip源地址来选择路由转发路径从而让系统管理员能轻松做到: 1、 管制某台计算机的带宽。 2、 管制通向某台计算机的带宽 3、 帮助你公平地共享带宽 4、 保护你的网络不受DOS的攻击 5、 保护你的Internet不受到你的客户的攻击 6、 把多台服务器虚拟成一台,并进行负载均衡或者提高可用性 7、 限制你的用户访问某些计算机 8、 限制对你的计算机的访问 9、 基于用户帐号、MAC地址、源IP地址、端口、QOS《TOS》、时间或者content等进行路由
在Linux下,基于策略路由的策略数据库是由ip命令来管理的,下面讨论“管理”的几个方面:
要查看策略数据库的内容,可以使用ip rule show命令,或者可以使用ip rule ls。如下是命令执行后所得到的输出结果,在这些数据中,可以看到系统的三条默认规则,而这三条规则默认分别对应于local、mail及default三个路由表。
[root@localhost /]# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
在添加规则时,必须先确定好“条件”、“优先级别”及“路由表ID”,此后才可以执行添加规则的操作。
条件是用来决定哪类数据包可以符合这项规则,而可用来匹配的字段为Source IP、Destination IP、Type of Service、fwmark及dev等,这些字段的使用方式如下:
根据来源端IP来决定数据包参考哪个路由表发送出去。以下两个示例分别指出,如果数据包的来源端IP是192.168.1.10,就参考路由表10;如果来源端IP为192.168.2.0/24网段的IP,就参考路由表20。
ip rule add from 192.168.1.10 table 10
ip rule add from 192.168.2.0/24 table 20
根据目的端IP来决定数据包参考哪个路由表发送出去。以下两个示例分别指出,如果数据包的目的端IP是168.95.1.1,就参考路由表10;如果目的端IP是168.95.0.0/24网段的IP,就参考路由表20。
ip rule add to 168.95.1.1 table 10
ip rule add to 168.96.0.0/24 table 20
将fwmark作为匹配条件时,必须搭配Netfilter一起使用, 这看起来很麻烦, 却是最灵活的匹配条件。如图10-8所示,某公司对外有三条ADSL,我们希望所有HT T P 协议经由第一条ADS L ,SMTP及POP3经由第二条ADSL,其余流量则经由第三条ADSL。可以使用如下的命令组合来达到这样的目的:

iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 25 -j MARK --set-mark 2
iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 110 -j MARK --set-mark 2
iptables -t mangle -A FORWARD -i eth3 -j MARK --set-mark 3
ip rule add fwmark 1 table 1
ip rule add fwmark 2 table 2
ip rule add fwmark 3 table 3
首先使用Netfilter的managle机制针对特定的数据包设置MARK值,在此将HTTP数据包的MARK值设置为1,SMTP及POP3数据包的MARK值设置为2,其余数据包则设置MARK值为3。接着,再根据fwmark条件来判断数据包的MARK值,如果MARK值为1,则参考路由表1将数据包送出;MAKR值为2时,则参考路由表2将数据包送出;最后,MARK值为3的数据包则参考路由表3送出。
以上示例只是一个概念而已,如果真要完整体现出这个示例的所有功能,还需要注意许多细节,稍后将使用详细的示例讲解这部分内容,在此只要首先了解fwmark与Netfilter结合使用的概念即可。
最后,还可以使用数据包输入的接口来作为判断依据,如图10-9所示,我们希望凡是由eth2接口送入的数据包都由eth0接口转发出去,由eth3接口送入的数据包都由eth1接口转发出去。以下命令组合将能满足我们的要求:
ip rule add dev eth2 table 1
ip rule add dev eth3 table 3

前面介绍了规则中“条件”的使用方式,接下来要讨论的是优先级别。优先级别用数字来表示,其范围可由0~4亿多,堪称天文数字,我们实际上不可能在一台PC上设置如此庞大的路由机制。
[root@localhost ~]# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@localhost ~]#
[root@localhost ~]# ip rule add from 192.168.1.0/24 table 1
[root@localhost ~]# ip rule add from 192.168.2.0/24 table 2
[root@localhost ~]#
[root@localhost ~]# ip rule show
0: from all lookup local
32764: from 192.168.2.0/24 lookup 2
32765: from 192.168.1.0/24 lookup 1
32766: from all lookup main
32767: from all lookup default
如以上示例,我们执行ip rule show命令所显示内容的第一个字段就是优先级别,数字越小,代表优先级别越高,也代表这条规则可以排得越靠前,如此数据包在进行条件匹配时,就会越早匹配到这条规则,从输出的数据中,默认优先级别0、32766及32767已被占用,因此,在添加规则时,如果没有特别设置优先级别,那么,优先级别默认会从32766开始递减,如32765、32764……,如果我们需要特别设置优先级别,可以在ip rule add命令的最后加上prio XXX参数。如下例所示:
[root@localhost ~]# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@localhost ~]#
[root@localhost ~]# ip rule add from 192.168.1.0/24 table 1 prio 10
[root@localhost ~]# ip rule add from 192.168.2.0/24 table 2 prio 20
[root@localhost ~]#
[root@localhost ~]# ip rule show
0: from all lookup local
10: from 192.168.1.0/24 lookup 1
20: from 192.168.2.0/24 lookup 2
32766: from all lookup main
32767: from all lookup default
在Linux的基于策略的路由中,路由表用ID来表示,但如有必要,还可以用ID与名称对照表将ID转换成名称。
ip命令提供的删除规则的方式十分灵活,例如,要删除下列第2条规则,可以分别使用“优先级别”、“条件”及“路由表”当中任何一个唯一的值来设置所需删除的规则,如下:
ip rule del prio 10
ip rule del from 192.168.1.0/24
ip rule del table 1
ip rule del from 192.168.1.0/24 table 1 prio 10
[root@localhost ~]# ip rule show
0: from all lookup local
10: from 192.168.1.0/24 lookup 1
20: from 192.168.2.0/24 lookup 2
32766: from all lookup main
32767: from all lookup default
由于route -n命令已经完全不适合在基于策略的路由使用,因此,route命令仅能操作一个特定的路由表,但在基于策略的路由中,会同时存在多个路由表,请放弃这个路由管理工具,取而代之的依然是ip命令。接下来将讨论如何使用ip命令来管理路由表。
在查看路由表之前,首先使用ip rule show命令来查看目前使用了哪些路由表(规则、策略),接着,再使用ip route show [table_id | name]命令来查看路由表的内容。例如,可以使用ip route showtable main来查看路由表main的内容,如果省略路由表名称(如ip route show),会默认地查看路由表main的内容。
[root@localhost /]# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@localhost /]#
[root@localhost /]# ip route show table main
10.10.15.0/25 dev eth0 proto kernel scope link src 10.10.15.46
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10
default via 10.10.15.1 dev eth0
[root@localhost /]#
在默认情况下,在 Linux 系统启动时,内核会为路由策略数据库配置三条缺省的规则,即系统有三个路由表,这三个路由表的功能如下:
local:优先级为0,查询路由表local(ID 255),该表local是一个特殊的路由表,路由表local包含本机路由及广播信息。例如,在本机上执行ssh 127.0.0.1时,就会参考这份路由表的内容,在正常情况下,只要配置好网卡的网络设置,就会自动生成local路由表的内容,我们应该也不必修改其内容。
root@mgt01:~# ip route show table local #发往本机的路由 broadcast 10.110.62.0 dev br-mgm proto kernel scope link src 10.110.62.41 local 10.110.62.41 dev br-mgm proto kernel scope host src 10.110.62.41 broadcast 10.110.62.255 dev br-mgm proto kernel scope link src 10.110.62.41 broadcast 10.200.8.0 dev control proto kernel scope link src 10.200.8.41 local 10.200.8.41 dev control proto kernel scope host src 10.200.8.41 broadcast 10.200.11.255 dev control proto kernel scope link src 10.200.8.41 local 100.101.187.0 dev tunl0 proto kernel scope host src 100.101.187.0 broadcast 100.101.187.0 dev tunl0 proto kernel scope link src 100.101.187.0 broadcast 100.102.0.0 dev docker0 proto kernel scope link src 100.102.0.1 local 100.102.0.1 dev docker0 proto kernel scope host src 100.102.0.1 broadcast 100.102.255.255 dev docker0 proto kernel scope link src 100.102.0.1 broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 broadcast 192.168.62.0 dev br-mgm proto kernel scope link src 192.168.62.1 local 192.168.62.1 dev br-mgm proto kernel scope host src 192.168.62.1 broadcast 192.168.62.255 dev br-mgm proto kernel scope link src 192.168.62.1main:优先级为32766,查询路由表main(ID 254),使用传统命令route -n所看到的路由表就是main的内容。Linux系统在默认情况下使用这份路由表的内容来传输数据包,因此,其内容极为重要,在正常情况下,只要配置好网卡的网络设置,就会自动生成main路由表的内容。
root@mgt01:~# ip route show table main #即 ip route查看的内容 default via 10.110.62.254 dev br-mgm proto static 10.110.62.0/24 dev br-mgm proto kernel scope link src 10.110.62.41 10.200.8.0/22 dev control proto kernel scope link src 10.200.8.41 100.102.0.0/16 dev docker0 proto kernel scope link src 100.102.0.1 100.123.0.0/16 via 10.200.11.254 dev control proto static 192.168.62.0/24 dev br-mgm proto kernel scope link src 192.168.62.1default:优先级为32767,查询路由表default(ID 253),这个路由表在默认情况下内容为空;除非有特别的要求,否则保持其内容为空即可。
linux 系统中,可以自定义从 1-252个路由表,其中,linux系统维护了4个路由表:
0#表: 系统保留表
253#表: default table ,没特别指定的默认路由都放在改表
254#表: main table ,没指明路由表的所有路由放在该表(默认表)
255#表: local table ,保存本地接口地址,广播地址、NAT地址 由系统维护,用户不得更改
路由表序号和表名的对应关系在 /etc/iproute2/rt_tables文件中,可以手动编辑。
在此使用路由表main的内容进行解释,以下是图10-10路由表main的内容,因为在主机上有eth0及eth1两块网卡,且为其设置的IP分别是10.10.15.46/25及192.168.1.10/24,因此,路由表内的第.行即是告诉系统,如果有数据包要送到10.10.15.0/25这个网段,就直接将数据包由eth0接口送出即可,而本机临近这个网段的IP是10.10.15.46,第.行则是设置到192.168.1.0/24的路由,其含义与第.行完全相同;以上这两行是只要将计算机网卡上的IP设置好,并在网络服务重启之后,默认就会生成的路由,无需特别的设置。最后一行.则指:如果数据包不是送往10.10.15.0/25及192.168.1.0/24网段,那么数据包将统一转发给10.10.15.1主机去处理,而10.10.15.1就是我们在网络配置中所设置的“默认网关”。
[root@localhost /]# ip route show table main
10.10.15.0/25 dev eth0 proto kernel scope link src 10.10.15.46
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10
default via 10.10.15.1 dev eth0
[root@localhost /]#
添加路由在此还是一样采用ip命令而不是route命令,下例首先使用ip route show.命令显示路由表main的内容,接着再使用ip route add命令将所需的路由添加到路由表main中.,最后再次使用ip route show命令将路由表main的内容打印出来,此时就可以在路由表main之中看到刚才添加的路由了。
[root@localhost /]# ip route show table main
10.10.15.0/25 dev eth0 proto kernel scope link src 10.10.15.46
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10
default via 10.10.15.1 dev eth0
[root@localhost /]#
[root@localhost /]# ip route add 192.168.2.0/24 via 10.10.15.50 table main
[root@localhost /]#
[root@localhost /]# ip route show table main
10.10.15.0/25 dev eth0 proto kernel scope link src 10.10.15.46
192.168.2.0/24 via 10.10.15.50 dev eth0
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10
default via 10.10.15.1 dev eth0
[root@localhost /]#
如果要添加的路由并未出现在现有的路由表中,又该如何处理呢?在此请先有一个概念,单纯添加路由表并无意义,因为新增出来的路由表,系统默认是不会去使用的,如果要将路由添加到main以外的路由表,只有先添加“规则”才能确定新的路由表名称(Table ID),有了新的路由表之后,才会把路由添加到新的路由表中。
我们使用下列示例来说明这个过程。首先使用ip rule show.来查询RPDB的当前状态,可以看到目前只有三条默认规则,接着,再使用ip rule add命令来添加一条规则.,此时系统内就多了一个有用的路由表,其路由表ID为10,我们可以立即使用ip route show命令来查看这个新的路由表.,其内容默认为空,接着可以在这个新路由表中添加路由,在此使用iproute add命令来添加路由,我们决定凡是来自于192.168.2.0/24网段的数据包,都从eth1接口将数据包送离本机,因此,必须完整编写eth1接口的路由。首先将临近eth1接口的路由填入.,告诉系统本机与192.168.1.0/24网段的通信都通过eth1接口来处理,接着填入这个路由表的默认路由.,最后使用ip route show命令显示路由表10的内容。
[root@localhost ~]# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@localhost ~]#
[root@localhost ~]# ip rule add from 192.168.2.0/24 table 10
[root@localhost ~]#
[root@localhost ~]# ip route show table 10
[root@localhost ~]#
[root@localhost ~]# ip route add 192.168.1.0/24 dev eth1 table 10
[root@localhost ~]# ip route add default via 192.168.1.254 table 10
[root@localhost ~]#
[root@localhost ~]# ip route show table 10
192.168.1.0/24 dev eth1 scope link
default via 192.168.1.254 dev eth1
[root@localhost ~]#
可以使用ip命令来方便地删除路由,我们使用以下示例来说明如何删除路由。首先将路由表10的内容显示出来.,可以看到路由表10中当前有两条路由,接着使用ip route del命令删除默认路由.,在此别忘了指定我们所要删除的是路由表10,否则默认会删除路由表main的默认路由,接着再使用ip route show 命令查看路由表10.,此时路由表10的默认路由已经不存在了,再次使用ip route del命令删除192.168.122.0/24的路由.,最后可以看到路由表10中已经没有任何路由了。
[root@localhost ~]# ip route show table 10
192.168.1.0/24 dev virbr0 scope link
default via 192.168.1.254 dev eth1
[root@localhost ~]#
[root@localhost ~]# ip route del default table 10
[root@localhost ~]#
[root@localhost ~]# ip route show table 10
192.168.1.0/24 dev virbr0 scope link
[root@localhost ~]#
[root@localhost ~]# ip route del 192.168.1.0/24 table 10
[root@localhost ~]#
[root@localhost ~]# ip route show table 10
[root@localhost ~]#
以一例子来说明:公司内网要求192.168.0.100 以内的使用 10.0.0.1 网关上网 (电信),其他IP使用 20.0.0.1 (网通)上网。
1,首先要在网关服务器上添加一个默认路由,当然这个指向是绝大多数的IP的出口网关:ip route add default gw 20.0.0.1
2,之后通过 ip route 添加一个路由表:ip route add table 3 via 10.0.0.1 dev ethX (ethx 是 10.0.0.1 所在的网卡, 3 是路由表的编号)
3,之后添加 ip rule 规则:ip rule add fwmark 3 table 3 (fwmark 3 是标记,table 3 是路由表3 上边。 意思就是凡事标记了 3 的数据使用 table3 路由表)
4,之后使用 iptables 给相应的数据打上标记:iptables -A PREROUTING -t mangle -i eth0 -s 192.168.0.1 - 192.168.0.100 -j MARK --set-mark 3
转载:https://blog.csdn.net/melancholy123/article/details/80782567
计算机网络通信的本质就是IP数据包的转发,而实现数据包转发的基础就是位于网络中各节点上的路由表(RouteTable),即使节点不具备数据包转发的功能,以其自身(Localhost)作为收发终端的的数据包传递也要通过其上路由表(策略路由中的local表)实现,下图是对网络节点数据包收发机制的抽象框图,通常充当网络节点的设备会具备不只一个网络接口,接口可以是物理的也可以是虚拟的,接口必须要配置上IP地址才能实现数据包的收发,接口上的IP地址可以根据实现需要配置同网段或不同网段,抑或二者混合,而在数据交换领域相同网段的接口拓扑层级相同因此可以被视为同一接口,所以在此接口区分的依据为其上的IP地址为不同网段。
数据包通过广播进入节点某个接口的缓冲区随后由内核即协议栈接收,检查数据包的下一跳地址如果是本机接口则发送给用户空间中的应用程序,如果不是本身接口则意味着需要进行数据包的转发,如果节点开启IP_FORWARD功能则根据路由表将数据包的目标地址替换为能到下一跳地址网络的网关地址随后通过对应的接口发送出去;应用程序输出的数据包也依据路由表确定目标地址后由对应接口广播出去。由此可见网络通信的核心就是路由表,其与协议栈皆位为内核层级,而iptables程序则拓展了内核功能,给使用者提供了接口可以自定义规则来实现特定的数据包收发,iptables规则对应逻辑上的五个链条,由下图所示分别是PREROUTING,POSTROUTING,FORWARD,INPUT和OUTPUT。