Throttling Linux Network Bandwidth by IP Address and Time of Day
Just now I found a fantastic and low-friction way to throttle network
bandwidth on a Linux server — by use of the tc
command. This command comes as
part of any Linux or BSD installation, which is nice because I like working
with standard utilities whenever possible.
It’s a three-step process.
First, create a class based queue on your interface (in my case eth0
). This
command tells the kernel to assume a 100mbit interface speed to base
calculations on.
tc qdisc add dev eth0 root handle 1: cbq avpkt 1000 bandwidth 100mbit
Then create a 512kbit class with some reasonable defaults.
tc class add dev eth0 parent 1: classid 1:1 cbq rate 512kbit allot 1500 prio 5 bounded isolated
Finally, tell which traffic should go to the shaped class. Only traffic matched by this rule gets shaped. In our case, we define an IP address.
tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 195.96.97.98 flowid 1:1
That’s it. You can effectively limit the bandwidth that goes to a specific IP
address. Add more filters if you like. If you made an unrecoverable error, just
run tc qdisc del dev eth0 root
to delete everything and start with a clean
slate.
For extra awesomeness, you could set up a cronjob that sets different limits for different times of day, for example. The following is an example I use on a clients’ Debian-based server with a severely contrained internet connection to rate limit the bandwidth for offsite backups during regular work hours. Because sometimes a backup has to run for several days on that connection.
30 8 * * * /sbin/tc class change dev eth0 classid 1:1 cbq rate 0.5mbit allot 1500 prio 5 bounded isolated
30 18 * * * /sbin/tc class change dev eth0 classid 1:1 cbq rate 4mbit allot 1500 prio 5 bounded isolated
This starts limiting traffic to the backup server starting at 8.30 am and restores full bandwidth at 6.30 pm.