OpenWrt > ADSL单线多拨,负载均衡(供参考)

ADSL单线多拨,负载均衡

  • 2021年11月更新:如果是K2P A2版本硬件,请参考更简易的步骤,更加高效,不需要太多代码知识。 K2P刷机-坐标北京Unicom

前题


  • 硬件:路由器,刷入OpenWrt
  • 一些背景知识和动手能力

目标效果图


实际例子Sample

步骤


  1. 使用SSH 登陆路由器。I.e. ssh root@192.168.2.1
  2. 运行/usr/bin/duobo。日志类似:
  3. sh: 2: unknown operand
    Killed
    Warning: Unable to locate ipset utility, disabling ipset support * Flushing IPv4 filter table * Flushing IPv4 nat table * Flushing IPv4 mangle table * Flushing IPv4 raw table * Flushing conntrack table … * Populating IPv4 filter table * Zone ‘lan’
    * Zone ‘wan’
    * Rule ‘Allow-DHCP-Renew’
    * Rule ‘Allow-Ping’
    * Rule ‘51413’
    * Rule ‘9091’
    * Rule ‘9000’
    * Rule ‘6800’
    * Forward ‘lan’ -> ‘wan’
    * Populating IPv4 nat table * Zone ‘lan’
    * Zone ‘wan’
    * Populating IPv4 mangle table * Zone ‘lan’
    * Zone ‘wan’
    * Populating IPv4 raw table * Zone ‘lan’
    * Zone ‘wan’
    * Set tcp_ecn to off * Set tcp_syncookies to on * Set tcp_window_scaling to on * Running script ‘/etc/firewall.user’
    * Running script ‘/usr/share/miniupnpd/firewall.include’
    * Running script ‘/usr/share/qos_gargoyle/firewall.include’
    ! Failed with exit code 1 ___________________________________________________
    开始第1次拔号………..
    正在并发拔号中………….
    等待3秒………….
    [3]拔[0]拔成功, 小于设定的[2]拔,将重新拔号…

    _________________________

    View Code

  4. 如果没有成功并发多播,根据提示信息调整duobo的内部参数设置,重新运行。分享一些技巧:

  5. number=10 #number是重拔次数,本脚本启动后一共尝试的次数 n\=7 #n是几拔,同时发出几拨,理论上设置越大成功概率越大! ok\=2 #ok是拔上几次后退出拔号, 要实现的预期目标
    wait\=5 #wait time 每次单线多拨失败后,重试的等待时间

    • 原则:失败多次以后,建议冷重启路由器,多个运行中的脚本会互相冲突,把问题复杂化。
    • 多拨失败以后,耐心等上1分钟;很多次的多播成功都是脚本完成以后退出,然后60秒内获取了超过预期的多条链接。
    • 把n调到7,这样会虚拟出很多wan接口,根据硬件性能,理论上设置越大成功概率越大!
    • 将ok调低一点,比如2。我觉得别太贪心,如果能稳定多播2个ADSL的IP,那其实概率上更折中了稳定性和高负载下的带宽均衡。
    • wait的时间我感觉5秒-8秒差不多,这个要看运行日志,做相应调整。
    • 看懂程序的原理,根据实际情况调整脚本程序。比如:这个版本的程序是这么多播的,ifup $prefix$i

遗留问题


