Forum Discussion
LTM :: iRule to Limit Source Addresses
So... here's a weird one. And I understand it's not optimal...
...but say there is a crisis and management sends down the proclamation: "Only allow X sources at a time access to the server pool until the admins can fix XYZ on the systems involved". So we rush to figure out a way to do so... and come up with the below.
Other than blasting the table full of addresses (such as a resource exhaustion DDoS against the F5), are there any other caveats that I might not be thinking about here?
when CLIENT_ACCEPTED {
set hsl [HSL::open -proto UDP -pool syslog-servers.pool]
}
when HTTP_REQUEST {
set source_ip [IP::client_addr]
set ip_limit 2000
Delete all IPs
table delete -subtable conns -all
if { [table lookup -notouch -subtable conns $source_ip] != 1 } {
Source IP doesn't exist in table, add to table
table add -subtable conns $source_ip 1 900
} else {
Source IP is in the table, actively involved, renew the timer
table lookup -subtable conns $source_ip
}
if { [table keys -subtable conns -count] <= $ip_limit } {
The current IP count is less than alloted, allow pool access
pool $pool_name
above variable acquired in prior logic
} else {
The IP count has been reached. Do not provide pool access.
HSL::send $hsl ":: Source IP limit ($ip_limit) hit for pool, redirecting to maintenance page."
call maintenance_page.irule::display_page
}
}
Hi Ryan,
the problem with your iRule is, that it would DoS your entire application once
has reached its configured limit. Even the[table keys -subtable conns -count]
which has been allowed before will become blocked.[IP::client_addr]
You may take a look to the iRule below how I would solve the puzzle. My iRule would allow the already known
until their[IP::client_addr]
entry expires and then allow another[table -subtable]
to access the application until its entry expires...[IP::client_addr]
when RULE_INIT { set static::ip_limit 2000 set static::ip_timeout 900 } when CLIENT_ACCEPTED { set hsl [HSL::open -proto UDP -pool syslog-servers.pool] } when HTTP_REQUEST { Delete all IPs table delete -subtable conns -all if { [table lookup -subtable conns [IP::client_addr]] ne "" } then { The client is currently known in the table. Already refreshed the clients table entry. Allow the request... } elseif { [table keys -subtable conns -count] < $static::ip_limit } then { The client is not known in the table. The connection limit has not been reached. Create a new entry for the client. table set -subtable conns [IP::client_addr] 1 $static::ip_timeout indef Allow the request... } else { The client is not known in the table. The connection limit has been reached. Log the request... HSL::send $hsl ":: Source IP limit ($ip_limit) hit for pool, redirecting to maintenance page." Display maintenance page... call maintenance_page.irule::display_page } }
Note: I've removed the pool logic, since it shouldn't considered as security control. The premptive
of your meintenance macro should be more than sufficent...[HTTP::respond]
Cheers, Kai
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com