Block new requests from source IP if it exceeds defined request rate (URI)
Problem this snippet solves:
Simple irule to watch requests to a specific URI over time. If the rate of requests to that URI goes over a set threshold, the source IP address will be placed into a shun table and all connections hitting the irule will be rejected for a set period.
How to use this snippet:
Items you will need to define:
- URI to match on
- Timeoutvalue - this is this timeframe in seconds that will define the rate of good requests allowed
- maxattempts - the number of good requests allowed in the timeoutvalue before being shunned
- shuntimeout - the number of seconds a source IP must wait with no blocks before being allowed to make requests again
Code :
when HTTP_REQUEST { #timeoutvalue is how long requests stay in the auth attempts table set timeoutvalue 30 #maxattempts is the number of requests that can happen within the timeoutvalue before being shunned set maxattempts 20 #shuntimeout is the time that the source IP will be blocked once it gets shunned set shuntimeout 60 #reset every request if in shun table if { [table lookup -subtable "shun" [IP::client_addr]] > 0 } { table incr -subtable "shun" [IP::client_addr] set totaldrops [table lookup -subtable "shun" [IP::client_addr]] reject #log local0. "SHUN - Reset connection from [IP::client_addr] - Total: $totaldrops" return } if { ( [string tolower [HTTP::uri]] equals "/auth/login" ) } { #placeholder- send back fake auth response if in shun table #create large random number to act as an approx unique key - key collisions are not too detrimental set randkey [expr { int(100000000 * rand()) } ] #log local0. "URI match: created random key $randkey, adding to subtable for [IP::client_addr]" table set -subtable [IP::client_addr] $randkey 1 $timeoutvalue if { [table keys -subtable [IP::client_addr] -count] > $maxattempts} { log local0. "auth rate exceeded for [IP::client_addr], adding IP to shun table. Will unblock if no new conns for $shuntimeout seconds" #add source IP to the shun table with value of 1 #note, this specific request was not blocked, but new connections from same src IP will be blocked on next request table set -subtable "shun" [IP::client_addr] 1 $shuntimeout } } }
Published Mar 09, 2018
Version 1.0Shane_Levin
Employee
Joined June 06, 2013
Shane_Levin
Employee
Joined June 06, 2013
- EkelNimbostratus
Hi,
I am new on this. This is great. Can I see the log local0 from the f5 frontend? or it´s only from ssh?
Is it possible add a whitelist ip from the security policy?
Regards