1 开始第3次拔号………..
2 正在并发拔号中………….
3 等待10秒………….
4 pppoe-wan Link encap:Point-to-Point Protocol
5 pppoe-wan3 Link encap:Point-to-Point Protocol
6 [3]拔[2]拔成功, 大于或等于设定的[2]拨,退出拔号…
7 Error: an inet address is expected rather than “dev”.
8 iptables v1.4.10: Couldn’t load target `zone_wan_notrack’:File not found
9
10 Try `iptables -h’ or ‘iptables –help’ for more information.
11 iptables v1.4.10: Couldn’t load target `zone_wan_nat’:File not found 12
13 Try `iptables -h’ or ‘iptables –help’ for more information.
14 iptables: No chain/target/match by that name. 15 iptables v1.4.10: Couldn’t load target `zone_wan’:File not found 16
17 Try `iptables -h’ or ‘iptables –help’ for more information.
18 iptables: No chain/target/match by that name. 19 iptables: No chain/target/match by that name. 20 iptables: No chain/target/match by that name. 21 iptables: No chain/target/match by that name. 22 iptables: No chain/target/match by that name. 23 iptables: No chain/target/match by that name. 24 iptables: No chain/target/match by that name. 25 Error: an inet address is expected rather than “dev”. 26 iptables v1.4.10: Couldn’t load target `zone_wan_notrack’:File not found 27
28 Try `iptables -h’ or ‘iptables –help’ for more information.
29 iptables v1.4.10: Couldn’t load target `zone_wan_nat’:File not found 30
31 Try `iptables -h’ or ‘iptables –help’ for more information.
32 iptables: No chain/target/match by that name. 33 iptables v1.4.10: Couldn’t load target `zone_wan’:File not found 34
35 Try `iptables -h’ or ‘iptables –help’ for more information.
36 iptables: No chain/target/match by that name. 37 iptables: No chain/target/match by that name. 38 iptables: No chain/target/match by that name. 39 iptables: No chain/target/match by that name. 40 iptables: No chain/target/match by that name. 41 iptables: No chain/target/match by that name. 42 iptables: No chain/target/match by that name. 43 Error: an IP address is expected rather than “dev”
44 192.168.2.0/24 dev br-lan proto kernel scope link src 192.168.2.1
45 221.218.232.1 dev pppoe-wan3 proto kernel scope link src 123.112.248.148
46 221.218.232.1 dev pppoe-wan proto kernel scope link src 221.218.236.51
47 Kernel IP routing table 48 Destination Gateway Genmask Flags Metric Ref Use Iface 49 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 br-lan 50 221.218.232.1 0.0.0.0 255.255.255.255 UH 0 0 0 pppoe-wan3 51 221.218.232.1 0.0.0.0 255.255.255.255 UH 0 0 0 pppoe-wan

View Error Code

显然这个0.3版本的脚本不完全适用于我的路由器,有时间我需要查查原因。

估计都是关于iptables

有没有大侠探讨一下?

修正了下面版本中的一个错误

line 19:if [ $j -ge $ok ] ;

