
App::Cerberus::Plugin::Throttle - Throttle request rates based on IP ranges

version 0.10

This plugin allows you to throttle (rate limit) requests per second, per minute, per hour, per day or per month. Different limits can apply to different network ranges, and to different events.

Throttling information is returned when an IPv4 address is passed in:
curl http://host:port/?ip=64.233.160.1
Optionally, an event name can be included, which defaults to 'default'.
curl http://host:port/?ip=64.233.160.1;event=foo

plugins:
- Throttle:
store:
Memcached:
namespace: cerberus
servers:
- localhost:11211
second_penalty: 5
ranges:
default:
ips: 0.0.0.0/0
limit:
- 20 per second
- 100 per minute
google_bot:
group_ips: 1
limit: 10 per second
ips:
- 64.233.160.0/19
- 66.102.0.0/20
abusive:
limit: banned
ips:
- 205.217.153.73
- 199.19.249.196
There are two store backends available: Memory and Memcached. The Memory backend should NEVER be used in production. It is for testing purposes only:
plugins:
- Throttle:
store: Memory
ranges: ...
The Memcached backend uses Cache::Memcached::Fast and you can pass whatever options you would pass to new().
- Throttle:
store:
Memcached:
namespace: cerberus
servers:
- localhost:11211
The key for each range is its name, eg default, google_bot etc, which is returned by Cerberus.
The ips parameter is compiled into a regex using Net::IP::Match::Regexp. If two ranges interesect, then the more specific range matches.
If you want any IP address in a range to be considered the same user (eg all IPs from Google), then specify:
group_ips: 1
Otherwise each IP address will be treated separately.
The limit parameter can be:
noneImpose no limits
bannedNever allow
MAX per PERIODFor instance, 5 per second or 10 per minute. MAX can be any positive integer and PERIOD any of second, minute, hour, day or month.
If no IP is passed, or if the IP does not match any range, this plugin returns:
"throttle": {
"sleep": 0
}
If a range is matched, but the limit is not exceeded, the plugin returns (eg):
"throttle": {
"range": "google",
"sleep": 0
}
If the limit has been exceeded, the plugin returns (eg):
"throttle": {
"range": "google",
"reason": "second",
"sleep": 10,
"request_count": 12
}
Or, if banned:
"throttle": {
"range": "google",
"sleep": -1,
"reason": "banned"
}
If you want to use different limits per event, then the config should be as follows:
plugins:
- Throttle:
events:
default:
ranges:
default:
ips: 0.0.0.0/0
limit:
- 20 per second
- 100 per minute
my_event:
ranges:
default:
ips: 0.0.0.0/0
limit: 5 per second
The value for sleep reflects the number of seconds that the requesting user should wait until they try again. If the limit that has been exceeded is the number of request per second, this value will be 1.
If you want to impose a bigger penalty ("Woah, slow down cowboy!") you can specify a second_penalty. Note: this is advisory only. Only polite robots will respect this value.

Clinton Gormley <drtech@cpan.org>

This software is copyright (c) 2012 by Clinton Gormley.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.