From Tim's website
Jump to: navigation, search

Bandwidth limiting

I have several machines sharing an internet connection, and so I've been looking for a way to control the bandwidth consumed by an individual machine. Outgoing traffic can be controlled effectively with tc and iptables, but incoming traffic is harder to control. If you can do this on a gateway machine or router then you can control the flow of traffic in both directions with this method.

Limiting outgoing bandwidth

The following commands were taken from a script by Gordon Henderson, which was loosely based on a script written by Shane.

Flush the mangle table and delete queuing disciplines

I put this script in /etc/networking/if-pre-up.d/ on my Debian box:

#!/bin/sh
# This traffic shaping script is run before the interfaces are brought up.
# It flushes the mangle table and deletes any queuing disciplines.

# Flush existing rules from mangle table
iptables -t mangle --flush

# Delete all queuing disciplines
tc qdisc del dev eth0 root

Add rules to the mangle table and create queuing disciplines

I put this script in /etc/networking/if-up.d/ on my Debian box:

#!/bin/sh
# This traffic shaping script is run after the interfaces have been brought up.
# Another script is run in if-pre-up to flush the mangle table and delete
# queuing disciplines. This script then creates the qdisc and classes, and
# adds the mangle table rules to classify traffic.

# Create the default Hierarchy Token Bucket queuing discipline
tc qdisc add dev eth0 root handle 1: htb default 99

# Create the top level class for all traffic
tc class add dev eth0 parent 1: classid 1:1 htb rate 7000kbit ceil 7000kbit

# Create a high priority class for small SSH packets and ACKs (with Stochastic Fairness Queuing)
tc class add dev eth0 parent 1: classid 1:2 htb rate 7000kbit ceil 7000kbit prio 0
tc qdisc add dev eth0 parent 1:2 handle 2: sfq perturb 10

# Create a normal priority class for everything else (with Stochastic Fairness Queuing)
tc class add dev eth0 parent 1: classid 1:3 htb rate 4000kbit ceil 6000kbit prio 2
tc qdisc add dev eth0 parent 1:3 handle 3: sfq perturb 10

# Add an iptables rule to classify all traffic as normal priority initially
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:3

# Add iptables rules to re-classify high priority small SSH packets and ACKs
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:2 -p icmp
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:2 -p tcp -m length --length 40:100 --tcp-flags ALL ACK -m state --state ESTABLISHED
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:2 -p tcp -m length --length 40:68  --dport 22