.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Perlbal::Plugin::Throttle 3pm" .TH Perlbal::Plugin::Throttle 3pm "2022-06-28" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Perlbal::Plugin::Throttle \- Perlbal plugin that throttles connections from hosts that connect too frequently. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& # 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 .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This plugin intercepts \s-1HTTP\s0 requests to a Perlbal service and slows or drops connections from \s-1IP\s0 addresses which are determined to be connecting too fast. .SH "BEHAVIOR" .IX Header "BEHAVIOR" An \s-1IP\s0 address address may be in one of four states depending on its recent activity; that state determines how new requests from the \s-1IP\s0 are handled: .IP "\(bu" 4 \&\fBallowed\fR .Sp An \s-1IP\s0 begins in the \fBallowed\fR state. When a request is received from an \s-1IP\s0 in this state, the request is handled immediately and the \s-1IP\s0 enters the \&\fBprobation\fR state. .IP "\(bu" 4 \&\fBprobation\fR .Sp If no requests are received from an \s-1IP\s0 in the \fBprobation\fR state for \&\fIthrottle_threshold_seconds\fR, it returns to the \fBallowed\fR state. .Sp When a new request is received from an \s-1IP\s0 in the \fBprobation\fR state, the \s-1IP\s0 enters the \fBthrottled\fR state and is assigned a \fIdelay\fR property initially equal to \fIinitial_delay\fR. Connection to a backend is postponed for \fIdelay\fR seconds while perlbal continues to work. If the connection is still open after the delay, the request is then handled normally. A dropped connection does not change the \s-1IP\s0's \fIdelay\fR value. .IP "\(bu" 4 \&\fBthrottled\fR .Sp If no requests are received from an \s-1IP\s0 in the \fBthrottled\fR state for \&\fIdelay\fR seconds, it returns to the \fBprobation\fR state. .Sp When a new request is received from an \s-1IP\s0 in the \fBthrottled\fR state, its \&\fIviolations\fR property is incremented, and its \fIdelay\fR property is doubled (up to a maximum of \fImax_delay\fR). The request is postponed for the new value of \fIdelay\fR. .Sp Only after the most recently created connection from a given \s-1IP\s0 exits the \&\fBthrottled\fR state do \fIviolations\fR and \fIdelay\fR reset to 0. .Sp Furthermore, if the \fIviolations\fR exceeds \fIban_threshold\fR, the connection is closed and the \s-1IP\s0 moves to the \fBbanned\fR state. .Sp IPs in the \fBthrottled\fR state may have no more than \fImax_concurrent\fR connections being delayed at once. Any additional requests received in that circumstance are sent a \*(L"503 Too many connections\*(R" response. Long-running requests which have already been connected to a backend do not count towards this limit. .IP "\(bu" 4 \&\fBbanned\fR .Sp New connections from IPs in the banned state are immediately closed with a 403 error response. .Sp An \s-1IP\s0 leaves the \fBbanned\fR state after \fIban_expiration\fR seconds have elapsed. .SH "FEATURES" .IX Header "FEATURES" .IP "\(bu" 4 \&\s-1IP\s0 whitelist .Sp Connections from IPs/CIDRs listed in the file specified by \fIwhitelist_file\fR are always allowed. .IP "\(bu" 4 \&\s-1IP\s0 blacklist .Sp Connections from IPs/CIDRs listed in the file specified by \fIblacklist_file\fR immediately sent a \*(L"403 Forbidden\*(R" response. .IP "\(bu" 4 Flexible attack response .Sp For services where throttling should not normally be enabled, use the \&\fIdefault_action\fR tunable. When \fIdefault_action\fR is set to \*(L"allow\*(R", new connections from non\-white/blacklisted IPs will not be throttled. .Sp Furthermore, if throttling should only apply to specific clients, set \&\fIblacklist_action\fR to \*(L"throttle\*(R". Blacklisted connections will then be throttled instead of denied. .IP "\(bu" 4 Dynamic configuration .Sp Most service tunables may be updated from the management port, after which the new values will be respected (although see \*(L"\s-1CAVEATS\*(R"\s0). To reload the whitelist and blacklist files, issue the \fIthrottle reload whitelist\fR or \&\fIthrottle reload blacklist\fR command to the service. .IP "\(bu" 4 Path specificity .Sp Throttling may be restricted to \s-1URI\s0 paths matching the \fIpath_regex\fR regex. .IP "\(bu" 4 External shared state .Sp The plugin stores state which IPs have been seen in a \fBmemcached\fR\|(1) instance. This allows many throttlers to share their state and 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 \&\fBallowed\fR state. .Sp Orthogonally, multiple throttlers which need to share memcacheds but not state may specify distinct \fIinstance_name\fR values. .IP "\(bu" 4 Logging .Sp If Perlbal::Plugin::Syslogger is installed and registered with the service, Throttle can use it to send syslog messages regarding actions that are taken. Granular control for which events are logged is available via the \fIlog_events\fR parameter. \fIlog_events\fR is composed of one or more of the following events, separated by commas: .RS 4 .IP "\(bu" 4 ban .Sp Log when a temporary local ban is added for an \s-1IP\s0 address. .IP "\(bu" 4 unban .Sp Log when a temporary local ban is removed for an \s-1IP\s0 address. .IP "\(bu" 4 whitelisted .Sp Log when a request is allowed because the source \s-1IP\s0 is on the whitelist. .IP "\(bu" 4 blacklisted .Sp Log when a request is denied or throttled because the source \s-1IP\s0 is on the blacklist. .IP "\(bu" 4 banned .Sp Log when a request is denied because the source \s-1IP\s0 is on the temporary ban list for connecting excessively. .IP "\(bu" 4 concurrent .Sp Log when a request is denied because the source \s-1IP\s0 has too many open connections waiting to be unthrottled. .IP "\(bu" 4 throttled .Sp Log when a request is throttled because the source \s-1IP\s0 was not on the whitelist or blacklist. .IP "\(bu" 4 all .Sp Enables all the above logging options. .IP "\(bu" 4 none .Sp Disables all the above logging options. .RE .RS 4 .RE .SH "CAVEATS" .IX Header "CAVEATS" .IP "\(bu" 4 Dynamic configuration changes .Sp Changes to certain service tunables will not be noticed until the \fBthrottle reload config\fR management command is issued. These include \fIlog_events\fR, \&\fIpath_regex\fR, and \fImethod_regex\fR). .Sp Changes to certain other tunables will not be respected after the plugin has been registered. These include \fImemcached_servers\fR and \&\fImemcached_async_clients\fR. .IP "\(bu" 4 List loading is blocking .Sp The \fIthrottle reload whitelist\fR and \fIthrottle reload blacklist\fR management commands load the whitelist and blacklist files synchronously, which will cause the perlbal to hang until it completes. .IP "\(bu" 4 Redirects .Sp If a handled request returns a 30x response code and the redirect \s-1URI\s0 is also throttled, then the client's attempt to follow the redirect will necessarily be delayed by \fIinitial_delay\fR. Fixing this would require that the plugin inspect the \s-1HTTP\s0 response headers, which would incur a lot of overhead. To workaround, try to have your backend not return 30x's if both the original and redirect \s-1URI\s0 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). .SH "OPTIONAL DEPENDENCIES" .IX Header "OPTIONAL DEPENDENCIES" .IP "\(bu" 4 Cache::Memcached::Async .Sp Required for memcached support. This is the supported way to share state between different perlbal instances. .IP "\(bu" 4 Net::CIDR::Lite .Sp Required for blacklist/whitelist support. .IP "\(bu" 4 Perlbal::Plugin::Syslogger .Sp Required for event logging support. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 List of tunables in Throttle.pm. .SH "TODO" .IX Header "TODO" .IP "\(bu" 4 Fix white/blacklist loading .Sp Load \s-1CIDR\s0 lists asynchronously (perhaps in the manner of Perlbal::Pool::_load_nodefile_async). .SH "AUTHOR" .IX Header "AUTHOR" Adam Thomason, .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2007\-2011 by Say Media Inc, .PP 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.