Controlling bandwidth usage with mod_cband or mod_bw on Apache2

Today's major problem was bandwidth. On one of my servers, there is a vhost that is beginning to consume a good chunk of bandwidth on a daily basis. I have daily reports sent to me showing the monthly total of bandwidth used on a per vhost basis. This is handy to see if any of my vhosts are hogging things up. I'll write another entry about that tool in a separate blog.

Either way, I have a site that normally consumes 3-4GBs of bandwidth a month, but looking at my report, I see that they've consumed 8.79GBs of bandwidth.. and it's only the 5th day of February!!!!

They server up high quality MP3s and they were just listed on a popular blog, that is why there is a large spike of bandwidth. To get a handle on this, I thought it would be good to try some of the bandwidth throttling/quota mods out there for Apache2. The two I thought I'd try are mod_cband and mod_bw.

* www-apache/mod_cband
     Available versions:  0.9.7.2 ~0.9.7.5
     Homepage:            http://cband.linux.pl/
     Description:         Apache2 bandwidth quota and throttling module.

http://tikiwiki.org/HowToApacheModCbandRateLimiting
http://cband.linux.pl/

* net-www/mod_bw
     Available versions:  0.7
     Homepage:            http://www.ivn.cl/apache/
     Description:         Bandwidth Management Module for Apache2.

http://www.ivn.cl/apache/
http://www.ivn.cl/apache/files/txt/mod_bw-0.7.txt

mod_cband has really good documentation and is rich in features, so I thought I'd give that a wack first. To get this rolling, just emerge -pv mod_cband and make some configuration changes. After those changes are done, simply restart apache.

The first change you'll need to do is to edit /etc/conf.d/apache2 and add the -D CBAND, this will load that module.

Next, edit /etc/apache2/httpd.conf and add the following somewhere in the config:

CBandScoreFlushPeriod 1
CBandRandomPulse On

This will help in performance. mod_cband also has something similar to server-status where you can view cband stats. This is configured in the /etc/apache2/modules/10_mod_cband.conf file. Make sure you edit this file and restrict by IP or set BasicAuth. I restricted by IP.

<IfModule mod_cband.c>
<Location /cband-status>
SetHandler cband-status
Order deny,allow
Deny from all
allow from xxx.xxx.xxx.xxx
</Location>
</IfModule>

Now, we need to add bandwidth restriction on a per vhost basis. Inside the VirtualDirectory section, I added the following:

<IfModule mod_cband.c>
CBandLimit 6G
CBandPeriod 4W
CBandPeriodSlice 1W
CBandSpeed 500kbps 10 30
CBandExceededSpeed 128kbps 5 15
CBandScoreboard /var/www/scoreboard/domain.com.scoreboard
</IfModule>

This is basically saying the following. I'm going to give this vhost a cap of 6GB split up in 4 week slices (so 1.5GBs / week maximum). The max speed is 500kbps, with 10 requests/second and a max of 30 connections. If the allowance is exceeded, it'll throttle connections down to 128kbps, with 5 requests/second and max of 15 connections. CBand also will use a scoreboard (database) to track. So you'll need to make the directory /scoreboard and touch a file called domain.com.scoreboard in there.

Once that is all set up test apache with apache2ctl -t and restart. You can watch the activity by going to a vhost and adding the cband-status

http://www.domain.com/cband-status

At first, I was psyched on this, but a few things bugged me. First off, the issue was MP3 downloads, and yet the whole site is throttled and punished for this. Didn't like that. I also knew that they would exceed their 1.5GBs/week allocation, and this would force their entire site to be bogged down. I wanted something easier and to the point. I want to quickly throttle MP3 downloads. Here is where mod_bw comes in.

This is the Apache2 port of mod_bandwidth. Set up is similar. I removed all the mod_cband settings in the config and emerge -pv mod_bw. Added a new -D flag in /etc/conf.d/apache2 called -D BW.

Now, in my troublesome vhost, I added the following:

<IfModule mod_bw.c>
BandwidthModule On
ForceBandWidthModule On
LargeFileLimit .mp3 1 30000
</IfModule>

This turns on the bandwidth module. The LargeFileLimit is the setting to pay attention to. This is saying any file with .mp3 extension and if the file size is greater than 1K, throttle it down to 30kbsps. Hopefully this will help my situation. This won't prevent excessive downloads, but will slow things down. If this continues to be a problem, I will go to mod_cband and shutdown the site after bandwidth allocation has been exceeded. I'd just like to avoid this.

Hello

I received a comment asking about the script(s) I use to monitor traffic on a per vhost basis. The script is called traffic_counter.pl. Documentation and files can be found here:
http://sws.dett.de/mini/VHost_Traffic/

Hope this helps!

Excellent point. The problem as to why I introduced this escalated, and I ended up using limitipconn, and that directly hit the problem with the DoS on specific files.

This solution sounds great for throttling your downloads and making you users' lives a little slower, however it seems like it might expose your site to availability issues. For example, because your clients are downloading large files at slower speeds, they'll be occupying your apache processes for longer making them unavailable for other connections. This of course is only a problem if your site a fair amount of traffic, but probably worth mentioning none-the-less.