多拨代码(V0.3)


 1 #!/bin/sh
 2 #modified by muziling v0.3
 3 #并发多拨脚本
 4 
 5 #number是重拔次数
 6 #n是几拔
 7 #ok是拔上几次后退出拔号
 8 #wait time
 9 
 10 number=10
 11 n=3
 12 ok=2
 13 wait\=5
 14 # avoid same with feixiang's N-WAN naming and must start with "wan"
 15 prefix=wan
 16 vthprefix=vth
 17 
 18 j=$(ifconfig | grep pppoe-wan | wc -l)
 19 if \[ "$j" >= "$ok" \] ; 20 then
 21     echo 已经是\[$j\]拔了,退出拔号... 22     exit 0
 23 fi
 24 
 25 if \[ -f /etc/config/nwannumset \] ;
 26 then
 27     uci set nwannumset.@macvlan\_numset\[0\].macvlan\_num=1
 28     uci commit nwannumset
 29 fi
 30 for i in $( seq 1 $(($n-1)))
 31 do
 32     ifname=$prefix$i
 33     ifvth=$vthprefix$i
 34     #ifwan=$(uci get network.wan.ifname)
 35     pppoe\_name=$(uci get network.wan.username) 
 36     pppoe\_pw=$(uci get network.wan.password) 
 37 
 38     if \[ $(ip link | grep " ${ifvth}@eth0.2:" | wc -l) == "0" \] ; 39     then
 40         macfac=$(ifconfig | grep eth0.2 | tr -s " " | cut -d " " -f5 | cut -b 1\-8)
 41         mac="$macfac:"$(md5sum /proc/sys/kernel/random/uuid | sed 's/\\(..\\)/&:/g' | cut -b 1\-8 | tr \[a-f\] \[A-F\])
 42         ip link add link eth0.2 $ifvth type macvlan 43         ifconfig $ifvth hw ether $mac 44     fi
 45 
 46     # add /etc/config/network
 47     uci delete network.$ifname
 48     uci set network.$ifname=interface
 49     uci set network.$ifname.ifname=$ifvth
 50     #uci set network.$ifname.\_orig\_ifname=eth0.2
 51     #uci set network.$ifname.\_orig\_bridge=false
 52     uci set network.$ifname.proto=pppoe
 53     uci set network.$ifname.username=$pppoe\_name
 54     uci set network.$ifname.password=$pppoe\_pw
 55     uci set network.$ifname.auto=0
 56     uci set network.$ifname.defaultroute=0
 57     uci set network.$ifname.peerdns=1
 58     uci set network.$ifname.pppd\_options="plugin rp-pppoe.so syncppp $n"
 59 
 60     # add /etc/config/dhcp
 61     uci delete dhcp.$ifvth
 62     uci set dhcp.$ifvth=dhcp 
 63     uci set dhcp.$ifvth.interface=$ifname
 64     uci set dhcp.$ifvth.ignore=1 
 65 
 66     if \[ -f /etc/config/nwan \] ;
 67     then
 68         uci delete nwan.$ifname
 69         uci set nwan.$ifname=interface 
 70         uci set nwan.$ifname.name=telecom 
 71         uci set nwan.$ifname.route=balance 
 72         uci set nwan.$ifname.weight=1 
 73         uci set nwan.$ifname.uptime\=0day,0hour,0min
 74         uci commit nwan
 75     fi
 76 done
 77 uci set network.wan.defaultroute=0
 78 uci set network.wan.peerdns=1
 79 uci set network.wan.pppd\_options="plugin rp-pppoe.so syncppp $n"
 80 uci commit network
 81 uci commit dhcp
 82 
 83 fw\_wan\_list=$(uci show network |grep =interface |grep -v lan|grep -v loopback |cut -d"." -f2 | awk -F "\=" '{printf $1" "}')
 84 uci set firewall.@zone\[1\].network="$fw\_wan\_list"
 85 uci commit firewall
 86 /etc/init.d/firewall restart
 87 
 88 for q in $( seq 1 $number ) 89 do
 90     echo
 91     echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 92     echo 开始第$q次拔号........... 93     killall -q -SIG pppd
 94     if \[ "$q" == "1" \] ; 95     then
 96         for i in $( seq 1 $(($n-1)))
 97         do
 98             ifup $prefix$i
 99         done
