Navigace

IPTables - QOS

#!/sbin/runscript

# NOTE!! - This script assumes your kernel has been patched with the
# appropriate HTB queue and IMQ patches available here:
# (subnote: future kernels may not require patching)
#
# http://luxik.cdi.cz/~devik/qos/htb/
# http://luxik.cdi.cz/~patrick/imq/
#

opts="start stop status"

depend() {
need net
}

#
#---------------------------------------------
#---------------------------------------------
#

DEV=eth0
RATEUP=3000

# 
# End Configuration Options
#

status() {
echo "[qdisc]"
tc -s qdisc show dev $DEV
echo "[class]"
tc -s class show dev $DEV
echo "[filter]"
tc -s filter show dev $DEV
echo "[iptables]"
# iptables -t mangle -L MYSHAPER-OUT -vn -x 2> /dev/null
iptables -t mangle -L MYSHAPER-OUT -vn -x 2> /dev/null | sed -e 's/\(.*\)MARK .*/\1/'
eend $?
}

stop() {

# Reset everything to a known state (cleared)
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
iptables -t mangle -D POSTROUTING -o $DEV -j MYSHAPER-OUT 2> /dev/null > /dev/n$
iptables -t mangle -F MYSHAPER-OUT 2> /dev/null > /dev/null
iptables -t mangle -X MYSHAPER-OUT 2> /dev/null > /dev/null

echo "Shaping removed on $DEV."
eend $?
}

