|
############################################################
# router shaping script written by Phill Brown
# requires in the following order.
# an interface, ie eth0, wifi0
# a maximum speed in kilobits, for maximum effeciency, it is
# suggested that the speed is at least 5-10% lower than real
# life speeds
# and finally a unique id, for shaping purposes. i might
# remove this necessity one day, but for now, it is required
############################################################
make sure the script is executable
chmod +x /script/location/router_shaper.sh
or
chmod 755 /script/location/router_shaper.sh
then call the script
/script/location/router_shaper.sh ppp0 196 1
/script/location/router_shaper.sh eth0 1102 2
any suggestions for improvement or fixes please let me know.
#!/bin/sh
############################################################
# router shaping script written by Phill Brown
# requires in the following order.
# an interface, ie eth0, wifi0
# a maximum speed in kilobits, for maximum effeciency, it is
# suggested that the speed is at least 5% lower than real
# life speeds
# and finally a unique id, for shaping purposes. i might
# remove this necessity one day, but for now, it is required
############################################################
IFACE=${1}
SPEED=${2}
PARENTID=${3}
# check that we have an interface
if [ "$IFACE" = "" ]; then
echo "an interface is required."
echo ": script.sh [interface] [max speed in Kb/s] [id(a unique number)]"
exit
fi
# chek that we have a speed
if [ "$SPEED" = "" ]; then
echo "a maximum speed is required."
echo ": script.sh [interface] [speed in Kb/s] [id(a unique number)]"
exit
fi
# check that we have a parent id for our shaping class
if [ "$PARENTID" = "" ]; then
echo "an id is required, it must be unique."
echo ": script.sh [interface] [speed in Kb/s] [id(a unique number)]"
exit
fi
# check that the interface exists
if grep $IFACE: /proc/net/dev 1> /dev/null ; then # interface exists
echo "$IFACE exists, using a max speed of ${SPEED}Kb/s"
else
exit
fi
iptables -t mangle -D POSTROUTING -o $IFACE -j ${IFACE}_SHAPING 2>/dev/null
iptables -t mangle -F ${IFACE}_SHAPING 2>/dev/null
iptables -t mangle -X ${IFACE}_SHAPING 2>/dev/null
iptables -t mangle -N ${IFACE}_SHAPING
iptables -t mangle -F ${IFACE}_PRIO_REALTIME 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_REALTIME 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_PRIO_REALTIME -j MARK --set-mark ${PARENTID}20
iptables -t mangle -A ${IFACE}_PRIO_REALTIME -j TOS --set-tos Minimize-Delay
iptables -t mangle -A ${IFACE}_PRIO_REALTIME -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_HIGH 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_HIGH 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_PRIO_HIGH -j MARK --set-mark ${PARENTID}21
iptables -t mangle -A ${IFACE}_PRIO_HIGH -j TOS --set-tos Minimize-Delay
iptables -t mangle -A ${IFACE}_PRIO_HIGH -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_NORMAL 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_NORMAL 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_NORMAL
iptables -t mangle -A ${IFACE}_PRIO_NORMAL -j MARK --set-mark ${PARENTID}22
iptables -t mangle -A ${IFACE}_PRIO_NORMAL -j TOS --set-tos Normal-Service
iptables -t mangle -A ${IFACE}_PRIO_NORMAL -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_LOW 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_LOW 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_LOW
iptables -t mangle -A ${IFACE}_PRIO_LOW -j MARK --set-mark ${PARENTID}23
iptables -t mangle -A ${IFACE}_PRIO_LOW -j TOS --set-tos Maximize-Throughput
iptables -t mangle -A ${IFACE}_PRIO_LOW -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_VERYLOW 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_VERYLOW 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_VERYLOW
iptables -t mangle -A ${IFACE}_PRIO_VERYLOW -j MARK --set-mark ${PARENTID}24
iptables -t mangle -A ${IFACE}_PRIO_VERYLOW -j TOS --set-tos Minimize-Cost
iptables -t mangle -A ${IFACE}_PRIO_VERYLOW -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_HALFSHAPED 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_HALFSHAPED 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_HALFSHAPED
iptables -t mangle -A ${IFACE}_PRIO_HALFSHAPED -j MARK --set-mark ${PARENTID}50
iptables -t mangle -A ${IFACE}_PRIO_HALFSHAPED -j TOS --set-tos Minimize-Cost
iptables -t mangle -A ${IFACE}_PRIO_HALFSHAPED -j ACCEPT
iptables -t mangle -F ${IFACE}_PRIO_DIALUP 2>/dev/null
iptables -t mangle -X ${IFACE}_PRIO_DIALUP 2>/dev/null
iptables -t mangle -N ${IFACE}_PRIO_DIALUP
iptables -t mangle -A ${IFACE}_PRIO_DIALUP -j MARK --set-mark ${PARENTID}60
iptables -t mangle -A ${IFACE}_PRIO_DIALUP -j TOS --set-tos Minimize-Cost
iptables -t mangle -A ${IFACE}_PRIO_DIALUP -j ACCEPT
iptables -t mangle -F ${IFACE}_DEFAULT 2>/dev/null
iptables -t mangle -X ${IFACE}_DEFAULT 2>/dev/null
iptables -t mangle -N ${IFACE}_DEFAULT
iptables -t mangle -A ${IFACE}_DEFAULT -j MARK --set-mark ${PARENTID}80
iptables -t mangle -A ${IFACE}_DEFAULT -j TOS --set-tos Minimize-Cost
iptables -t mangle -A ${IFACE}_DEFAULT -j ACCEPT
# add our entry into our new tables
iptables -t mangle -A POSTROUTING -o $IFACE -j ${IFACE}_SHAPING
############################################################
# set our rate
MINIMUM=$[SPEED/6]
DEFAULT=$[MINIMUM*4]
DIALUP=32
############################################################
# delete old qdisc
tc qdisc del dev $IFACE ingress 2> /dev/null > /dev/null
tc qdisc del dev $IFACE root 2> /dev/null > /dev/null
############################################################
# add HTB root qdisc
# the following line was commented and adjusted so as not to automatically capture
# all packets so that a custom rule could be put in effect from iptables to bypass the
# shaping when required for certain networks.
#tc qdisc add dev $IFACE root handle $PARENTID: htb default 80
tc qdisc add dev $IFACE root handle $PARENTID: htb
############################################################
# add main rate limit classes
tc class add dev $IFACE parent $PARENTID: classid $PARENTID:1 htb rate ${SPEED}Kbit
############################################################
# add leaf classes. Here 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 $IFACE parent $PARENTID:1 classid $PARENTID:20 htb rate ${MINIMUM}Kbit ceil ${SPEED}Kbit prio 0
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:21 htb rate ${MINIMUM}Kbit ceil ${SPEED}Kbit prio 1
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:22 htb rate ${MINIMUM}Kbit ceil ${SPEED}Kbit prio 2
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:23 htb rate ${MINIMUM}kbit ceil ${SPEED}Kbit prio 3
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:24 htb rate ${MINIMUM}kbit ceil ${SPEED}kbit prio 4
# the following classes are SHAPING classes, anything passed to these classes will be SHAPED to a slower speed
# this class is shaped to half speed
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:50 htb rate $[MINIMUM/2]kbit ceil $[SPEED/2]kbit prio 5
# this is shaped to dial up speed
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:60 htb rate ${DIALUP}kbit ceil ${DIALUP}kbit prio 6
# this is the DEFAULT class, anything that is not specified will end up here
tc class add dev $IFACE parent $PARENTID:1 classid $PARENTID:80 htb rate $[MINIMUM/2]kbit ceil $[DEFAULT]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 $IFACE parent $PARENTID:20 handle 20: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:21 handle 21: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:22 handle 22: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:23 handle 23: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:24 handle 24: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:50 handle 50: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:60 handle 60: sfq perturb 10
tc qdisc add dev $IFACE parent $PARENTID:80 handle 80: 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 $PARENTID:80 so unmarked packets
# (or packets marked with unfamiliar IDs) will be defaulted to the lowest priority class.
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}20 fw flowid $PARENTID:20
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}21 fw flowid $PARENTID:21
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}22 fw flowid $PARENTID:22
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}23 fw flowid $PARENTID:23
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}24 fw flowid $PARENTID:24
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}50 fw flowid $PARENTID:50
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}60 fw flowid $PARENTID:60
tc filter add dev $IFACE parent $PARENTID:0 prio 0 protocol ip handle ${PARENTID}80 fw flowid $PARENTID:80
###############################################################################
# our shaping rules here.
# i might place this into a seperate file one day.
#
# want ssh nice and fast
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 22 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 22 -j ${IFACE}_PRIO_HIGH
# ftp command port nice and fast
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 21 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 21 -j ${IFACE}_PRIO_HIGH
# ftp-data port, low prio
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 20 -j ${IFACE}_PRIO_VERYLOW
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 20 -j ${IFACE}_PRIO_VERYLOW
# smtp
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 25 -j ${IFACE}_PRIO_NORMAL
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 25 -j ${IFACE}_PRIO_NORMAL
# dns nice & fast
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 53 -j ${IFACE}_PRIO_REALTIME
# http
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 80 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 80 -j ${IFACE}_PRIO_HIGH
# http proxy
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 800 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 800 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 8080 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 8080 -j ${IFACE}_PRIO_HIGH
# pop
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 110 -j ${IFACE}_PRIO_VERYLOW
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 110 -j ${IFACE}_PRIO_VERYLOW
# https
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 443 -j ${IFACE}_PRIO_NORMAL
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 443 -j ${IFACE}_PRIO_NORMAL
# cpanel
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 2083 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 2083 -j ${IFACE}_PRIO_HIGH
# give irc full
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 6667 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 6667 -j ${IFACE}_PRIO_REALTIME
# give remote desktop app full
# remote desktop
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 3389 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 3389 -j ${IFACE}_PRIO_REALTIME
# radmin
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 4899 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 4899 -j ${IFACE}_PRIO_REALTIME
# ultra VNC
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 5900 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 5900 -j ${IFACE}_PRIO_REALTIME
# VNC http
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 5901 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 5901 -j ${IFACE}_PRIO_REALTIME
# microsoft server 2003 vpn
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 1723 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 1723 -j ${IFACE}_PRIO_HIGH
# msn (DROP this to block msn messenger)
#iptables -t nat -A PREROUTING -d 207.46.0.0/16 -j DROP
iptables -t mangle -A ${IFACE}_SHAPING -d 207.46.0.0/16 -j ${IFACE}_PRIO_LOW
# Games
# Battlfield DC
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 14567 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 14567 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 14567 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 14567 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 14690 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 14690 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 22000 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 22000 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 27900 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 27900 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 28900 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 28900 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 23000:23009 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 23000:23009 -j ${IFACE}_PRIO_HIGH
# teamspeak voip *client, web interface, tcp query
iptables -t mangle -A ${IFACE}_SHAPING -p udp --dport 8767 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p udp --sport 8767 -j ${IFACE}_PRIO_REALTIME
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 14534 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 14534 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 51234 -j ${IFACE}_PRIO_HIGH
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 51234 -j ${IFACE}_PRIO_HIGH
###############################################################################
# do not adjust below this line
# packets marked with Maximize-Throughput or Minimize-Cost
#iptables -t mangle -A REDSHAPING -m tos --tos Maximize-Throughput -j RED_PRIO_LOW
#iptables -t mangle -A REDSHAPING -m tos --tos Minimize-Cost -j RED_PRIO_LOW
# some defaults
# Default for low port traffic
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --dport 0:1024 -j ${IFACE}_PRIO_NORMAL
iptables -t mangle -A ${IFACE}_SHAPING -p tcp --sport 0:1024 -j ${IFACE}_PRIO_NORMAL
# icmp (ping etc)
iptables -t mangle -A ${IFACE}_SHAPING -p icmp -j ${IFACE}_PRIO_REALTIME
# small packets (probably just ACKs, voip)
iptables -t mangle -A ${IFACE}_SHAPING -p tcp -m length --length :64 -j ${IFACE}_PRIO_REALTIME
# dns games streaming etc
iptables -t mangle -A ${IFACE}_SHAPING -p udp -j ${IFACE}_PRIO_HIGH
# if packets are not marked or make it here then mark them as default traffic
iptables -t mangle -A ${IFACE}_SHAPING -m mark --mark 0 -j ${IFACE}_DEFAULT
|