100     fi
101 
102     echo 正在并发拔号中............. 103     echo 等待$wait秒............. 104     sleep $wait
105 
106     j=$(ps | grep pppd | wc -l) 107     ! \[ "$j" -ge "$n" \]  && ifup ${prefix}1
108 
109     ifconfig|grep pppoe 110     j=$(ifconfig | grep pppoe-wan | wc -l) 111 
112     ! \[ "$j" -ge "$ok" \] && echo \[$n\]拔\[$j\]拔成功, 小于设定的\[$ok\]拔,将重新拔号... 113     \[ "$j" -ge "$ok" \] && echo \[$n\]拔\[$j\]拔成功, 大于或等于设定的\[$ok\]拨,退出拔号... 114 
115     if \[ "$j" -ge "$ok" \] ; 116     then
117         for i in $( seq 0 $(($n-1))) 118         do
119             if \[ "$i" == "0" \] ; 120             then
121                 interface=wan 122             else
123                 interface=$prefix$i 124             fi
125             if \[ $(ifconfig | grep "pppoe-$interface " | wc -l) == "0" \] ; 126             then
127 ifdown $interface 128             fi
129         done
130 break 131     fi
132 done
133 # kill ddns sleep and re-check wan ip change 134 killall sleep
135 
136 j=$(ifconfig | grep pppoe-wan | wc -l) 137 ! \[ "$j" -ge 0 \] && reboot 138 
139 #ppoename=$(ifconfig |grep 'ppoe-' |awk '{print substr($1,7)}'|tr '\\n' ' ') 140 ppoename=$(ifconfig |grep 'ppoe-' |awk '{print $1}'|tr '\\n' ' ') 141 i=0
142 vias=""
143 for wan\_ifname in $ppoename 144 do
145     vias="$vias nexthop via $wan\_ip dev $wan\_ifname weight 1 "
146     let "rt=100+$i"
147     i=$(($i+1)) 148 ip route flush table $rt 149 ip route add default via $wan\_ip dev $wan\_ifname table $rt 150     ip route add table $rt to $(ip route | grep br-lan) 151 
152     if \[ $(iptables -t nat -vxnL POSTROUTING | grep -c " $wan\_ifname ") == "0" \] ; 153     then
154         iptables -t raw -A PREROUTING -i $wan\_ifname -j zone\_wan\_notrack 155         iptables -t nat -A PREROUTING -i $wan\_ifname -j zone\_wan\_prerouting 156         iptables -t nat -A POSTROUTING -o $wan\_ifname -j zone\_wan\_nat 157         iptables -t filter -A forward -i $wan\_ifname -j zone\_wan\_forward 158         iptables -t filter -A input -i $wan\_ifname -j zone\_wan 159         iptables -t filter -A zone\_wan\_ACCEPT -o $wan\_ifname -j ACCEPT 160         iptables -t filter -A zone\_wan\_ACCEPT -i $wan\_ifname -j ACCEPT 161         iptables -t filter -A zone\_wan\_DROP -o $wan\_ifname -j DROP 162         iptables -t filter -A zone\_wan\_DROP -i $wan\_ifname -j DROP 163         iptables -t filter -A zone\_wan\_REJECT -o $wan\_ifname -j reject 164         iptables -t filter -A zone\_wan\_REJECT -i $wan\_ifname -j reject 165     fi
166     iptables -A PREROUTING -t mangle -i $wan\_ifname -j MARK --set-mark $rt 167     iptables -t mangle -A zone\_wan\_MSSFIX -o $wan\_ifname -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 168 ip rule add fwmark $rt table $rt prio $rt 169 done
170 ip route del default 171 ip route add default scope global $vias 172 ip route flush cache 173 ip route list 174 route -n 175 root@OpenWrt:~# 

View Code (duobo)

