心想事成 发表于 2004-11-27 18:54:40

双adsl链路冗余互备及流量分担的实现转自:http://www.iuiuiu.com/plog/post/1/29经过一周的摸索,实现了双adsl链路冗余互备及流量分担,整理如下: 目的:实现双adsl的冗余热备和流量分担功能: 双adsl同时连线; 当两条adsl同时连线时,流量经策略路由分流到两条链路上; 当其中一条adsl掉线时,所有流量自动分配另一条可用连接; 可以扩展到多条ppp连接.1.添加网卡 插入网卡,启动机器,修改/etc/modules.conf并加入 alias eth2 driver.o 2.配置adsl拨号 通过adsl-setup程序创建ppp0和ppp1的拨号配置文件,并保存配置。 修改/etc/sysconfig/network-script/ifcfg-ppp*文件,将其中的PIDFILE参数设为: PIDFILE=/var/run/ppp-adsl*.pid 其中*对应0、1等 如果不修改此参数将无法启动第二个ppp接口。 3.启动ppp接口 因为adsl-start 命令缺省只能启动第一的ppp接口。所以要启动两个接口,必须指定配置文件。

QUOTE
adsl-start /etc/sysconfig/network-scripts/ifcfg-ppp0 adsl-start /etc/sysconfig/network-scripts/ifcfg-ppp1
4.添加路由表 缺省情况下,系统只有3个路由表,local、main、default,路由规则为所有进入的数据报都参照main、defaul来决策路由,这可以通过ip rule ls来查看。其输出如下:

CODE
# ip rule ls 0:?rom all lookup local 32766:?rom all lookup main 32767:?rom all lookup 253 #
要实现策略路由,添加额外的路由表是必须的。 下面两条命令分别添加名为ppp0和ppp1的路由表。 echo 201 ppp0 >> /etc/iproutes/rt_tables echo 202 ppp1 >> /etc/iproutes/rt_tables 5.创建路由表项 上面创建的两个路由表都是空表,需要在其中注入路由表项。 本人编写了如下脚本用于注入路由表项:

CODE
#!/bin/bash # Name: cprt # This program copy the route from $1 route table to $2 route table, # exclude the default route entry. if [ -z "$1" -o -z "$2" ]; then echo $"usage: cprt" exit 1 fi SOURCE=$1 DEST=$2 # Clear the destination route table echo $"Clearing route table $DEST ......" echo /sbin/ip route flush table $DEST # Inject routes from source to destination echo $"Injecting route from $SOURCE to $DEST ......" /sbin/ip route ls table $SOURCE | grep -v default > /tmp/route-tmp while read line; do /sbin/ip route add table $DEST $line done < "/tmp/route-tmp"
把main表中的路由表项复制到ppp0和ppp1中。 将下面命令加入到/etc/rc.d/rc.local中。 cprt main ppp0 cprt main ppp1 此时,两个路由表中都有相同的路由表项了,除了default路由以外。缺省路由的添加要通过另外的途径添加。当ppp激活,或者掉线时,pppd守护进 程会调用/etc/ppp/目录下的ip-up、ip-down脚本,这些教本又分别调用ip-up.local、ip-down.local。在此我们 利用这两个脚本来对路由表和流量控制策略进行维护,此脚本需要人工创建。 下面时本例中的脚本: /etc/ppp/ip-up.local

