Forum Discussion

What_Lies_Benea's avatar
What_Lies_Benea
Icon for Altostratus rankAltostratus
Oct 29, 2013

OCSP With CRL Fallback

Hi all, I've been trying to get my head around OCSP and CRL in a rush. My requirement is relatively simple but without APM (not an option) I'm trying to do this via an iRule. Anyway, the requirement is this;

 

-Use OCSP as the primary method of verifying client certificates (requires an OCSP profile) -Use CRL (not CRLDP) as a fallback should the OCSP responders be unavailable for any reason (requires an SSL profile)

 

According to this, if both are applied (via profiles) then both checks must 'pass' not just one or the other, hence the iRule.

 

I've found examples of using OCSP in an iRule here, here and here (thanks Hoolio) but litle around CRL checking.

 

So, my questions are;

 

-Can I use an iRule to perform the OCSP check and then, if OCSP fails for some reason, switch to an SSL profile that has CRL checking enabled so that CRL checking is performed?

 

-If not, does anyone has any example code for performing a CRL check?

 

-Would it simply be better to use a Pool (or something along these lines) and check it's up rather than do the OCSP check 'manually' in the iRule?

 

6 Replies

  • Can I use an iRule to perform the OCSP check and then, if OCSP fails for some reason, switch to an SSL profile that has CRL checking enabled so that CRL checking is performed?

    That's actually a pretty good idea. Here's what you'd need to make this work:

    • An internal virtual server, pool, and monitor to load balance the actual remote OCSP resource(s).

    • An OCSP profile including a responder config that points to the above VIP, and the following iRule (applied directly to the profile). This is a slightly modified version of the built-in _sys_auth_ssl_ocsp iRule:

      when RULE_INIT {
           user-defined: name of OCSP server pool (behind OCSP VIP)
          set static::OCSP_POOL "ocsp.domain.com.pool"
      
           user-defined: name of client SSL profile with defined (static) CRL
          set static::CRL_CLIENTSSL "myserver1.domain.com.crl"
      
           user-defined: local debug
          set static::LOCAL_DEBUG 1
      }
      when CLIENT_ACCEPTED {
          if { [active_members $static::OCSP_POOL] < 1 } {
              if { $static::LOCAL_DEBUG } { log local0. "OCSP pool is down - switching to local CRL" }
              set localcrl 1
              SSL::profile $static::CRL_CLIENTSSL
          } else {
              set tmm_auth_ssl_ocsp_sid 0
              set tmm_auth_ssl_ocsp_done 0
          }
          set local_ip [IP::client_addr]
      }
      when CLIENTSSL_CLIENTCERT {
          set local_cert_subj [X509::subject [SSL::cert 0]]
          set local_cert_sn [X509::serial_number [SSL::cert 0]]
      
          if { not ( [info exists localcrl] ) } {
              set tmm_auth_ssl_ocsp_done 0
              if {$tmm_auth_ssl_ocsp_sid == 0} {
                  set tmm_auth_ssl_ocsp_sid [AUTH::start pam default_ssl_ocsp]
                  if {[info exists tmm_auth_subscription]} {
                      AUTH::subscribe $tmm_auth_ssl_ocsp_sid
                  }
              }
              AUTH::cert_credential $tmm_auth_ssl_ocsp_sid [SSL::cert 0]
              AUTH::cert_issuer_credential $tmm_auth_ssl_ocsp_sid [SSL::cert issuer 0]
              AUTH::authenticate $tmm_auth_ssl_ocsp_sid
              SSL::handshake hold
          }
      }
      when CLIENTSSL_HANDSHAKE {
          if { not ( [info exists localcrl] ) } {
              set tmm_auth_ssl_ocsp_done 1
          } 
      }
      when AUTH_RESULT {
          if { [info exists tmm_auth_ssl_ocsp_sid] and ( $tmm_auth_ssl_ocsp_sid == [AUTH::last_event_session_id] ) } {
              switch [AUTH::status] {
                  "0" {
                       OCSP check good certificate
                      if { $static::LOCAL_DEBUG } { log local0. "OCSP check good certificate: Source: $local_ip - Subject: $local_cert_subj - Serial: $local_cert_sn" }
                          set tmm_auth_ssl_ocsp_done 1
                          SSL::handshake resume
                      }
                  "1" {
                       OCSP check revoked certificate
                      if { $static::LOCAL_DEBUG } { log local0. "OCSP check revoked certificate: Source: $local_ip - Subject: $local_cert_subj - Serial: $local_cert_sn"  }           
                          reject
                      }
                  default {
                       OCSP check failed or unknown status
                      if { $static::LOCAL_DEBUG } { log local0. "OCSP check failed or unknown status: Source: $local_ip" }            
                          reject
                      }
                  }
              }
          }
      
    • Your application virtual server that has a standard client SSL profile (client certificate request/require and trusted authorities cert selected) and the OCSP authentication profile.

    • A second client SSL profile, identical to the first, but with a static CRL embedded.

    The OCSP auth iRule simply switches to the other client SSL profile if there are no members in the OCSP pool. You'll want a good monitor on the OCSP pool, one that potentially makes OCSP calls with known good and revoked certificates. You'll also need a mechanism to update the static CRL on some regular interval. See:

    https://devcentral.f5.com/questions/automaticlly-update-crl

    On a side note, it's actually quite difficult with the (old) auth profile stuff to detect OCSP errors within the iRule, so it tends to be easier and more reliable to stand up a monitor that proactively maintains the state of the remote OCSP resource.

  • Thanks Kevin, I've already 'borrowed' the bash script ;-) I don't know where you get the time.

     

    Interesting that the iRule is applied to the OCSP profile; it hadn't occurred to me it could be and great it can be!

     

    I'll probably be tweaking/checking tonight and testing tomorrow, I'll let you (and DC in general) know how it goes. Thanks again.

     

  • Kevin, forgive the dumb question but apart from the part that switches to the CRL enabled SSL profile, why do I actually need the rest of the rule?

     

  • Authentication profiles are triggered by iRules. You'll notice your system has a set of built-in "_sys_auth_" iRules. These are used with their respective auth profiles to actually trigger the authentication process - generally a call to PAM - and are actually assigned in the auth profile (not in the VIP). The code I'm using is a modification of the required OCSP iRule.

     

  • lani93's avatar
    lani93
    Icon for Nimbostratus rankNimbostratus

    Hello Kevin_Stewart 

    am facing the same problematic.

    what about if there is just a CRL's URL in the certificate (no AIA ocsp) and the pool is up. how can i fix this scenario ?

    • Kevin_Stewart's avatar
      Kevin_Stewart
      Icon for Employee rankEmployee

      This is a super old thread 😉

      So before diving into any options, just need to clarify: the above is for client cert validation only. Do you mean that the client cert only has a CRLDP value, and no AIA (OCSP) value?