Forum Discussion

Ryan_34424's avatar
Ryan_34424
Icon for Altostratus rankAltostratus
Apr 14, 2017

LTM :: SSL Client Authentication :: Lock Out

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.