Forum Discussion

bmeshier_10715's avatar
bmeshier_10715
Icon for Nimbostratus rankNimbostratus
Nov 15, 2011

Exponential back off on failed logins

I'm trying to implement an exponential back off to thwart dictionary attacks. I'm currently being hit by over 5,000+ unique IPs, so linear rate limiting is not an effective solution.

 

 

http://en.wikipedia.org/wiki/Exponential_backoff

 

 

Using the algorithm below, where 'T' is seconds before they can attempt another login and 'c' is the number of failed attempts.

 

 

T(c) = (2^c -1) / 2

 

 

I'm comfortable with general iRule aspects but tying in time with subtables is throwing me for a loop. If anyone wants to give it a crack, for simplicity write an exponential back off for any POST request.

 

  • George_Watkins_'s avatar
    George_Watkins_
    Historic F5 Account
    What about something like this?

    when RULE_INIT {  set static::min_timeout 2  set static::max_timeout 86400  set static::debug 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 > 0 } {       exponential backoff - http://en.wikipedia.org/wiki/Exponential_backoff      set new_timeout [expr (((1 << $prev_attempts)-1)/2)]      if { $new_timeout > $static::max_timeout } {        set new_timeout $static::max_timeout      } elseif { $new_timeout < $static::min_timeout } {        set new_timeout $static::min_timeout      }      table incr -subtable $static::state_table $static::session_id      table timeout -subtable $static::state_table $static::session_id $new_timeout        if { $static::debug > 0 } {        log local0. "POST request from $static::session_id received during lockout period, updating timeout to ${new_timeout}s"      }       send TCP reset to client      reject       alternatively respond with content - http://devcentral.f5.com/wiki/iRules.HTTP__respond.ashx       HTTP::respond 200 content     } else {      table add -subtable $static::state_table $static::session_id 1 $static::min_timeout      if { $static::debug > 0 } {        log local0. "Added $static::session_id to exponential backoff state table"      }    }  }}

    Thanks for the idea,

    -George
  • Thanks, I'm going to look this over today and try it out. I'll post my final iRule, which includes detection of a failed login via web form.