openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]
轉自: http://www.right.com.cn/forum/thread-169414-1-1.html ,本人未經測試,轉來自已備用
由于樹莓派2裝openwrt官方沒有imq模塊, 好像說ifb比較有優勢,優勢對于普通玩家來說,沒用~.
百度翻遍各種文檔,總算湊合起來可以用.有問題再提出來討論,歡迎測試.
有些參數是寫死在腳本里面,因為暫時設了htb的帶寬不可借用的,所以大小好像沒關系.
all_wan_down_speed=1500
all_wan_up_speed=50
腳本如下:
#!/bin/sh
#copyright by zhoutao0712 modify lynatgz??@2015.07.12
. /lib/functions.sh
#裝載核心模塊
load_modules(){
? ? #insmod imq numdevs=2
? ? #ifb模塊 代替 imq模塊
? ? insmod ifb
? ? insmod cls_fw
? ? insmod sch_hfsc
? ? insmod sch_sfq
? ? insmod sch_red
? ? insmod sch_htb
? ? insmod sch_prio
? ? insmod xt_multiport
? ? insmod xt_CONNMARK
? ? insmod xt_length
? ? insmod xt_hashlimit
? ? insmod cls_u32
? ? insmod xt_connlimit
? ? insmod xt_connbytes
? ? echo "" > ${qosv4_tmp_pach}/insmod
}
bak(){
<<!
#必需在函數里面才能多行注釋!
? ?? ???##sfq 隨機公平隊列,參數perturb 12秒后重新配置一次散列算法(默認為10). quantum 每輪當前的class能發送的字節數
? ?? ???#隊列 hadnle 編號為 $RULE_ID$IP4 (后面沒有用到這條隊列!)
? ?? ???#tc qdisc add dev ifb0 parent 1RULE_ID$IP4 handle $RULE_ID$IP4 sfq perturb 12 quantum 2000
!
}
qos_stop(){
? ? #for iface in $(tc qdisc show | grep htb | awk '{print $5}'); do
? ? for iface in $(tc qdisc show | awk '{print $5}'); do
? ?? ???#ifconfig的所有網卡
? ?? ???tc qdisc del dev "$iface" root
? ? done
? ? #刪鏈重建.NEW meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions
? ? iptables -t mangle -D PREROUTING -m state --state NEW -j NEWLMT
? ? #刪除舊規則
? ? iptables -t mangle -D NEWLMT -i pppoe+ -j RETURN
? ? iptables -D FORWARD -o pppoe+ -p udp -j UDPLMT
? ? iptables -t mangle -D FORWARD -i pppoe+ -j QOSDOWN
? ? iptables -t mangle -D POSTROUTING -o pppoe+ -j QOSUP
? ? #清空鏈規則
? ? iptables -t mangle -F QOSDOWN
? ? iptables -t mangle -F QOSUP
? ? iptables -t mangle -F NEWLMT
? ? iptables -F UDPLMT
? ? #iptables -t mangle -F PUNISH0
? ? #-X --delete-chain 刪除鏈
? ? iptables -t mangle -X QOSDOWN
? ? iptables -t mangle -X QOSUP
? ? iptables -t mangle -X NEWLMT
? ? iptables -X UDPLMT
? ? #iptables -t mangle -X PUNISH0
? ? [ -f ${qosv4_tmp_pach}/connlimit ] && {
? ?? ???sh ${qosv4_tmp_pach}/connlimit
? ?? ???echo "" > ${qosv4_tmp_pach}/connlimit
? ? }
? ? echo "QOS DELETE DONE";echo ""
}
#創建QOS專用鏈
qos_start(){
? ? #刪除各種鏈
? ? qos_stop
? ? #新建鏈NEWLMT, 用于新建連接控制??-N --new-chain
? ? iptables -t mangle -N NEWLMT
? ? #PREROUTING下一規則NEWLMT, 當匹配到新建鏈接全部入NEWLMT鏈規則
? ? iptables -t mangle -I PREROUTING -m state --state NEW -j NEWLMT
? ? #放行本地地址訪問局域網
? ? iptables -t mangle -A NEWLMT -s $(uci get network.lan.ipaddr)/24 -d $(uci get network.lan.ipaddr)/24 -j RETURN
? ? #放行upd端口53,67,68,1900 53端口為DNS端口,67和68是DHCP端口,
? ? iptables -t mangle -A NEWLMT -p udp -m multiport --dports 53,67,68,1900 -j RETURN
? ? #udp鏈接數超過100的包丟棄
? ? iptables -t mangle -A NEWLMT -p udp -m connlimit --connlimit-above 120 -j DROP
? ? #點對點的tcp握手包鏈接數超過200的包丟棄, 握手包SYN、ACK、FIN.connlimit: Allows you to restrict the number of parallel connections??to??a??server??per??client??IP address
? ? iptables -t mangle -A NEWLMT -p tcp --syn -m connlimit --connlimit-above 200 -j DROP
? ? #為每個源IP(收與發)建立匹配項, 產生速度25/s, 放行匹配的數據包, 超過速率的就可能丟棄了
? ? iptables -t mangle -A NEWLMT -m hashlimit --hashlimit-name newlmt --hashlimit-mode srcip --hashlimit 40 -j RETURN
? ? #限制tcp 80端口的請求包低于25/秒
? ? iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN
? ? #其他全部丟棄
? ? iptables -t mangle -A NEWLMT -j DROP
? ? #NEWLMT -I 插入首規則: 當網卡N收到數據, 回原路PREROUTING. 對端發起連接時,放行
? ? iptables -t mangle -I NEWLMT -i pppoe+ -j RETURN
? ? #新建鏈 UDPLMT, 用于控制udp, 不指定則入filter表
? ? iptables -N UDPLMT
? ? #為每個源IP(收與發)建立匹配項, 產生速度120/s, 放行匹配的數據包, 超過速率的就可能丟棄了
? ? iptables -A UDPLMT -m hashlimit --hashlimit-name udplmt --hashlimit-mode srcip --hashlimit 120 -j RETURN
? ? #限制udp 30, 8000端口的請求包低于30/秒
? ? iptables -A UDPLMT -p udp -m multiport --dports 53,8000 -m limit --limit 30 -j RETURN
? ? #其他全部丟棄
? ? iptables -A UDPLMT -j DROP
? ? #FORWARD -I 插入首規則:當網卡N發送數據udp, 入UDPLMT,
? ? iptables -I FORWARD -o pppoe+ -p udp -j UDPLMT
? ? iptables -t mangle -N QOSDOWN
? ? iptables -t mangle -N QOSUP
? ? #FORWARD -I 插入首規則:當網卡N收到數據, 入QOSDOWN? ? #INPUT 可能是訪問路由的, 不限制路由自身下行
? ? iptables -t mangle -I FORWARD -i pppoe+ -j QOSDOWN
? ? #FORWARD -I 插入首規則:當網卡N發送數據, 入QOSUP
? ? iptables -t mangle -I POSTROUTING -o pppoe+ -j QOSUP
<<!
? ? #小包不進入后面的打標記,小包不進入tc限速
!
? ? #放下行upd外部端口為53的, 53端口為DNS端口
? ? iptables -t mangle -A QOSDOWN -p udp --sport 53 -j RETURN
? ? #放上行upd外部端口為53的,53端口為DNS端口
? ? iptables -t mangle -A QOSUP -p udp --dport 53 -j RETURN
? ? #放下行tcp 不是初始包, 長度0:100字節的
? ? iptables -t mangle -A QOSDOWN -p tcp ! --syn -m length --length :100 -j RETURN
? ? #放上行tcp 不是初始包, 長度0:80字節的
? ? iptables -t mangle -A QOSUP -p tcp ! --syn -m length --length :80 -j RETURN
? ? #以下3條規則是一起生效的
? ? # iptables -t mangle -A PREROUTING -p tcp -m connmark ! --mark 80 -m web --path ".exe$ .rar$ .iso$ .zip$ .rm$ .rmvb$ .wma$ .avi$" -j CONNMARK --set-mark 80
? ? #connmark連接打標記, mask為80的, 設置連接mark為80
? ? #iptables -t mangle -A QOSDOWN -m connmark --mark 80 -j MARK --set-mark 80
? ? #iptables -t mangle -A QOSUP -m connmark --mark 80 -j MARK --set-mark 80
<<!
? ? #大包作特殊標記
!
? ? #QOSDOWN tcp包長度0:768字節的,下一規則為MARK,標記為255(配合TC做QOS流量限制或應用策略路由)
? ? #iptables -t mangle -A QOSDOWN -p tcp -m length --length :768 -j MARK --set-mark 255
? ? #QOSUP tcp包長度0:512字節的,下一規則為MARK,標記為255(配合TC做QOS流量限制或應用策略路由)
? ? #iptables -t mangle -A QOSUP -p tcp -m length --length :512 -j MARK --set-mark 255
? ? ##CONNBYTES模塊
? ? ##tcp 80,443,25,110 QOSDOWN下一規則為CONNBYTES, 可能這一寫法是錯誤的
? ? #iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -j CONNBYTES
? ? #iptables -t mangle -A QOSUP -p tcp -m multiport --dports 80,443,25,110 -j CONNBYTES
? ? ##--connbytes 1:200 match packets from a connection whose packets/bytes/average packet size is more than FROM and less than TO bytes/packets
? ? ##QOSUP tcp 80,443,25,110 端口 雙向的數據達到 0:51200字節, 下一規則為MARK,標記為254
? ? #iptables -t mangle -A QOSUP -p tcp -m multiport --sports 80,443,25,110??-m connbytes??--connbytes :51200 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254
? ? ##QOSDOWN tcp 80,443,25,110 端口 雙向的數據達到 0:102400字節, 下一規則為MARK,標記為254
? ? #iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -m connbytes??--connbytes :102400 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254
? ? #http://segmentfault.com/a/1190000000666869
? ? #http://blog.chinaunix.net/uid-7396260-id-3294466.html
? ? #http://it.chinawin.net/internet/article-24b44.html
? ? #http://www.cnblogs.com/endsock/archive/2011/12/09/2281519.html
? ? #tc cl ad dev ifb0 縮寫寫法.
? ? #ifb0-下行控制,??ifb1-上行控制
? ? ifconfig ifb1 up
? ? #下載速度控制,限制內網網卡發送給用戶的數據包速度
? ? #1. htb可以很容易地保證每個類別的帶寬, 雖然它也允許特定的類可以突破帶寬上限, 占用別的類的帶寬
? ? #根隊列規則, 把htb隊列綁定到 ifb0 , 并指定了一個 handle 句柄 1: (效果1:0) 用于標識它下面的子類, 沒標識的分配默認子類 9999 (默認值只是設置而已, 可以不用)
? ? tc qdisc add dev eth0 root handle 1: htb default 999
? ? tc qdisc add dev ifb1 root handle 1: htb default 999
? ? #2. 為隊列建一個主干類, htb的主干類不能互相借用帶寬, 但是一個父類的所有子類之間可以借用帶寬, parent 1: 是剛才建立的 handle 1: , 父類為1:0 , 分類號 1:1
? ? #ceil 不配則值與rate一樣, prio 0 burst 1599b cburst 1599b
? ? tc class add dev eth0 parent 1: classid 1:1 htb rate $((all_wan_down_speed))kbps
? ? tc class add dev ifb1 parent 1: classid 1:1 htb rate $((all_wan_up_speed))kbps
? ? #每個IP限速, 下行 & 上行
? ? config_foreach? ?get_qos_ip_limit? ?qos_ip
? ? #tc class add dev ifb0 parent 1:1 classid 1:a254 htb rate $((GLOBAL_DOWN/10))kbps ceil $((GLOBAL_DOWN*7/10))kbps quantum 8000 prio 3
? ? ##sfq 隨機公平隊列,參數perturb 12秒后重新配置一次散列算法(默認為10). quantum 每輪當前的class能發送的字節數
? ? #tc qdisc add dev ifb0 parent 1:a254 handle a254 sfq perturb 12 quantum 1500
? ? #tc filter add dev ifb0 parent 1: protocol ip prio 10 handle 254 fw flowid 1:a254
}
wan_list=$(ifconfig | grep "oint-to-Point Protocol" | cut -d" " -f1)
#所有普通IP單獨限速 (暫不調用)
qos_ip_limit() {
? ? #傳入參數: 1-limit_ip? ?2-DOWNLOADR 保證? ? 3-DOWNLOADC 最大??
? ? #? ?? ?? ?? ?? ?4-UPLOADR 保證? ?5-UPLOADC 最大? ? 6-ip_prio? ?? ???7-tcplimit??8-udplimit
? ? #保存IP第4個數字
? ? start=$(echo $1|cut -d '-' -f1|cut -d '.' -f4)
? ? end=$(echo $1|cut -d '-' -f2|cut -d '.' -f4)
? ? #NET 保存前3個數字 192.168.1
? ? NET=$(echo $1|cut -d '.' -f1-3)
? ? #記錄在處理第幾條規則
? ? RULE_ID=$((RULE_ID+1))
? ? echo "QOS_IP_LIMIT??limit_ip=$1??DOWNLOADR=$2? ?DOWNLOADC=$3??UPLOADR=$4 UPLOADC=$5 ip_prio=$6??tcplimit=$7??udplimit=$8"
? ? while [ $start -le $end ]
? ? do
? ?? ???#不足2位前面補0
? ?? ???IP4=$(printf "%02x" $start)
? ?? ???echo "$NET.start??end=$end??RULE_ID=$RULE_ID IP4=$IP4"
? ?? ???#QOSDOWN 標記tc需要限速的包, 標記為255
? ?? ???iptables -t mangle -A QOSDOWN -d $NET.$start -j MARK --set-mark $start
? ?? ???#QOSUP 標記tc需要限速的包, 標記為 1255
? ?? ???iptables -t mangle -A QOSUP -s $NET.$start -j MARK --set-mark $((start+1000))
? ?? ???##u32過濾器匹配ip目標地址, u32 match ip dst 10.0.0.229/32??##防火墻標記過濾器 handle 254 fw
? ?? ???#eth0 葉分類,parent 1:1能借用帶寬, 不想借用,寫成parent 1:, 改用主干類, 主干ceil不啟作用
? ?? ???tc class add dev eth0 parent 1: classid 1RULE_ID$IP4 htb rate $2kbps ceil $3kbps prio $6
? ?? ???#3. 設過濾器, handle 255 fw-根據防火墻標識控制標記為 255 的包,(與 iptables, set-mark對應), 父類1:, 送到子類1RULE_ID$IP4處理
? ?? ???tc filter add dev eth0 parent 1: protocol ip prio 1 handle $start fw flowid 1RULE_ID$IP4
? ?? ???#ifb1 葉分類,parent 1:1能借用帶寬, 不想借用,寫成parent 1:, 改用主干類
? ?? ???tc class add dev ifb1 parent 1: classid 1RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
? ?? ???tc filter add dev ifb1 parent 1: protocol ip prio 1 handle $((start+1000)) fw flowid 1:$RULE_ID$IP4
? ?? ???for pppoe_ifconfig in $wan_list;
? ?? ???do
? ?? ?? ?? ?#pppoe 重定向到 ifb0? ? #redirect 會進入blackhole
? ?? ?? ?? ?[ -z $init ] && {
? ?? ?? ?? ?? ? tc qdisc add dev $pppoe_ifconfig root handle 1: htb default 999
? ?? ?? ?? ?}
? ?? ?? ?? ?tc class add dev $pppoe_ifconfig parent 1: classid 1:$RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
? ?? ?? ?? ?tc filter add dev $pppoe_ifconfig parent 1: protocol ip prio 1 handle $((start+1000)) fw flowid 1:$RULE_ID$IP4 action mirred egress mirror dev ifb1
? ?? ???done
? ?? ???init=1
? ?? ???#tc class add dev ifb1 parent 1: classid 1:$RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
? ?? ???#tc filter add dev ifb1 parent 1: protocol ip prio 1 u32 match ip src $NET.$start flowid 1:$RULE_ID$IP4
<<!
? ?? ???#TCP UDP 連接數限制
? ?? ???[ "$7" != "0" ] && {
? ?? ?? ?? ?echo "iptables -t mangle -D FORWARD -p tcp -d $NET.$start -m connlimit --connlimit-above $7 -j DROP" >> $qosv4_tmp_pach/connlimit
? ?? ?? ?? ?iptables -t mangle -A FORWARD -p tcp -d $NET.$start -m connlimit --connlimit-above $7 -j DROP
? ?? ???}
? ?? ???[ "$8" != "0" ] && {
? ?? ?? ?? ?echo "iptables -t mangle -D FORWARD -p udp -d $NET.$start -m connlimit --connlimit-above $8 -j DROP" >> $qosv4_tmp_pach/connlimit
? ?? ?? ?? ?iptables -t mangle -A FORWARD -p udp -d $NET.$start -m connlimit --connlimit-above $8 -j DROP
? ?? ???}
!
? ?? ???start=$((start+1))
? ? done
}
#沒有配置限速的IP, 設置默認規則
qos_default_limit(){
? ? tc class add dev ifb1 parent 1:1 classid 1:999 htb rate 8kbps ceil 12kbps prio 7
? ? tc class add dev ifb0 parent 1:1 classid 1:999 htb rate 250kbps ceil 300kbps prio 7
}
#QOS白名單
qos_white(){
? ? #192.168.1.8,192.168.1.80-192.168.1.90有zhoutao0712發放的免死金牌
? ? #iptables -t mangle -I PUNISH0 -m iprange --src-range 192.168.1.80-192.168.1.90 -j RETURN
? ? iptables -t mangle -I PUNISH0 -s $nolimit_ip -j RETURN
}
<<!
? ? config qos_settings
? ?? ???option UP '100'
? ?? ???option UPLOADR2 '1'
? ?? ???option UPLOADC2 '5'
? ?? ???option DOWNLOADR2 '1'
? ?? ???option DOWNLOADC2 '2'
? ?? ???option DOWNLOADR '50'
? ?? ???option UPLOADR '20'
? ?? ???option qos_scheduler '0'
? ?? ???option DOWN '2600'
? ?? ???option enable '0'
!
#讀取總網速配置
get_qos_config(){
? ? config_get GLOBAL_ENABLE $1 enable
? ? config_get GLOBAL_UP $1 UP
? ? config_get GLOBAL_DOWN $1 DOWN
? ? #config_get GLOBAL_UPLOADR2 $1 UPLOADR2
? ? #config_get GLOBAL_UPLOADC2 $1 UPLOADC2
? ? #config_get GLOBAL_DOWNLOADR2 $1 DOWNLOADR2
? ? #config_get GLOBAL_DOWNLOADC2 $1 DOWNLOADC2
? ? #config_get qos_scheduler $1 qos_scheduler
? ? echo "get_qos_config: GLOBAL_ENABLE=$GLOBAL_ENABLE GLOBAL_UP=$GLOBAL_UP??GLOBAL_DOWN=$GLOBAL_DOWN"
}
<<!
? ? config qos_ip
? ?? ???option enable '1'
? ?? ???option limit_ips '192.168.1.12'
? ?? ???option limit_ipe '192.168.1.19'
? ?? ???option UPLOADR '10'??保證
? ?? ???option UPLOADC '16'??最大
? ?? ???option DOWNLOADR '150'??保證
? ?? ???option DOWNLOADC '2200'??最大
? ?? ???option tcplimit '0'
? ?? ???option udplimit '0'
? ?? ???option ip_prio '5'
!
#循環讀取每條IP限速規則, 并調用限速
get_qos_ip_limit(){
? ? config_get qos_limit_enable $1 enable
? ? config_get limit_ips $1 limit_ips
? ? config_get limit_ipe $1 limit_ipe
? ? config_get ip_prio $1 ip_prio
? ? config_get UPLOADC $1 UPLOADC
? ? config_get DOWNLOADC $1 DOWNLOADC
? ? config_get UPLOADR $1 UPLOADR
? ? config_get DOWNLOADR $1 DOWNLOADR
? ? config_get tcplimit $1 tcplimit
? ? config_get udplimit $1 udplimit
? ? limit_ip=$limit_ips-$limit_ipe
? ? #echo "get_qos_ip_limit: enable=$qos_limit_enable limit_ips=$limit_ips??limit_ipe=$limit_ipe ip_prio=$ip_prio UPLOADC=$UPLOADC DOWNLOADC=$DOWNLOADC"
? ? #放在這里調用是因為foreach循環調用
? ? [ "$qos_limit_enable" == "1" ] && qos_ip_limit $limit_ip $DOWNLOADR $DOWNLOADC $UPLOADR $UPLOADC $ip_prio $tcplimit $udplimit
}
<<!
? ? config 'qos_nolimit_ip'
? ?? ???option 'nolimit_ip' '192.168.1.1'
? ?? ???option 'nolimit_mac' '00:00:00:00:00'
? ?? ???option 'enable' '0'
!
#讀取不限制ip和mac
get_qos_nolimit_ip(){
? ? config_get enable $1 enable
? ? config_get nolimit_ip $1 nolimit_ip
? ? config_get nolimit_mac $1 nolimit_mac
? ? [ "$enable" == "1" ]&&printf "|grep -v??$nolimit_mac " >>${qosv4_tmp_pach}/qosv4_nolimit_mac
}
usage() {
cat << EOF
? ? Usage: $0 [start|stop]
EOF
? ? exit 1
}
#lan_net
#單位: kbps--千字節/s
all_wan_down_speed=1500
all_wan_up_speed=50
#each_wan_up_speed=30
qosv4_tmp_pach="/tmp/qosv4"
[ -d $qosv4_tmp_pach ] || mkdir -p ${qosv4_tmp_pach}
case $1 in
? ? start)
? ?? ???config_load qosv4
? ?? ???echo "start qosv4........"
? ?? ???rm -rf ${qosv4_tmp_pach}/qosv4_nolimit_mac
? ?? ???config_foreach? ?get_qos_config? ?qos_settings
? ?? ???#GLOBAL_ENABLE=1
? ?? ???echo "qosv4 enable=$GLOBAL_ENABLE "
? ?? ???if [ "$GLOBAL_ENABLE" == "1" ];then
? ?? ?? ?? ?#存在insmod文件表示已經加載過了
? ?? ?? ?? ?[ -f ${qosv4_tmp_pach}/insmod ] || load_modules >/dev/null 2>&1
? ?? ?? ?? ?qos_start
? ?? ?? ?? ?#qos_default_limit
? ?? ?? ?? ?#QOS白名單
? ?? ?? ?? ?#config_foreach? ?get_qos_nolimit_ip? ?qos_nolimit_ip
? ?? ?? ?? ?#qos_white
? ?? ???else
? ?? ?? ?? ?echo "ENABLE = 0.";echo ""
? ?? ?? ?? ?qos_stop
? ?? ???fi
? ?? ???;;
? ? stop)
? ?? ???qos_stop
? ?? ???#qos_stop >/dev/null 2>&1
? ?? ???;;
? ? *) usage;;
esac
轉載于:https://www.cnblogs.com/d9394/p/10611690.html
總結
以上是生活随笔為你收集整理的openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「SDOI2016」储能表(数位dp)
- 下一篇: Unity User Group深圳站—