CODE
#!/bin/bash # Name: ip-up.local # Created by lyking@CU # If the if-down is not completed, this script can't be excute. while [ -e /var/lock/subsys/if-down.$IFNAME ]; do sleep 3 done # Creat a lock file to prevent the if-down from running on my turn touch /var/lock/subsys/if-up.$IFNAME # Determin device here # We should use IFNAME as the interface name.For some reason, the IFNAME maybe not # same as the LINKNAME. And the route table should associate with the IFNAME. For # some conveniency, I name the route table as "ppp0" and "ppp1". RT_TABLE=$IFNAME # Add or change static route here,including default route. # Check if a default is exist. RS="" ip route ls table $RT_TABLE | grep default RS=$? if [ $RS -eq 0 ]; then ip route change default dev $IFNAME table $RT_TABLE else ip route add default dev $IFNAME table $RT_TABLE fi echo >> /var/log/ifchang.log echo "$0: $IFNAME going up at `date`." >> /var/log/ifchang.log echo "$0: $IFNAME got address: $IPLOCAL, peer address is $IPREMOTE." >> /var/log/ifchang.log echo "$0: Table $RT_TABLE default route change to `ip route ls table $RT_TABLE | grep default`." >> /var/log/ifchang.log # Refresh routing cache to activating the routing immediately. ip route flush cache # Add traffic control policy here tc qdisc add dev $IFNAME root handle 1: prio ## This *instantly* creates classes 1:1, 1:2, 1:3 tc qdisc add dev $IFNAME parent 1:1 handle 10 sfq perturb 20 tc qdisc add dev $IFNAME parent 1:2 handle 20 sfq perturb 20 tc qdisc add dev $IFNAME parent 1:3 handle 30 sfq # Remove the lock file rm -f /var/lock/subsys/if-up.$IFNAME
/etc/ppp/ip-down.local

CODE
#!/bin/bash # Name: ip-down.local # Created by lyking@CU while [ -e /var/lock/subsys/if-up.$IFNAME ]; do         sleep 3 done touch /var/lock/subsys/if-down.$IFNAME cd /etc/sysconfig/network-scripts . network-functions # Determin device here # We should use IFNAME as the interface name.For some reason, the IFNAME maybe not # same as the LINKNAME. And the route table should associate with the IFNAME. For # some conveniency, I name the route table as "ppp0" and "ppp1". RT_TABLE=$IFNAME # Looking for a valide connection to Internet DEFAULT_RT="" PPPS='ppp0 ppp1' for i in $PPPS; do ifconfig | grep $i RS=$?         if [ $RS -eq 0 ]; then             DEFAULT_RT=$i             break         fi done # Update default route here as nesessary if [ $DEFAULT_RT != $IFNAME ]; then         if [ $DEFAULT_RT != "" ]; then               ip route add default dev $DEFAULT_RT table $RT_TABLE         else               for i in $PPPS; do                         ip route del default dev $i table $i               done               echo >> /var/log/ifchang.log               echo "$0: All connection is down, remove all default route from all branch tables" >> /var/log/ifchang.log         fi         echo >> /var/log/ifchang.log         echo "$0: $IFNAME going down at `date`." >> /var/log/ifchang.log         echo "$0: Connection lasted $CONNECT_TIME seconds." >> /var/log/ifchang.log         echo "$0: $BYTES_SENT bytes sent, $BYTES_RCVD bytes received." >> /var/log/ifchang.log         echo "$0: $DEFAULT_RT is available." >> /var/log/ifchang.log         echo "$0: Table $RT_TABLE default route changed to `ip route ls table $RT_TABLE | grep default`. " >> /var/log/ifchang.log fi # Refresh routing cache to activating the routing immediately. ip route flush cache rm -f /var/lock/subsys/if-down.$IFNAME
注意,创建完脚本后必须将其属性改为可执行,否则不会被执行。 6.路由策略的选择 策略路由可以通过源地址、目标地址、ToS或者fwmark标记来进行选择。在此,为了利用iptables的强大的过滤功能采用fwmark标记来决策路由。 在/etc/rc.d/rc.local中添加如下命令: /sbin/ip rule add fwmark 1 table ppp0 /sbin/ip rule add fwmark 2 table ppp1 7.防火墙规则的添加 这里利用的iptables的强大过滤功能来对流量进行标记。本例中仅根据ip地址的奇偶性来拆分流量,根据具体需求,你还可以根据第4层端口号、ToS等来拆分流量。防火墙需要添加如下命令:

CODE
# Divid traffic to different mark iptables -t mangle -A PREROUTING -s 10.0.0.0/255.255.255.1 -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -s 10.0.0.1/255.255.255.1 -j MARK --set-mark 0x2 # NAT /sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE /sbin/iptables -t nat -A POSTROUTING -o ppp1 -j MASQUERADE
至此,双adsl链路的热互备及负载分担基本完成。 下面是一些运行结果 A.ifconfig显示结果

