Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

LTM :: SSL Client Authentication :: Lock Out

Ryan_34424
Altostratus
Altostratus

Has anybody implemented any controls on their LTMs that prohibits a source from repeatedly authenticating to a virtual server that requires SSL client authentication?

 

Granted... the ability to brute-force a 2048 bit key signed with sha256 from an internal/protected PKI is going to be rather... umm... difficult. However I don't want to give any prospects of a snow ball's slight chance in Mojave to induce any sort of undesirable condition (DoS, failure of authentication logic, unknown bugs... whatever it is). I want to slow that process down so it can either be detected earlier or prevented as a whole - of course. Plus, I'm an overly paranoid soul who simply rather not provide the ability for random sources to pound on the door at-will.

 

That being said... anybody share that concern? Has anybody done anything to put controls in place to limit failed SSL client authentication?

 

In my scenario, nobody should be touching the VS unless they have an approved mobile device that is part of our MDM with a certificate acquired by our PKI (SCEP). In light of that, I have zero regard for the gracefulness of client rejection.

 

There might be something built-in to accommodate this scenario... but I'm not aware of it. I was initially thinking iRule, so I just dove right into it.

 

I'm no programmer... but I'm thinking something along these lines (warning: this code has not been tested!). Would love any constructive feedback on any of the above or below!

 

Thanks 🐵

 

when RULE_INIT {
  set static::ip_lockout_attempts 3 
  set static::ip_lockout_xtimeout 900
}

when CLIENT_ACCEPTED {
  set client_ip [IP::client_addr]
  set hsl [HSL::open -proto UDP -pool syslog.pool]

  set bad_cert_count [table lookup -notouch $client_ip]
  if { $bad_cert_count == {} } {
    table add $client_ip 0 $static::ip_lockout_xtimeout
  } elseif { $bad_cert_count < $static::ip_lockout_attempts } {
    table lookup $client_ip
  } else {
    reject
    set time_remaining [expr { [table timeout -remaining $client_ip] / 60 }]
    HSL::send $hsl ":: SSL_REJECT :: Source IP $client_ip has been locked out. Time remaining: $time_remaining minutes."
  }
}

when CLIENTSSL_CLIENTCERT {
  if { [SSL::cert count] > 0 } {
    set cert_result [X509::verify_cert_error_string [SSL::verify_result]]
    if { $cert_result eq "ok" } {
      table delete $client_ip
    } else {
      table incr $client_ip
      HSL::send $hsl ":: SSL_REJECT :: Client certificate from $client_ip rejected."
    }
  } else {
    table incr $client_ip
    HSL::send $hsl ":: SSL_REJECT :: Client certificate from $client_ip not supplied to virtual server."
  }
}

Theory and base code borrowed from Jason Rahm and Stephanie via DevCentral.

 

2 REPLIES 2

Ryan77777
Altocumulus
Altocumulus

Was able to get this tested... and works. You may want something more graceful than the above... but for my use-case, it works as desired.

 

Kevin_Davies_40
Nacreous
Nacreous

Nice work!