Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

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.
0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi bmeshier,

If you're still working on implementing this algo, I wrote a tech tip and an updated iRule for it. Check it out here: http://devcentral.f5.com/Tutorials/...tacks.aspx

-George
0