start() {

###########################################################
#
# Outbound Shaping (limits total bandwidth to RATEUP)

# Reset everything to a known state (cleared)
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
iptables -t mangle -D POSTROUTING -o $DEV -j MYSHAPER-OUT 2> /dev/null > /dev/n$
iptables -t mangle -F MYSHAPER-OUT 2> /dev/null > /dev/null
iptables -t mangle -X MYSHAPER-OUT 2> /dev/null > /dev/null

# set queue size to give latency of about 2 seconds on low-prio packets
#ip link set dev $DEV qlen 40
ip link set dev $DEV qlen 30

# changes mtu on the outbound device. Lowering the mtu will result
# in lower latency but will also cause slightly lower throughput due 
# to IP and TCP protocol overhead.
ip link set dev $DEV mtu 1500

# add HTB root qdisc
tc qdisc add dev $DEV root handle 1: htb default 27

# add main rate limit classes
tc class add dev $DEV parent 1: classid 1:1 htb rate ${RATEUP}kbit

# add leaf classes - We grant each class at LEAST it's "fair share" of bandwidth.
# this way no class will ever be starved by another class. Each
# class is also permitted to consume all of the available bandwidth
# if no other classes are in use.
tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[$RATEUP/32]kbit ceil $[${RATEUP}-100]kbit prio 0
tc class add dev $DEV parent 1:1 classid 1:21 htb rate $[$RATEUP/24]kbit ceil $[${RATEUP}-100]kbit prio 1
tc class add dev $DEV parent 1:1 classid 1:22 htb rate $[$RATEUP/12]kbit ceil $[${RATEUP}-100]kbit prio 2
tc class add dev $DEV parent 1:1 classid 1:23 htb rate $[$RATEUP/24]kbit ceil $[${RATEUP}-100]kbit prio 3
tc class add dev $DEV parent 1:1 classid 1:24 htb rate $[$RATEUP/4]kbit ceil $[${RATEUP}-100]kbit prio 4
tc class add dev $DEV parent 1:1 classid 1:25 htb rate $[$RATEUP/12]kbit ceil $[${RATEUP}-100]kbit prio 5
tc class add dev $DEV parent 1:1 classid 1:26 htb rate $[$RATEUP/3]kbit ceil $[${RATEUP}-100]kbit prio 6
tc class add dev $DEV parent 1:1 classid 1:27 htb rate $[$RATEUP/6]kbit ceil $[${RATEUP}-100]kbit prio 7

# attach qdisc to leaf classes - here we at SFQ to each priority class. SFQ insures that
# within each class connections will be treated (almost) fairly.

#tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
#tc qdisc add dev $DEV parent 1:21 handle 21: sfq perturb 10
#tc qdisc add dev $DEV parent 1:22 handle 22: sfq perturb 10
#tc qdisc add dev $DEV parent 1:23 handle 23: sfq perturb 10
#tc qdisc add dev $DEV parent 1:24 handle 24: sfq perturb 10
#tc qdisc add dev $DEV parent 1:25 handle 25: sfq perturb 10
#tc qdisc add dev $DEV parent 1:26 handle 26: sfq perturb 10
#tc qdisc add dev $DEV parent 1:27 handle 27: sfq perturb 10

# filter traffic into classes by fwmark - here we direct traffic into priority class according to
# the fwmark set on the packet (we set fwmark with iptables
# later). Note that above we've set the default priority
# class to 1:26 so unmarked packets (or packets marked with
# unfamiliar IDs) will be defaulted to the lowest priority
# class.
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
tc filter add dev $DEV parent 1:0 prio 1 protocol ip handle 21 fw flowid 1:21
tc filter add dev $DEV parent 1:0 prio 2 protocol ip handle 22 fw flowid 1:22
tc filter add dev $DEV parent 1:0 prio 3 protocol ip handle 23 fw flowid 1:23
tc filter add dev $DEV parent 1:0 prio 4 protocol ip handle 24 fw flowid 1:24
tc filter add dev $DEV parent 1:0 prio 5 protocol ip handle 25 fw flowid 1:25
tc filter add dev $DEV parent 1:0 prio 6 protocol ip handle 26 fw flowid 1:26
tc filter add dev $DEV parent 1:0 prio 7 protocol ip handle 27 fw flowid 1:27

# add MYSHAPER-OUT chain to the mangle table in iptables - this sets up the table we'll use
# to filter and mark packets.
iptables -t mangle -N MYSHAPER-OUT
iptables -t mangle -I POSTROUTING -o $DEV -j MYSHAPER-OUT

# add fwmark entries to classify different types of traffic - Set fwmark from 20-27 according to
# desired class. 20 is highest prio.
iptables -t mangle -A MYSHAPER-OUT -p icmp -j MARK --set-mark 20 # ICMP (ping) - high prio, impress friends
iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length :64 -j MARK --set-mark 21 # small packets (probably just ACKs)
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 53 -j MARK --set-mark 21
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 53 -j MARK --set-mark 21
iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 53 -j MARK --set-mark 21
iptables -t mangle -A MYSHAPER-OUT -p udp --sport 53 -j MARK --set-mark 21
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport ssh -j MARK --set-mark 22 # secure shell
iptables -t mangle -A MYSHAPER-OUT -p tcp --sport ssh -j MARK --set-mark 22 # secure shell
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport telnet -j MARK --set-mark 22 # unsecure shell
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5190 -j MARK --set-mark 23 # ICQ
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5222 -j MARK --set-mark 23 # JABBER
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5223 -j MARK --set-mark 23 # JABBER
# RDP and VPN-clients
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 3389 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 4090 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 4112 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 500 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 786 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 1194 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --sport 1194 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 4090 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 4112 -j MARK --set-mark 24
iptables -t mangle -A MYSHAPER-OUT -p udp --dport 4500 -j MARK --set-mark 24
#
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 25 -j MARK --set-mark 25 # SMTP
iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 25 -j MARK --set-mark 25 # SMTP
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 80 -j MARK --set-mark 26 # HTTP
iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 80 -j MARK --set-mark 26 # HTTP
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 8080 -j MARK --set-mark 26 # HTTP
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 443 -j MARK --set-mark 26 # HTTPs
iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 443 -j MARK --set-mark 26 # HTTPs
iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 21 -j MARK --set-mark 27 # FTP

iptables -t mangle -A MYSHAPER-OUT -m mark --mark 0 -j MARK --set-mark 27 # redundant- mark any unmarked packets as 26 (low prio)

# ----------------------------------

#iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 0:1024 -j MARK --set-mark 23 # Default for low port traffic 
#iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 0:1024 -j MARK --set-mark 23 # "" 
#iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 20 -j MARK --set-mark 26 # ftp-data port, low prio
#iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5190 -j MARK --set-mark 23 # aol instant messenger

#iptables -t mangle -A MYSHAPER-OUT -p udp -j MARK --set-mark 21 # DNS name resolution (small packets)
#iptables -t mangle -A MYSHAPER-OUT -p tcp --dport telnet -j MARK --set-mark 22 # telnet (ew...)
#iptables -t mangle -A MYSHAPER-OUT -p tcp --sport telnet -j MARK --set-mark 22 # telnet (ew...)
#iptables -t mangle -A MYSHAPER-OUT -p ipv6-crypt -j MARK --set-mark 24 # IPSec - we don't know what the payload is though...
#iptables -t mangle -A MYSHAPER-OUT -p tcp --sport http -j MARK --set-mark 25 # Local web server

# Done with outbound shaping
#
####################################################

eend $?
}