5b55d3fd4b8b3ebbfd78f35c4725262956c8a448
[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 if ! $IP6TABLES -t mangle -C "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio} >/dev/null 2>&1
56 then
57 $IP6TABLES -t mangle -A "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio}
58 fi
59 }
60
61 shape_if "${EXT_IF}" "${UPLINK}" "${BURST}"
62
63 if ! $IPTABLES -t mangle -L "${SHAPE_CHAIN}" >/dev/null 2>&1
64 then
65 echo "initializing ipv4 chain '${SHAPE_CHAIN}'"
66 $IPTABLES -t mangle -N "${SHAPE_CHAIN}"
67 fi
68 if ! $IP6TABLES -t mangle -L "${SHAPE_CHAIN}" >/dev/null 2>&1
69 then
70 echo "initializing ipv6 chain '${SHAPE_CHAIN}'"
71 $iP6TABLES -t mangle -N "${SHAPE_CHAIN}"
72 fi
73
74 # prioritize small and responsive things
75 shape 1 -p icmp
76 shape 1 -p ipv6-icmp
77 shape 1 -p udp
78 shape 1 -p tcp -m length --length :64
79 shape 1 -p tcp --syn -m length --length 40:68
80 shape 1 -p tcp --tcp-flags ALL ACK -m length --length 40:100
81 shape 1 -p tcp --tcp-flags ALL RST
82 shape 1 -p tcp --tcp-flags ALL ACK,RST
83 shape 1 -p tcp --tcp-flags ALL ACK,FIN
84
85 # favor ssh
86 shape 2 -p tcp --dport 22
87
88 # defavor ftp
89 shape 4 -p tcp --dport 20
90 shape 4 -p tcp --dport 115
91
92 # bulk bittorrent
93 shape 5 -p tcp --dport 8881:8899
94 shape 5 -p tcp --sport 8881:8899
95
96 # default everything else to middle
97 shape 3 -m mark --mark 0
98
99 if ! $IPTABLES -t mangle -C POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}" >/dev/null 2>&1
100 then
101 $IPTABLES -t mangle -I POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}"
102 fi
103
104 if ! $IP6TABLES -t mangle -C POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}" >/dev/null 2>&1
105 then
106 $IP6TABLES -t mangle -I POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}"
107 fi
108
109 if [[ ! -e /etc/local.d/shaper.start ]]
110 then
111 echo "add shaper to local rc start!"
112 fi