POST Request Exponential Backoff

Problem this snippet solves:

When applied to an HTTP virtual server, the exponential backoff iRule will count the POST requests and prevent users from firing them off two quickly. If a user or bot issues two tightly coupled POST requests they will be locked out temporarily and receive an HTTP response advising them to slow down. If they continue to probe the virtual server, they will be locked out for the next 24 hours on their 18th attempt.

Code :

when RULE_INIT {
  set static::min_lockout 2
  set static::max_lockout 86400
  set static::logging 1
}

when CLIENT_ACCEPTED {
  set static::session_id "[IP::remote_addr]:[TCP::remote_port]"
  set static::state_table "[virtual name]-exp-backoff-state"
}

when HTTP_REQUEST {
  if { [HTTP::method] eq "POST" } {
    set prev_attempts [table lookup -subtable $static::state_table $static::session_id]

    if { $prev_attempts eq "" } { set prev_attempts 0 }

    # exponential backoff - http://en.wikipedia.org/wiki/Exponential_backoff
    set new_lockout [expr (1 << ($prev_attempts-1))]

    if { $new_lockout > $static::max_lockout } {
      set new_lockout $static::max_lockout
    } elseif { $new_lockout < $static::min_lockout } {
      set new_lockout $static::min_lockout
    }

    table incr -subtable $static::state_table $static::session_id
    table timeout -subtable $static::state_table $static::session_id $new_lockout

    if { $static::logging > 0 } {
      log local0. "POST request (#[expr ($prev_attempts+1)]) from $static::session_id received during lockout period, updating lockout to ${new_lockout}s"
    }

    if { $prev_attempts > 1 } {
      # alternatively respond with content - https://devcentral.f5.com/s/wiki/iRules.HTTP__respond.ashx
      set response "Hold up there!

Hold up there!

You're" append response " posting too quickly. Wait a few moments are try again.

" HTTP::respond 200 content $response } } }
Published Mar 18, 2015
Version 1.0

Was this article helpful?

No CommentsBe the first to comment