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 may be read and cleared using the REST API.
Rate limits are synchronized in the cluster if a HMAC-SHA1 key is specified on the Configuration > Server > Settings page. 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.
Under the Operations -> Activity -> Rate limiting page you can find all rates that have been registered by the rate() function. It's possible to search for a specific namespace, entry and only show rates that have exceeded a threshold. In this view you can also delete rates to reset the counter.
|Namespace||The namespace or "bucket".|
|Entry||The name of the rate limit entry.|
|See tables below|
|Interval||The time between first and last count.|
|Most recent||When a
If All hosts is selected under the Host selector. The rate limit may or may not be synchronized.
|Min||If shown, it is the lowest
|Same as for synchronized|
|Sum||The total sum of all
If a node is selected under the Host selector.
|Local count||If shown, the