34

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...

Mike Pennington
  • 8,266
  • 9
  • 41
  • 86
loco41211
  • 349
  • 1
  • 4
  • 6
  • We could do with know what OS you are using. – Sam Cogan Aug 09 '09 at 21:05
  • debian. Added in an edit. – loco41211 Aug 09 '09 at 21:21
  • just curious, are you using TorrentFlux? – cop1152 Aug 09 '09 at 22:55
  • it's one of the things I am trying. At the moment we are looking at anything to possibly use for a seedbox with disk space limiting (which we have a solution for) and bandwidth limiting which we are stuck on.... and some of my friends use around 1TB a month while others only a few Mbs. Would really like to limit this per user equally. – loco41211 Aug 09 '09 at 22:59

7 Answers7

13

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.

chris.moos
  • 296
  • 1
  • 3
13

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.

katriel
  • 4,407
  • 22
  • 20
  • 1
    Could you give an example on how to use tc to set a limit of say 100GB for username blablaX? And an example of the code that should be used to reset the limit after one month? Thank you – loco41211 Aug 09 '09 at 22:57
  • This will limit the user on a permanent basis, and not on a timed quota – katriel Aug 10 '09 at 21:40
13

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.

alemartini
  • 1,023
  • 1
  • 6
  • 14
  • that sounds like it would work. So with the help of iptables I can mark all traffic that comes in and goes out for a set user. And I can limit it for a set time period. I still can't work out how the whole set up will be though. So is the exact command I could use to mark the incoming and outgoing traffic: "iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner someuser -j MARK --set-mark 100" ? Or how would I do it? What for example would the command be to mark username bob with id 56 with a monthly limit of 100GB? I guess a monthly cron job would reset the traffic counter? – loco41211 Aug 10 '09 at 14:20
8

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).

mfriedman
  • 1,959
  • 1
  • 13
  • 14
  • The main reason we use a seedbox instead just torrents on our pcs because it is a lot faster, so sadly this doesn't solve the problem... Thanks anyway – loco41211 Aug 10 '09 at 09:48
7

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

BrierMay
  • 249
  • 1
  • 3
  • 8
3

For completeness, there is a userspace daemon called trickle. It can be used to limit bandwidth of a single process. Usage is very simple: f.e. to limit bandwidth used by aptitude, you could write: trickle -d 10 aptitude install wesnoth However because it works using LD_PRELOAD, it could be easily overridden by an user with shell access.

liori
  • 737
  • 3
  • 14
  • None of the users besides myself have shell access. Also, with bandwidth limiting I mean per month, or a set period of time. Would that be possible? – loco41211 Aug 09 '09 at 21:47
  • 1
    No, trickle limits speed as in per second. – liori Aug 09 '09 at 23:28
2

Take a look at the useripacct kernel patch (this actually has quite a long history). In the docs for the old version it appears to also provide quota enforcement as well as monitoring, and it's also possible to provide your own policy scripts.

Given the useripacct creators had to resort to a kernel patch to obtain the behaviour you want, it seems unlikely there's a simpler method available by default. The only alternatives would appear to be bandwidth limiting (by something like tc or trickle) as suggested by most of the other answers here (but not actually what you're looking for), or creating a VM for each user (using lightweight OS virtualization by something like OpenVZ) and accounting traffic per VM (which is fairly easy assessed by something like vnstat). That seems like overkill though (suddenly you have a bunch of VMs to administer instead of one system).

timday
  • 856
  • 1
  • 10
  • 24