virtual server connection rate limit with tables
Problem this snippet solves:
Summary: Limit the rate of connections to a virtual server to prevent overloading of pool members
iRule Methodology:
For a given time interval, ensure that the rate of connections doesn't exceed a configurable threshold. Uses the table command to track number of new connections per second.
Code :
#
# Name: virtual server connection rate limiting rule
#
# Purpose: Limit the rate of connections to a virtual server to prevent overloading of pool members
#
# Methodology: For a given time interval, ensure the rate of connections doesn't exceed a configurable threshold
#
# Requirements:
# - LTM v10.1 or higher to use the table command
# - IP address datagroup containing a whitelist of IPs/subnets that should not be limited/counted (vsratelimit_whitelist_class)
# - Addition of this iRule to the virtual server.
#
# Warning: Due to a bug (fixed in 10.2.2), TMM can crash if this iRule is reconfigured or removed
# from the virtual server while traffic is pending. For more info see:
# Changing an iRule assignment on a virtual server may cause TMM to panic.
# http://support.f5.com/kb/en-us/solutions/public/11000/100/sol11149.html
#
when RULE_INIT {
# Log debug to /var/log/ltm? 1=yes, 0=no.
set static::conn_debug 1
# Maximum connection rate (new connections / time interval)
# To avoid the bug described in SOL11149, you could move this configuration to a datagroup
set static::conn_rate 10
# Time interval (in seconds)
# This shouldn't need to be changed.
# We track connections opened in the last X seconds
set static::interval 1
log local0. "Configured to enforce a rate of [expr {$static::conn_rate / $static::interval}]\
cps ($static::conn_rate connections / $static::interval second)"
# IP datagroup name which contains IP addresses/subnets to not track/rate limit
set static::whitelist_class vsratelimit_whitelist_class
# Generate a subtable name unique to this iRule and virtual server
# We use the virtual server name with this prefix (vsratelimit_)
set static::tbl "vsratelimit"
}
when CLIENT_ACCEPTED {
# Don't process any of this iRule if the client IP is in the whitelist datagroup
if {[class match [IP::client_addr] equals vsratelimit_whitelist_class]}{
# Exit this event from this iRule
return
}
# Track this connection in the subtable using the client IP:port as a key
set key "[IP::client_addr]:[TCP::client_port]"
# Save the virtual server-specific subtable name (vsratelimit_)
set tbl ${static::tbl}_[virtual name]
# Check if we're under the connection limit for the virtual server
set current [table keys -subtable $tbl -count]
if { $current >= $static::conn_rate } {
# We're over the rate limit, so reset the connection
if { $static::conn_debug }{ log local0. "$key: Connection to [IP::local_addr]:[TCP::local_port]\
([virtual name]). At limit, rejecting (current: $current / max: $static::conn_rate)" }
#reject
# apachebench stops when it gets a reset, so you can test with TCP::close to send a FIN and close the connection cleanly.
TCP::close
} else {
# We're under the virtual server connection rate limit,
# so add an entry for this client IP:port with a lifetime of X seconds
table set -subtable $tbl $key " " indefinite $static::interval
if { $static::conn_debug }{ log local0. "$key: Connection to [IP::local_addr]:[TCP::local_port]\
([virtual name]). Under limit, allowing (current: [table keys -subtable $tbl -count] / max: $static::conn_rate)" }
}
} Published 11 years ago
Version 1.0hoolio
Cirrostratus
VP of Solutions at WorldTech IT4 Comments
No CommentsBe the first to comment