CODE
ppp0      Link encap:Point-to-Point Protocol         inet addr:220.163.38.208P-t-P:220.163.38.1Mask:255.255.255.255         UP POINTOPOINT RUNNING NOARP MULTICASTMTU:1492Metric:1         RX packets:100295 errors:0 dropped:0 overruns:0 frame:0         TX packets:67817 errors:0 dropped:0 overruns:0 carrier:0         collisions:0 txqueuelen:3         RX bytes:108844271 (103.8 Mb)TX bytes:6073206 (5.7 Mb) ppp1      Link encap:Point-to-Point Protocol         inet addr:220.163.36.57P-t-P:220.163.36.1Mask:255.255.255.255         UP POINTOPOINT RUNNING NOARP MULTICASTMTU:1492Metric:1         RX packets:150583 errors:0 dropped:0 overruns:0 frame:0         TX packets:125136 errors:0 dropped:0 overruns:0 carrier:0         collisions:0 txqueuelen:3         RX bytes:132921157 (126.7 Mb)TX bytes:8749585 (8.3 Mb)

smile787 发表于 2004-11-27 19:17:40

支持~~~

DreamCat 发表于 2004-11-27 19:20:45

good~~~只能是策略路由。

心想事成 发表于 2004-11-27 19:45:30

其实这样的做的效果并不好,因为它在两个IP间切换的时候会造成网络游戏的断线。而我的想法是,很简单的。分别用两台破机器A、B运行 coyote作adsl拨号。这样一来,就可以把adsl 的动态ip转换为“固定”IP。然后再用一台机器C运行openbsd接入A和B。openbsd的Packet Filter直接支持地址池的动态平衡,而且通过哈希算法保证某一个TCP连接只从地址池中的某个IP出去。这样就保证了网络游戏不会断掉。这是我的一点看法。

DreamCat 发表于 2004-11-27 20:02:54

我不这么看,断线是必然的,除了少数游戏能自动完成重连接过程而不需要重新登录。关键问题就是不管你如何路由,IP肯定是变化的。头都大了哦。

心想事成 发表于 2004-11-28 09:53:29

今天上午经过试验。证实我以上所说的完全可以。openbsd完全实现了流量实时平均分担。如图:用两台coyote 做adsl拨号,两个连接分别为pppoe-a和pppoe-b,然后再用openbsd做均衡,完美的做到了流量分但。

心想事成 发表于 2004-11-28 09:58:38

这是经过的路由抓图,请注意是变化的。

心想事成 发表于 2004-11-28 10:05:19

在路由上看到的数据:

bow 发表于 2004-11-28 13:21:37

老大你怎么在ROS 里添加的动态地址池的?

心想事成 发表于 2004-11-28 13:24:13

呵,你没有明白我的意思。我用roueteros做pppoe接入服务器。用两个coyote做pppoe拨号,最后用bsd做均衡。

DreamCat 发表于 2004-11-28 13:25:15

能画个拓扑图么?我的意思是把舔上。还有就是你都用的什么软件啊?按我的理解,一般的网络游戏都是根据来源IP决定连接的,而且只能是外网IP,不会参照不可路由的IP,如果切换了路由,IP自然也会跟着变化。结果就是连接中断。我前面说的能够重新建立连接的游戏还是太少了。是游戏软件问题。

心想事成 发表于 2004-11-28 13:37:11

如图:

DreamCat 发表于 2004-11-28 13:43:45

明白了。:)可是。。。。算了以后再说了。理论上我还是没明白。可惜没条件做测试。网络游戏哦。。。。

bow 发表于 2004-11-28 13:45:50

猫猫地址池分配路由链路是动态的,但分配之后就不会变了,除非断开从连。或有一个条线路失效。

DreamCat 发表于 2004-11-28 13:55:28

还是这句话:

QUOTE
按我的理解,一般的网络游戏都是根据来源IP决定连接的,而且只能是外网IP,不会参照不可路由的IP,如果切换了路由,IP自然也会跟着变化。结果就是连接中断。我前面说的能够重新建立连接的游戏还是太少了。是游戏软件问题
问题就在这里啊。
页: [1] 2
查看完整版本: 双adsl链路冗余互备及流量分担的实现