Rate limiting is a crucial defense method against service misuse. The Halon platform implements this in a global rate controlling service called
rated. It handles rate limiting for all processes (HSL contexts), based on an "items per time interval" algorithm. Our implementation features a sliding rate limit (in contrast to leaking bucket; which has a fixed output rate regardless of exactly when the rate was exceeded).
The rate() function takes up to five arguments, the last one is for the optional array. For each defined namespace you can have multiple entries and if the count value is greater than zero it will increase the rate by one for each time the function is called with the same arguments. The function will return
true as long as the
rate() call interval is less than its rate limit, but
false when exceeded.
rate(namespace, entry, count, interval[, options])
You can use this function in use cases like
- Limit bulk / spam outbreaks from specific senders or authenticated users
- Prevent brute-force attacks against any type of SASL AUTH mechanism
- Service abuse control
Here's an example how you can limit how many suspicious messages a authenticated user can send per day.
// increase, and reject if exceeded if ($is_spam) if (rate("spammers", $senderip, 100, 86400) == false) Reject("You may only send 100 suspicious messages per day");
Or if you want to check if a specific namespace and entry has exceeded the limit
// get the rate limit number, without increasing if (rate("failed-login:saslusername", $saslusername, 0, 60) >= 3) Reject("Too many failed logins");
Rate limits are synchronized in the cluster if a HMAC-SHA1 key is specified in the configuration. The protocol is based on UDP and uses port 13131. In terms of security it may be wise to only activate this feature on local networks, as the HMAC-SHA1 only serves as a packet-authenticity firewall. It does not provide encryption nor protect against replay attacks. It should probably be protected by other means such as a VPN tunnel or psychical security (DMZ).
The rate limits performance is roughly O(log N + log M) and lookups are currently implemented as a C++ std::multimap.