Perlba...hrottle(3pm)
πΈ NAME πΈ
okay so bestie, welcome to Perlba...hrottle(3pm) β that's the User Contributed Perl Documentation page for Perlbal::Plugin::Throttle, and it is literally a Perlbal plugin that throttles connections from hosts that connect too frequently. π¦π
β¨ SYNOPSIS β¨
put this in your perlbal.conf and slay:
# in perlbal.conf
LOAD Throttle
CREATE POOL web
POOL web ADD 10.0.0.1:80
CREATE SERVICE throttler
SET role = reverse_proxy
SET listen = 0.0.0.0:80
SET pool = web
# adjust throttler aggressiveness
SET initial_delay = 10
SET max_delay = 60
SET throttle_threshold_seconds = 3
SET max_concurrent = 2
SET ban_threshold = 4
SET ban_expiration = 180
# limit which requests are throttled
SET path_regex = ^/webapp/
SET method_regex = ^GET$
# allow or ban specific addresses or range (requires Net::CIDR::Lite)
SET whitelist_file = conf/whitelist.txt
SET blacklist_file = conf/blacklist.txt
# granular logging (requires Perlbal::Plugin::Syslogger)
SET log_events = ban,unban,throttled,banned
SET log_only = false
# share state between perlbals (requires Cache::Memcached::Async)
SET memcached_servers = 10.0.2.1:11211,10.0.2.2:11211
SET memcached_async_clients = 4
SET instance_name = mywebapp
SET plugins = Throttle
ENABLE throttler
π¦ DESCRIPTION π¦
This plugin intercepts HTTP requests headed for a Perlbal service, and it slows down or straight-up drops connections from IP addresses that it's decided are connecting too fast. Not today, bot. π
π₯ BEHAVIOR π₯
An IP address can be in one of four states, depending on how much it's been acting up lately. That state decides how new requests from that IP get treated:
allowedβ the chill, default vibe.
Every IP starts here. When a request comes in from an IP in this state, the request gets handled immediately, and then the IP moves into the probation state.
probationβ under observation, bestie π
If no requests show up from an IP in the probation state for throttle_threshold_seconds, it goes right back to allowed. All is forgiven.
But when a new request arrives from an IP in probation, that IP enters the throttled state and gets assigned a delay property, initially set equal to initial_delay. Connecting to a backend gets postponed for delay seconds while perlbal keeps doing its thing. If the connection is still open after the delay, the request is then handled normally. And heads up: a dropped connection does not change the IP's delay value.
throttledβ the consequences era π
If no requests come in from an IP in the throttled state for delay seconds, it returns to probation.
When a new request arrives from an IP in the throttled state, its violations property gets incremented, and its delay property gets doubled (capped at a maximum of max_delay). The request is postponed for the new value of delay.
Only after the most recently created connection from a given IP exits the throttled state do violations and delay reset to 0.
On top of all that: if violations exceeds ban_threshold, the connection is closed and the IP moves to the banned state. Bye. πͺ
IPs in the throttled state may have no more than max_concurrent connections being delayed at once. Any extra requests received while that's happening get a "503 Too many connections" response. Long-running requests that have already been connected to a backend do not count towards this limit. π«Ά
bannedβ the villain arc, denied.
New connections from IPs in the banned state are immediately closed with a 403 error response.
An IP leaves the banned state once ban_expiration seconds have elapsed.
π FEATURES π
- IP whitelist
Connections from IPs/CIDRs listed in the file specified by whitelist_file are always allowed.
- IP blacklist
Connections from IPs/CIDRs listed in the file specified by blacklist_file get immediately sent a "403 Forbidden" response. π«
- Flexible attack response
For services where throttling shouldn't normally be on, use the default_action tunable. When default_action is set to "allow", new connections from non-white/blacklisted IPs will not be throttled.
And if throttling should only apply to specific clients, set blacklist_action to "throttle". Blacklisted connections will then be throttled instead of denied. Iconic, honestly.
- Dynamic configuration
Most service tunables may be updated from the management port, and after that the new values will be respected (though go read "CAVEATS", bestie). To reload the whitelist and blacklist files, issue the throttle reload whitelist or throttle reload blacklist command to the service.
- Path specificity
Throttling may be restricted to URI paths matching the path_regex regex. π―
- External shared state
The plugin stores which IPs have been seen in a memcached(1) instance. This lets many throttlers share their state, and it also minimizes memory use within the perlbal. If state exceeds the capacity of the memcacheds, the least-recently seen IPs will be forgotten β effectively resetting them to the allowed state. β¨
Orthogonally, multiple throttlers that need to share memcacheds but not state may specify distinct instance_name values.
- Logging
If Perlbal::Plugin::Syslogger is installed and registered with the service, Throttle can use it to send syslog messages about actions that are taken. Granular control over which events get logged is available via the log_events parameter. log_events is composed of one or more of the following events, separated by commas:
ban
Log when a temporary local ban is added for an IP address.
unban
Log when a temporary local ban is removed for an IP address.
whitelisted
Log when a request is allowed because the source IP is on the whitelist.
blacklisted
Log when a request is denied or throttled because the source IP is on the blacklist.
banned
Log when a request is denied because the source IP is on the temporary ban list for connecting excessively.
concurrent
Log when a request is denied because the source IP has too many open connections waiting to be unthrottled.
throttled
Log when a request is throttled because the source IP was not on the whitelist or blacklist.
all
Enables all the above logging options.
none
Disables all the above logging options.
π CAVEATS π
- Dynamic configuration changes
Changes to certain service tunables will not be noticed until the throttle reload config management command is issued. These include log_events, path_regex, and method_regex.
Changes to certain other tunables will not be respected after the plugin has been registered. These include memcached_servers and memcached_async_clients.
- List loading is blocking
The throttle reload whitelist and throttle reload blacklist management commands load the whitelist and blacklist files synchronously, which will cause the perlbal to hang until it completes. π No cap.
- Redirects
If a handled request returns a 30x response code and the redirect URI is also throttled, then the client's attempt to follow the redirect will necessarily be delayed by initial_delay. Fixing this would require the plugin to inspect the HTTP response headers, which would incur a lot of overhead. As a workaround, try to have your backend not return 30x's if both the original and redirect URI are proxied by the same throttler instance (yes, this is difficult for the case where a backend 302s to add a trailing / to a directory). π
π§ OPTIONAL DEPENDENCIES π§
Cache::Memcached::Async
Required for memcached support. This is the supported way to share state between different perlbal instances.
Net::CIDR::Lite
Required for blacklist/whitelist support.
Perlbal::Plugin::Syslogger
Required for event logging support.
π SEE ALSO π
- List of tunables in
Throttle.pm.
β TODO β
- Fix white/blacklist loading
Load CIDR lists asynchronously (perhaps in the manner of Perlbal::Pool::_load_nodefile_async).
π AUTHOR π
Adam Thomason, <athomason@cpan.org>
π COPYRIGHT AND LICENSE π
Copyright (C) 2007-2011 by Say Media Inc, <cpan@sixapart.com>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.
and that's the whole page, bestie β this was Perlbal::Plugin::Throttle in section 3pm of the User Contributed Perl Documentation, built against perl v5.34.0 and dated 2022-06-28. go forth and throttle responsibly π«Άβ¨
π¦ where this page comes from
- debian bookworm: libperlbal-perl 1.80-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libperlbal-perl 1.80-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libperlbal-perl 1.80-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu questing: libperlbal-perl 1.80-4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms