how can I limit per user bandwidth?

To summarise: I have a dedicated server with a few friends running a torrent client with web gui. Each user is running a client under their username on the server so downloads go in their user dir, and only they have access to their own files etc.

How can I monitor and limit the bandwidth per month on a per user basis?

I was thinking there must be a way using iptables maybe. And by monitoring the bandwidth used by all processes of user X. And if they have used more then their monthly allowed bandwidth of Y GB, they get a message saying that and networking gets blocked for their torrent client, or the client gets killed completely. I also thought about squid, but seeing as it would be using multiple torrent clients this could use a lot of server resources...

I am using debian lenny.

I'm not sure how to do this...

would this be possible at all? I am grateful for even just partial solutions to this...


Solution 1:

Just to add on the above question.

You could use iptables with user matching to color the packets like so:

iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner someuser -j MARK --set-mark 100

And then use 'tc' to limit on a per user basis.

Solution 2:

You could use the 'tc' traffic shaping command.

Give each of your friends a different port to use for BitTorrent. Mark the TCP packets with iptables for each port.

iptables -t mangle -A FORWARD -p tcp --sport 6881 -j MARK --set-mark 100
iptables -t mangle -A FORWARD -p tcp --dport 6881 -j MARK --set-mark 100

Then use the tc command to set the maximum bandwidth and rate for each user.

At the end of the month you can delete and add the 'tc' commands to reset the counts.

You can monitor usage for each user by:

tc filter show dev ethX

If you are using Debian install shorewall, it makes it really easy to do traffic shaping without messing with iptables. You just edit tcdevices,tcclasses, and tcrules in the /etc/shorewall directory. More info here: http://www.shorewall.net/traffic_shaping.htm

As the other person suggested, marking packets by username is probably better than by port, that way the ports can be changed without updating iptables.

Solution 3:

You could try using the --quota option in iptables, which allows you to set a transfer limit in bytes. Since you are running multiple torrent clients, each under a different user name, you could combine that with the --uid-owner option, as katriel suggested.

In this way you could enforce a transfer limit per time period (day/week/month/etc) without having to limit your users' download speed.

In order to make the packet counters persistent, you'd have to save them periodically (for example, through a cron job), so that you can restore them in case that you need to reboot the server or flush the firewall rules.

Solution 4:

Depending on how much monthly traffic you want to allow for each user per month, you could set a bandwidth limit accordingly, using some of the tools that were suggested by the other users.

For example, let's say that you want to set a maximum download limit of 250 GB/month. Now, if you divide that by the number of hours in a month (~730), and then by 3600, you would get the maximum download rate, which in this example would be arount 100 KB/s.

Then, if you set a maximum DL rate of 100 KB/s, you'd be automatically enforcing your 250 GB/month download limit (assuming of course that your traffic shaper is working properly). If your users cannot download faster than 100 KB/s, then they won't be able to download more than 250 GB/month.

In order to limit the download rate you could use tc or some of the other tools that have been mentioned. If you don't want to deal directly with tc, you could use cbq.init, which is pretty simple to set up. This script was present in Debian Etch as the shaper package, but it seems to have been removed after that. Anyway, it's just a simple script that you can download from SourceForge.

Of course this approach might not be useful in your case (for example, if you wanted that your users could download at the maximum available speed but still enforce your montly limit, my suggestion wouldn't work).

Solution 5:

i know this is an old post but even I stumbled upon it looking for answers today and I eventually pieced together something that works perfectly for me. I have a 25Mbs downlink and 2.5Mbs uplink and there are 4 people and 5 servers sharing this link. with servers uplink bandwith is critical but downlink is usefull with 4 people so no one hogs it all.

I'm running centos 6.3 as a router but these commands should work on any linux. eth0 is my uplink to provider eth1 is my lan via 24 port switch and wifi access point I limit downloads to 5 of the 25 Mbs (roughly 500KB/sec) I limit uploads to 200Kbit (roughly 25KB/sec)

tc qdisc add dev eth0 root handle 1:0 htb default 99
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 100Mbit ceil 100Mbit
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 200Kbit ceil 200Kbit prio 2
tc qdisc add dev eth0 parent 1:11 handle 10: sfq perturb 10

tc qdisc add dev eth1 root handle 2:0 htb default 99
tc class add dev eth1 parent 2:0 classid 2:1 htb rate 100Mbit ceil 100Mbit
tc class add dev eth1 parent 2:1 classid 2:11 htb rate 5Mbit ceil 5Mbit prio 2
tc qdisc add dev eth1 parent 2:11 handle 20: sfq perturb 10

then to limit users you use 2 iptables lines per user

to limit uploads:

iptables -t mangle -A POSTROUTING -o eth0 -p tcp -s 192.168.0.100 -j CLASSIFY --set-class 1:11

to limit downloads

iptables -t mangle -A POSTROUTING -o eth1 -p tcp -d 192.168.0.100 -j CLASSIFY --set-class 2:11

just change your ip address and eth ports to match who you want to limit