37

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

4
  • We could do with know what OS you are using.
    – Sam Cogan
    Aug 9, 2009 at 21:05
  • debian. Added in an edit.
    – loco41211
    Aug 9, 2009 at 21:21
  • just curious, are you using TorrentFlux?
    – cop1152
    Aug 9, 2009 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 9, 2009 at 22:59

8 Answers 8

15

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.

4
  • could you give an example on setting a limit? Say 100GB incoming and outgoing together?
    – loco41211
    Aug 9, 2009 at 22:17
  • torrent can (and actually is) use other ports so the example is does not really solve the problem.
    – cstamas
    Aug 9, 2009 at 22:36
  • that removes those two options as a solution...
    – loco41211
    Aug 9, 2009 at 22:56
  • cstamas: you can set one port, or multiple ports when using a bittorrent client. see this: dessent.net/btfaq/#ports
    – chris.moos
    Aug 10, 2009 at 10:04
14

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.

2
  • 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 9, 2009 at 22:57
  • This will limit the user on a permanent basis, and not on a timed quota
    – katriel
    Aug 10, 2009 at 21:40
14

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.

1
  • 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, 2009 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).

1
  • 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, 2009 at 9: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

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.

2
  • 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 9, 2009 at 21:47
  • 1
    No, trickle limits speed as in per second.
    – liori
    Aug 9, 2009 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).

1
  • it's a bit overkill as it would drain server resources.. but thank you for the idea!
    – loco41211
    Aug 10, 2009 at 17:43
2

While the question is very old, there is a completely different solution, which allows to limit incoming bandwidth per local user. It is nearly impossible to achieve using other techniques.

First, on OUTPUT using owner match to assign a connection mark:

iptables -t mangle -A OUTPUT -m owner --uid-owner 1000 -j CONNMARK --set-mark 0x1/0x1

Second, as early as on PREROUTING drop everything that has that mark and exceeds a set bandwidth:

iptables -t mangle -A PREROUTING -m connmark --mark 0x1/0x1 -m hashlimit --hashlimit-name merlin --hashlimit-above 1mb/second --hashlimit-burst 10mb -j DROP

hashlimit used this way without type just counts total traffic, so the total incoming bandwidth of the uid 1000 will be limited to 1 MiB/s, but other users will not be constrained.

1
  • This one is very cool solution, especially for proftpd as proxy, because its own traffic shaper module does not work with proxy module.
    – Grrruk
    Jan 2, 2023 at 2:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .