8fdc296445799747ab9271a7171f9e52e0847736
[firewall-squeep] / shaper.sh
1 #!/bin/sh
2
3 # settings
4 UPLINK=11232 #kbit
5 BURST=15 #k
6 SHAPE_CHAIN='SHAPER-OUT'
7 #
8
9 set -e
10
11 . ./common.sh
12
13 if [ $# -lt 1 ]
14 then
15 echo "Usage: $(basename "$0") external_interface" 1>&2
16 exit 64
17 fi
18
19 EXT_IF="$1"
20 if ! ip link show "${EXT_IF}" >/dev/null 2>&1
21 then
22 echo "'${EXT_IF}' does not seem to be a valid interface"
23 exit 1
24 fi
25
26 function shape_if(){
27 local ext_if="$1" uplink="$2" burst="$3"
28
29 $TC qdisc del dev ${ext_if} root >/dev/null 2>&1 || true
30
31 $TC qdisc add dev ${ext_if} root handle 1: htb default 30
32 $TC class add dev ${ext_if} parent 1: classid 1:1 htb rate ${uplink}kbit burst ${burst}k
33
34 $TC class add dev ${ext_if} parent 1:1 classid 1:10 htb rate ${uplink}kbit burst ${burst}k prio 1
35 $TC class add dev ${ext_if} parent 1:1 classid 1:20 htb rate ${uplink}kbit burst ${burst}k prio 2
36 $TC class add dev ${ext_if} parent 1:1 classid 1:30 htb rate $(expr 9 \* ${uplink} / 10)kbit burst ${burst}k prio 3
37 $TC class add dev ${ext_if} parent 1:1 classid 1:40 htb rate $(expr 5 \* ${uplink} / 10)kbit burst ${burst}k prio 4
38 $TC class add dev ${ext_if} parent 1:1 classid 1:50 htb rate $(expr 5 \* ${uplink} / 10)kbit burst $(expr 2 \* ${burst} / 3)k prio 5
39
40 for x in $(seq 5)
41 do
42 # $TC qdisc add dev ${ext_if} parent 1:${x}0 handle ${x}0: sfq perturb 10
43 $TC qdisc add dev ${ext_if} parent 1:${x}0 handle ${x}0: fq_codel
44 $TC filter add dev ${ext_if} parent 1: prio 0 protocol ip handle ${x} fw flowid 1:${x}0
45 done
46 }
47
48 function shape(){
49 local prio="$1"
50 shift
51 if ! $IPTABLES -t mangle -C "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio} >/dev/null 2>&1
52 then
53 $IPTABLES -t mangle -A "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio}
54 fi
55 }
56
57 shape_if "${EXT_IF}" "${UPLINK}" "${BURST}"
58
59 if ! $IPTABLES -t mangle -L "${SHAPE_CHAIN}" >/dev/null 2>&1
60 then
61 echo "initializing chain '${SHAPE_CHAIN}'"
62 $IPTABLES -t mangle -N "${SHAPE_CHAIN}"
63 fi
64
65 # prioritize small and responsive things
66 shape 1 -p icmp
67 shape 1 -p ipv6-icmp
68 shape 1 -p udp
69 shape 1 -p tcp -m length --length :64
70 shape 1 -p tcp --syn -m length --length 40:68
71 shape 1 -p tcp --tcp-flags ALL ACK -m length --length 40:100
72 shape 1 -p tcp --tcp-flags ALL RST
73 shape 1 -p tcp --tcp-flags ALL ACK,RST
74 shape 1 -p tcp --tcp-flags ALL ACK,FIN
75
76 # favor ssh
77 shape 2 -p tcp --dport 22
78
79 # defavor ftp
80 shape 4 -p tcp --dport 20
81 shape 4 -p tcp --dport 115
82
83 # bulk bittorrent
84 shape 5 -p tcp --dport 8881:8899
85 shape 5 -p tcp --sport 8881:8899
86
87 # default everything else to middle
88 shape 3 -m mark --mark 0
89
90 if ! $IPTABLES -t mangle -C POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}" >/dev/null 2>&1
91 then
92 $IPTABLES -t mangle -I POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}"
93 fi
94