diff options
-rwxr-xr-x | hfsc_shaper.sh | 298 | ||||
-rw-r--r-- | qos_ports.sh | 25 |
2 files changed, 205 insertions, 118 deletions
diff --git a/hfsc_shaper.sh b/hfsc_shaper.sh index 3504c68..2321e7b 100755 --- a/hfsc_shaper.sh +++ b/hfsc_shaper.sh @@ -1,7 +1,7 @@ #!/bin/bash #---------------------------------------------------- # File: hfsc_shaper.sh -# Version: 0.2 +# Version: 0.3 # Edited: Florian "Bluewind" Pritz <bluewind@xinu.at> # Author: Maciej BliziĆski, http://automatthias.wordpress.com/ #---------------------------------------------------- @@ -21,151 +21,140 @@ # Uplink and downlink speeds # Normally use a bit lower values than your real speed, but # you should experiment a bit -# downlink is unused -#DOWNLINK=75000 -UPLINK=7400 +DOWNLINK=100000 +UPLINK=20500 # Device that connects you to the Internet DEV="extern0" -# Traffic classes: -# 1:2 Interactive (SSH, DNS, ACK, Quake) -# 1:3 Low latency (VoIP) -# 1:4 Browsing (HTTP, HTTPs) -# 1:5 Default -# 1:6 Middle-low priority -# 1:7 Lowest priority - -# Interactive class: SSH Terminal, DNS and gaming (Quake) -INTERACTIVEPORTS="22 23 53 3389 5900 22222 6667 7000 44400 7776 4949 11030 11239 143 445 25765" - -# VoIP telephony -#VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731" -VOIPPORTS="7977 9987" # IP addresses of the VoIP phones, # if none, set VOIPIPS="" -VOIPIPS="" +VOIPIPS=''; +DATAIPS=''; + +source /etc/qos_ports.sh +# Interactive class: SSH, DNS and gaming (csgo) +# INTERACTIVEPORTS="22 18765 1200 3478 4379 4380 " + +# VoIP / gaming +#VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731" +# VOIPPORTS="53 27000:27036 " # WWW, jabber and IRC -BROWSINGPORTS="80 443 8080 993" +# BROWSINGPORTS="80 443 8080 " # Everything unspecified will be here (inbetween Browsing and Data) # FTP, Mail... -DATAPORTS="110 25 21 137:139 4662 4664 " +# DATAPORTS="21 25 110 137:139 143 993 995 4662 4664 27014:27050" # The lowest priority traffic: eDonkey, Bittorrent, etc. #P2PPORTS="6881:6999 36892 8333" -P2PPORTS="" +# P2PPORTS="" ######################################################################## # CONFIGURATION ENDS HERE ######################################################################## -if [ -z "$DEV" ] ; then - echo "$0: device not set, aborting." - exit -1 -fi +function check_device() { + if [ -z "$DEV" ] ; then + echo "$0: stop requires a device, aborting." + exit -1 + fi +} function stop() { + check_device # Reset everything to a known state (cleared) - tc qdisc del dev $DEV root &> /dev/null + tc qdisc del dev $DEV root &> /dev/null tc qdisc del dev $DEV ingress &> /dev/null # Flush and delete tables iptables -t mangle --delete POSTROUTING -o $DEV -j THESHAPER &> /dev/null - iptables -t mangle --flush THESHAPER &> /dev/null + iptables -t mangle --flush THESHAPER &> /dev/null iptables -t mangle --delete-chain THESHAPER &> /dev/null + echo "Shaping removed on $DEV." } function start() { - #if [ -z "$DOWNLINK" ] ; then - #echo "$0: start requires a downlink speed, aborting." - #exit -1 - #fi + check_device + if [ -z "$DOWNLINK" ] ; then + echo "$0: start requires a downlink speed, aborting." + exit -1 + fi if [ -z "$UPLINK" ] ; then echo "$0: start requires an uplink speed, aborting." exit -1 fi + # Traffic classes: + # 1:2 Low latency (VoIP) + # 1:3 Interactive (SSH, DNS, ACK, Quake) + # 1:4 Browsing (HTTP, HTTPs) + # 1:5 Default + # 1:6 Middle-low priority + # 1:7 Lowest priority + # add HFSC root qdisc tc qdisc add dev $DEV root handle 1: hfsc default 5 # add main rate limit class tc class add dev $DEV parent 1: classid 1:1 hfsc \ - sc rate ${UPLINK}kbit ul rate ${UPLINK}kbit + sc rate ${UPLINK}kbit ul rate ${UPLINK}kbit - # Interactive traffic: guarantee full uplink for 50ms, then - # 5/10 of the uplink + # VoIP: guarantee full uplink for 200ms, then 6/10 tc class add dev $DEV parent 1:1 classid 1:2 hfsc \ - sc m1 ${UPLINK}kbit d 50ms m2 $((5*$UPLINK/10))kbit \ - ul rate ${UPLINK}kbit + sc m1 ${UPLINK}kbit d 200ms m2 $((6*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit - # VoIP: guarantee full uplink for 200ms, then 3/10 + # Interactive traffic: guarantee 8/10 uplink for 50ms, then + # 5/10 of the uplink tc class add dev $DEV parent 1:1 classid 1:3 hfsc \ - sc m1 ${UPLINK}kbit d 200ms m2 $((3*$UPLINK/10))kbit \ - ul rate ${UPLINK}kbit + sc m1 $((8*$UPLINK/10))kbit d 50ms m2 $((5*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit - # Browsing: guarantee 3/10 uplink for 200ms, then + # Browsing: guarantee 2/10 uplink for 200ms, then # guarantee 1/10 tc class add dev $DEV parent 1:1 classid 1:4 hfsc \ - sc m1 $((3*$UPLINK/10))kbit d 200ms m2 $((1*$UPLINK/10))kbit \ - ul rate ${UPLINK}kbit + sc m1 $((2*$UPLINK/10))kbit d 200ms m2 $((1*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit # Default traffic: guarantee 1/10 uplink for 100ms, - # then guarantee 3/20 + # then guarantee 1/10 tc class add dev $DEV parent 1:1 classid 1:5 hfsc \ - sc m1 $((1*$UPLINK/10))kbit d 100ms m2 $((3*$UPLINK/20))kbit \ - ul rate ${UPLINK}kbit + sc m1 $((1*$UPLINK/10))kbit d 100ms m2 $((1*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit # Middle-low taffic: don't guarantee anything for the first 5 seconds, # then guarantee 1/10 tc class add dev $DEV parent 1:1 classid 1:6 hfsc \ - sc m1 0 d 5s m2 $((1*$UPLINK/10))kbit \ - ul rate ${UPLINK}kbit + sc m1 0 d 5s m2 $((1*$UPLINK/10))kbit \ + ul rate ${UPLINK}kbit # Lowest taffic: don't guarantee anything for the first 10 seconds, # then guarantee 1/20 - #ls m2 $((1*$UPLINK/200))kbit \ tc class add dev $DEV parent 1:1 classid 1:7 hfsc \ - sc m1 0 d 5s m2 10kbit \ - ul rate $((UPLINK-200))kbit + sc m1 0 d 10s m2 $((1*$UPLINK/40))kbit \ + ul rate ${UPLINK}kbit # add THESHAPER chain to the mangle table in iptables iptables -t mangle --new-chain THESHAPER iptables -t mangle --insert POSTROUTING -o $DEV -j THESHAPER - # Type of service filters (see /etc/iproute2/rt_dsfield) - iptables -t mangle -A THESHAPER \ - -m tos --tos 0x10 \ - -j CLASSIFY --set-class 1:2 - - iptables -t mangle -A THESHAPER \ - -m tos --tos 0x08 \ - -j CLASSIFY --set-class 1:7 - - # To speed up downloads while an upload is going on, put short ACK - # packets in the interactive class - iptables -t mangle -A THESHAPER \ - -p tcp \ - -m tcp --tcp-flags FIN,SYN,RST,ACK ACK \ - -m length --length :64 \ - -j CLASSIFY --set-class 1:2 - - # put large (512+) icmp packets in default category - iptables -t mangle -A THESHAPER \ - -p icmp \ - -m length --length 512: \ - -j CLASSIFY --set-class 1:5 - - # small ICMP in the interactive class - iptables -t mangle -A THESHAPER \ - -p icmp \ - -m length --length :512 \ - -j CLASSIFY --set-class 1:2 - - setclassbyport() { + setclassbyport_udp() { + port=$1 + CLASS=$2 + iptables -t mangle -A THESHAPER -p udp --sport $port -j CLASSIFY --set-class $CLASS + iptables -t mangle -A THESHAPER -p udp --dport $port -j CLASSIFY --set-class $CLASS + } + setclassbyport_tcp() { + port=$1 + CLASS=$2 + iptables -t mangle -A THESHAPER -p tcp --sport $port -j CLASSIFY --set-class $CLASS + iptables -t mangle -A THESHAPER -p tcp --dport $port -j CLASSIFY --set-class $CLASS + } + setclassbyport_both() { port=$1 CLASS=$2 iptables -t mangle -A THESHAPER -p udp --sport $port -j CLASSIFY --set-class $CLASS @@ -174,44 +163,99 @@ function start() { iptables -t mangle -A THESHAPER -p tcp --dport $port -j CLASSIFY --set-class $CLASS } - for port in $INTERACTIVEPORTS; do setclassbyport $port 1:2; done - for port in $VOIPPORTS; do setclassbyport $port 1:3; done - for port in $BROWSINGPORTS; do setclassbyport $port 1:4; done - for port in $DATAPORTS; do setclassbyport $port 1:6; done - for port in $P2PPORTS; do setclassbyport $port 1:7; done + # for port in $VOIPPORTS; do setclassbyport_udp $port 1:2; done + for port in $VOIPPORTS; do setclassbyport_both $port 1:2; done + for port in $INTERACTIVEPORTS; do setclassbyport_both $port 1:3; done + for port in $BROWSINGPORTS; do setclassbyport_both $port 1:4; done + for port in $DATAPORTS; do setclassbyport_tcp $port 1:6; done + # for port in $DATAPORTS; do setclassbyport_both $port 1:6; done + for port in $P2PPORTS; do setclassbyport_both $port 1:7; done + + if [[ -n "$VOIPIPS" ]]; then + echo "enabling ip-based VOIP class 1:2.." + for VOIP in $VOIPIPS; do + echo " [+] $VOIP" + iptables -t mangle -A THESHAPER --src $VOIP -j CLASSIFY --set-class 1:2 + iptables -t mangle -A THESHAPER --dst $VOIP -j CLASSIFY --set-class 1:2 + done + fi - for VOIP in $VOIPIPS; do - iptables -t mangle -A THESHAPER --src $VOIP -j CLASSIFY --set-class 1:3 - iptables -t mangle -A THESHAPER --dst $VOIP -j CLASSIFY --set-class 1:3 - done + if [[ -n "$DATAIPS" ]]; then + echo "enabling ip-based DATA class 1:7.." + for DATAIP in $DATAIPS; do + echo " [+] $DATAIP" + iptables -t mangle -A THESHAPER --src $DATAIP -j CLASSIFY --set-class 1:7 + iptables -t mangle -A THESHAPER --dst $DATAIP -j CLASSIFY --set-class 1:7 + done + fi # put large (1024+) https packets in default category iptables -t mangle -A THESHAPER \ - -p tcp --dport 443 \ - -m length --length 1024: \ - -j CLASSIFY --set-class 1:6 + -p tcp --dport 443 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:5 # put large (1024+) http packets in default category iptables -t mangle -A THESHAPER \ - -p tcp --dport 80 \ - -m length --length 1024: \ - -j CLASSIFY --set-class 1:6 + -p tcp --dport 80 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:5 - # put large (1024+) packets in default category - #iptables -t mangle -A THESHAPER \ - #-p tcp \ - #-m length --length 1024: \ - #-j CLASSIFY --set-class 1:6 + iptables -t mangle -A THESHAPER \ + -p tcp --dport 8080 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:5 + + # Type of service filters (see /etc/iproute2/rt_dsfield) + iptables -t mangle -A THESHAPER \ + -m tos --tos 0x08 \ + -j CLASSIFY --set-class 1:7 + + iptables -t mangle -A THESHAPER \ + -m tos --tos 0x10 \ + -j CLASSIFY --set-class 1:2 # put large (1024+) ssh packets in default category iptables -t mangle -A THESHAPER \ - -p tcp --dport 22 \ - -m length --length 1024: \ - -j CLASSIFY --set-class 1:6 + -p tcp --dport 22 \ + -m length --length 1024: \ + -j CLASSIFY --set-class 1:6 + + # put small ssh packets in interactive category. they should be here, but + # ssh sets ToS fields for non-interactive sessions to 0x08 and multiplexing + # counts as that + iptables -t mangle -A THESHAPER \ + -p tcp --dport 22 \ + -m length --length :1024 \ + -j CLASSIFY --set-class 1:2 + + + + # To speed up downloads while an upload is going on, put short ACK + # packets in the interactive class + iptables -t mangle -A THESHAPER \ + -p tcp \ + -m tcp --tcp-flags FIN,SYN,RST,ACK ACK \ + -m length --length :64 \ + -j CLASSIFY --set-class 1:3 + + + # put large (512+) icmp packets in default category + iptables -t mangle -A THESHAPER \ + -p icmp \ + -m length --length 512: \ + -j CLASSIFY --set-class 1:5 + + # ICMP (ip protocol 1) in the voip class + iptables -t mangle -A THESHAPER \ + -p icmp \ + -m length --length :512 \ + -j CLASSIFY --set-class 1:2 + # put all traffic from user torrent into p2p category (only works for the host this script runs on) #iptables -t mangle -A THESHAPER \ - #--match owner --uid-owner 169 -j CLASSIFY --set-class 1:7 + # --match owner --uid-owner 169 -j CLASSIFY --set-class 1:7 # Try to control the incoming traffic as well. # Set up ingress qdisc @@ -219,23 +263,41 @@ function start() { # Filter everything that is coming in too fast # It's mostly HTTP downloads that keep jamming the downlink, so try to restrict - # them to 95/100 of the downlink. + # them to 90/100 of the downlink. # FIXME: slows down too much - #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ - #u32 match ip src 0.0.0.0/0 \ - #match ip protocol 6 0xff \ - #match ip sport 80 0xffff \ - #police rate $((95*${DOWNLINK}/100))kbit \ - #burst 10k drop flowid :1 - - #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ - #u32 match ip src 0.0.0.0/0 \ - #police rate $((95*${DOWNLINK}/100))kbit \ - #burst $((95*${DOWNLINK}/100*2)) drop flowid :1 + #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ + #u32 match ip src 0.0.0.0/0 \ + #match ip protocol 6 0xff \ + #match ip sport 80 0xffff \ + #police rate $((90*${DOWNLINK}/100))kbit \ + #burst 10k drop flowid :1 + + #tc filter add dev $DEV parent ffff: protocol ip prio 50 \ + #u32 match ip src 0.0.0.0/0 \ + #police rate $((90*${DOWNLINK}/100))kbit \ + #burst $((90*${DOWNLINK}/100*2)) drop flowid :1 + + #=========== downstream stuff =========== + # "${tc_cake}" qdisc del dev $DEV root + # "${tc_cake}" qdisc add dev $DEV root cake bandwidth $UPLINK diffserv8 + + # "${ip_cake}" link del name dev ifb4$DEV + # "${ip_cake}" link add name ifb4$DEV type ifb + # "${tc_cake}" qdisc del dev $DEV ingress + # "${tc_cake}" qdisc add dev $DEV handle ffff: ingress + # "${tc_cake}" qdisc del dev ifb4$DEV root + # "${tc_cake}" qdisc add dev ifb4$DEV root cake bandwidth ${DOWNLINK}kbit besteffort + # if you dont bring the device up your connection will lock up on the next step. + # "${ip_cake}" link set dev ifb4$DEV up + # "${tc_cake}" filter add dev $DEV parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb4$DEV + + echo "Shaping added on $DEV." } function status() { + check_device + echo "[qdisc]" tc -s qdisc show dev $DEV @@ -249,7 +311,7 @@ function status() { echo "" echo "[iptables]" - iptables -n -t mangle -L THESHAPER -v -x + iptables -n -t mangle -L THESHAPER -v -x 2> /dev/null } case "$1" in diff --git a/qos_ports.sh b/qos_ports.sh new file mode 100644 index 0000000..10ace54 --- /dev/null +++ b/qos_ports.sh @@ -0,0 +1,25 @@ +# 1500, 3005, 3101, 28960 = call of duty stuff +# 3478, 4379, 4380 = steam voip / friend network +# 5000:5500 = league of legends game traffic +# 1725, 27000:27031, 27036 = game traffic (cs, tf, ark, portal, ...) +# 7777, 27900, 28900, 28910, 51014, 60576 = borderlands2 (p2p) ports???? +VOIPPORTS="1500 1725 3005 3101 3478 4379 4380 5000:5500 7777 27000:27031 27036 27900 28900 28910 28960 51014 60576" +# 22, 18765 = ssh +# 53 = dns +# 1200 = steam client +# 2099, 5222, 5223 = pvp.net +# 8766 = steam serverbrowser +# 8088 = league of legends spectator mode +# 9987 = teamspeak 3 +# 64738 = mumble +INTERACTIVEPORTS="22 53 1200 2099 5222 5223 8766 8088 9987 18765 64738 143 993 587" +# 80, 443, 591, 593, 8008 8080, 8081, 8243 8280, 8443, 8888, 9080, 9443= http / web ports +BROWSINGPORTS="80 443 591 593 8008 8080 8081 8243 8280 8443 8888 9080 9443" +# 21 = ftp +# 25, 110, 143, 465, 587, 993, 995 = mail +# 8393:8400 = league of legends cdn / downloads +# 8530, 8531 = windows server update services +# 11371 = openpgp http key server +# 27014:27054 = steam cdn / downloads +DATAPORTS="21 25 110 465 995 8393:8400 8530 8531 11371 27014:27054" +P2PPORTS="" |