For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

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:

  1. URI to match on
  2. Timeoutvalue - this is this timeframe in seconds that will define the rate of good requests allowed
  3. maxattempts - the number of good requests allowed in the timeoutvalue before being shunned
  4. 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.0

1 Comment

  • Ekel's avatar
    Ekel
    Icon for Nimbostratus rankNimbostratus

    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