修订版(V0.3.1)

 1 #!/bin/sh
 2 #modified by muziling v0.3
 3 #并发多拨脚本
 4 #modified by carl v0.3.1 (修正一处bug,改善友好提示信息) 5 
 6 #number是重拔次数,本脚本启动后一共尝试的次数
 7 #n是几拔,同时发出几拨,理论上设置越大成功概率越大!
 8 #ok是拔上几次后退出拔号, 要实现的预期目标
 9 #wait time 每次单线多拨失败后,重试的等待时间 10 
 11 number=15
 12 n=7
 13 ok=2
 14 wait\=8
 15 # avoid same with feixiang's N-WAN naming and must start with "wan"
 16 prefix=wan
 17 vthprefix=vth
 18 
 19 j=$(ifconfig | grep pppoe-wan | wc -l)
 20 if \[ $j -ge $ok \] ;
 21 then
 22     echo 已经是\[$j\]拔了,退出拔号程序。 23     exit 0
 24 fi
 25 
 26 if \[ -f /etc/config/nwannumset \] ;
 27 then
 28     uci set nwannumset.@macvlan\_numset\[0\].macvlan\_num=1
 29     uci commit nwannumset
 30 fi
 31 
 32 for i in $( seq 1 $(($n-1)))
 33 do
 34     ifname=$prefix$i
 35     ifvth=$vthprefix$i
 36     #ifwan=$(uci get network.wan.ifname)
 37     pppoe\_name=$(uci get network.wan.username) 
 38     pppoe\_pw=$(uci get network.wan.password) 
 39 
 40     if \[ $(ip link | grep " ${ifvth}@eth0.2:" | wc -l) == "0" \] ; 41     then
 42         macfac=$(ifconfig | grep eth0.2 | tr -s " " | cut -d " " -f5 | cut -b 1\-8)
 43         mac="$macfac:"$(md5sum /proc/sys/kernel/random/uuid | sed 's/\\(..\\)/&:/g' | cut -b 1\-8 | tr \[a-f\] \[A-F\])
 44         ip link add link eth0.2 $ifvth type macvlan 45         ifconfig $ifvth hw ether $mac 46         echo 更换MAC完毕$ifvth. 47     fi
 48 
 49     # add /etc/config/network
 50     uci delete network.$ifname
 51     uci set network.$ifname=interface
 52     uci set network.$ifname.ifname=$ifvth
 53     #uci set network.$ifname.\_orig\_ifname=eth0.2
 54     #uci set network.$ifname.\_orig\_bridge=false
 55     uci set network.$ifname.proto=pppoe
 56     uci set network.$ifname.username=$pppoe\_name
 57     uci set network.$ifname.password=$pppoe\_pw
 58     uci set network.$ifname.auto=0
 59     uci set network.$ifname.defaultroute=0
 60     uci set network.$ifname.peerdns=1
 61     uci set network.$ifname.pppd\_options="plugin rp-pppoe.so syncppp $n"
 62 
 63     # add /etc/config/dhcp
 64     uci delete dhcp.$ifvth
 65     uci set dhcp.$ifvth=dhcp 
 66     uci set dhcp.$ifvth.interface=$ifname
 67     uci set dhcp.$ifvth.ignore=1 
 68 
 69     if \[ -f /etc/config/nwan \] ;
 70     then
 71         uci delete nwan.$ifname
 72         uci set nwan.$ifname=interface 
 73         uci set nwan.$ifname.name=unicom 
 74         uci set nwan.$ifname.route=balance 
 75         uci set nwan.$ifname.weight=1 
 76         uci set nwan.$ifname.uptime\=0day,0hour,0min
 77         uci commit nwan
 78     fi
 79 done
 80 
 81 uci set network.wan.defaultroute=0
 82 uci set network.wan.peerdns=1
 83 uci set network.wan.pppd\_options="plugin rp-pppoe.so syncppp $n"
 84 uci commit network
 85 uci commit dhcp
 86 
 87 fw\_wan\_list=$(uci show network |grep =interface |grep -v lan|grep -v loopback |cut -d"." -f2 | awk -F "\=" '{printf $1" "}')
 88 uci set firewall.@zone\[1\].network="$fw\_wan\_list"
 89 uci commit firewall
 90 /etc/init.d/firewall restart
 91 
 92 for q in $( seq 1 $number ) 93 do
 94     echo
 95     echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 96     echo 开始第$q次拔号........... 97     killall -q -SIG pppd
 98     if \[ "$q" == "1" \] ; 99     then
