Limiting the bandwidth of incoming traffic
A backup server was saturating the DSL links of remote offices every time the backups were running. To prevent this, I had to limit the incoming bandwidth of the TCP-connections that were used to back up the remote hosts, but not touch the ones that were used to connect to the servers in the local network. Here’s how to do it.
The limiting must be done by attaching a queuing discipline on the ingress side of the interface the traffic is coming in from. After that you can attach filters that filter traffic from specified hosts or subnets with a given bandwidth.
Step number one is to attach the ingress qdisc:
root@srv:/# tc qdisc add dev eth0 handle ffff: ingress
Step number two is to add one or more filters that police the bandwidth:
root@srv:/# tc filter add dev eth0 parent ffff: protocol ip prio 50 \
u32 match ip src 192.168.123.123 \
police rate 64kbit burst 10k drop flowid :1
root@srv:/# tc filter add dev eth0 parent ffff: protocol ip prio 50 \
u32 match ip src 192.168.124.0/24 \
police rate 128kbit burst 10k drop flowid :1
Step number three is to make your new qdisc and filters to load each time you reboot your server. On Ubuntu, this can be achieved by adding a script to the /etc/network/if-up.d directory. Scripts in that directory will be called whenever a network interface comes up.
Let’s add a file called /etc/network/if-up.d/tc with the following contents:
#!/bin/sh
#
# Network traffic control settings
#
/sbin/tc qdisc add dev eth0 handle ffff: ingress
/sbin/tc filter add dev eth0 parent ffff: protocol ip prio 50 \
u32 match ip src 192.168.123.123 \
police rate 64kbit burst 10k drop flowid :1
/sbin/tc filter add dev eth0 parent ffff: protocol ip prio 50 \
u32 match ip src 192.168.124.0/24 \
police rate 128kbit burst 10k drop flowid :1
Further reading:






August 11th, 2009 at 14:10
moro mikko
minulla olisi kysymys tc:llä liikenteen rajoittamiseen..
onko seuraava mahdollista ?
pystynkö rajoittamaan serverini liikennettä niin että yksittäisen käyttäjän liikenne tiettyyn porttiin rajoitetaan kahteen megaan (outbound)? eli en halua rajoittaa yleistä kaistan käyttöä vain yksittäisten käyttäjien liikennettä.
esim. apache palvelin.. yhdestä ip:stä käyttäjä voi ladata palvelimeltani korkeintaan 2mb nopeudella.
kiitos kovasti
August 17th, 2009 at 2:05
En tiedä onko tuo suoraan mahdollista. On helppoa lisätä sääntö jolla yksittäisen IP:n kaistanleveyttä rajataan kuten yllä on esitetty. Mutta tapauksessasi pitäisi periaatteessa lisätä filter-sääntö jokaiselle saapuvalle pyynnölle (tai oikeastaan siihen liittyvälle IP-osoitteelle).
Homman voisi toteuttaa esim. vahtimalla Apachen lokitiedostoja ja lisäämällä uusi tc filter -sääntö aina kun lokiin ilmestyy ennennäkemätön IP-osoite.
for IP in $(cat /var/log/apache2/access.log | cut -f1 -d’ ‘ | sort | uniq)
do
echo Setting 2048kbit limit for $IP
tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip src $IP police rate 2048kbit burst 10k drop flowid :1
done
Tuo siis käy lokin kertaalleen läpi ja tekee säännön jokaiselle IP-osoitteelle joka sieltä löytyy. Sitä pitää ajella jatkuvasti, ja muistaa tyhjentää tc-säännöt aina välissä. “tail -f” -komennolla pystyisi ehkä rakentelemaan jatkuvasti toimivan systeemin mutta sen täytyy jotenkin pitää kirjaa IP-osoitteista.
Sitten hommaan voisi löytyä jotain valmiita Apache-moduuleja. Kannattaa tsekata ainakin mod_qos (http://mod-qos.sourceforge.net/)