100         for i in $( seq 1 $(($n-1))) 101         do
102 ifup $prefix$i 103         done
104     fi
105 
106     echo 正在并发拔号中............. 107     echo 等待$wait秒............. 108     sleep $wait
109 
110     j=$(ps | grep pppd | wc -l) 111     ! \[ "$j" -ge "$n" \]  && ifup ${prefix}1
112 
113     ifconfig | grep pppoe 114     j=$(ifconfig | grep pppoe-wan | wc -l) 115 
116     ! \[ "$j" -ge "$ok" \] && echo \[$n\]拔\[$j\]拔成功, 小于设定的\[$ok\]拔,将重新拔号... 117     \[ "$j" -ge "$ok" \] && echo \[$n\]拔\[$j\]拔成功, 大于或等于设定的\[$ok\]拨,退出拔号... 118     
119     if \[ "$j" -ge "$ok" \] ; 120     then
121         for i in $( seq 0 $(($n-1))) 122         do
123             if \[ "$i" == "0" \] ; 124             then
125                 interface=wan 126             else
127                 interface=$prefix$i 128             fi
129             if \[ $(ifconfig | grep "pppoe-$interface " | wc -l) == "0" \] ; 130             then
131 ifdown $interface 132             fi
133         done
134 break 135     fi
136 done # done/tried all tring times $number 137 
138 # kill ddns sleep and re-check wan ip change 139 killall sleep
140 
141 # reboot the machine if failed tried times 142 #sleep $wait
143 j=$(ifconfig | grep pppoe-wan | wc -l) 144 ! \[ "$j" -gt 0 \] && reboot 145 
146 
147 echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 148 echo 开始N-WAN负载均衡功能... 149 #ppoename=$(ifconfig |grep 'ppoe-' |awk '{print substr($1,7)}'|tr '\\n' ' ') 150 ppoename=$(ifconfig|grep 'ppoe-' |awk '{print $1}'|tr '\\n' ' ') 151 i=0
152 vias=""
153 for wan\_ifname in $ppoename 154 do
155     vias="$vias nexthop via $wan\_ip dev $wan\_ifname weight 1 "
156     let "rt=100+$i"
157     i=$(($i+1)) 158 ip route flush table $rt 159 #REMOVE ERROR 160 ip route add default via $wan\_ip dev $wan\_ifname table $rt 161     ip route add table $rt to $(ip route | grep br-lan) 162 
163     if \[ $(iptables -t nat -vxnL POSTROUTING | grep -c " $wan\_ifname ") == "0" \] ; 164     then
165 #REMOVE ERROR 166         iptables -t raw -A PREROUTING -i $wan\_ifname -j zone\_wan\_notrack 167         iptables -t nat -A PREROUTING -i $wan\_ifname -j zone\_wan\_prerouting 168 #REMOVE ERROR 169         iptables -t nat -A POSTROUTING -o $wan\_ifname -j zone\_wan\_nat 170         iptables -t filter -A forward -i $wan\_ifname -j zone\_wan\_forward 171 #REMOVE ERROR 172         iptables -t filter -A input -i $wan\_ifname -j zone\_wan 173         iptables -t filter -A zone\_wan\_ACCEPT -o $wan\_ifname -j ACCEPT 174         iptables -t filter -A zone\_wan\_ACCEPT -i $wan\_ifname -j ACCEPT 175         iptables -t filter -A zone\_wan\_DROP -o $wan\_ifname -j DROP 176         iptables -t filter -A zone\_wan\_DROP -i $wan\_ifname -j DROP 177         iptables -t filter -A zone\_wan\_REJECT -o $wan\_ifname -j reject 178         iptables -t filter -A zone\_wan\_REJECT -i $wan\_ifname -j reject 179     fi
180     
181     iptables -A PREROUTING -t mangle -i $wan\_ifname -j MARK --set-mark $rt 182     iptables -t mangle -A zone\_wan\_MSSFIX -o $wan\_ifname -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 183 ip rule add fwmark $rt table $rt prio $rt 184 done
185 
186 ip route del default 187 
188 echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 189 echo 下面执行ip route add default scope global $vias 190 ip route add default scope global $vias 191 
192 ip route flush cache 193 
194 echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 195 echo 下面输出ip route list 196 ip route list 197 
198 echo \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 199 echo 下面输出route -n 200 route -n

参考文献


OpenWrt For AR71xx系列 ar2 Tr 脱机 N-WAN r48549

自己动手 4530R 脱机 Samba U-BOOT 多拨(11-04更新部分问题说明,请看2楼)

[0916更新]WR703N WR720N 及其他各类 OpenWRT类路由实现一号多拨带宽叠加教程


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注