Forum Discussion

Andreia's avatar
Andreia
Icon for Cirrus rankCirrus
Feb 28, 2023

How to read "Trusted Certificates Authorities" on an IRule ?


Hello,

I need to make an irule that reads a list of certificates, as is done in the SSL Client Profile in Trusted Certificate Authorities.
Something like this: https://clouddocs.f5.com/api/irules/ClientCertificateCNChecking.html
But without validating on a datagroup DN, or Issuers and etc. certificate specifics.

The logic I need is this:

If uri contains "/auth" then the client certificate is validated. Anything else is not validated.

I tried to use the following parameters in the iRule, but it falls in case I have to read a list or datagroup and I need to read any data from the client certificate that is valid in a "CA-Bundle".
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/auth/" } {
set protected 1
log local0. "Protected URI requested: [HTTP::uri]"
set collected 1
HTTP::collect
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
SSL::renegotiate
}
I can't disable "SSL::cert mode require" for everything that isn't "/auth".

Can someone please help me?

This kind of thing is so simple in NGINX code, but in BIG-IP I'm struggling to do it.

Thanks!

  • Here's something to get started...this will pick up the client cert if present, and expects in the static variables for you to set a validation string to compare to what's received dynamically from clients. It also expects you to set the client certificate field to request instead of the default ignore in the client-ssl profile. Once that's done, you can set the mode to require in the /auth URI requests and then do your other actions (not included)

    when RULE_INIT {
        set static::sdn_validator "subject_validation_string"
        set static::idn_validator "issuer_validation_string"
    }
    when CLIENTSSL_CLIENTCERT {
       if { [SSL::cert 0] != "" } {
            set subject_dn [X509::subject [SSL::cert 0]]
            set issuer_dn [X509::issuer [SSL::cert 0]]
            if { ($subject_dn contains $static::sdn_validator) and ($issuer_dn contains $static::idn_validator) } {
                set client_cert_validated 1
            }
        }
    }
    when HTTP_REQUEST {
        if { [HTTP::uri] == "/auth" }
            # make sure in your client-ssl profile you set the client certificate field to "request", default is ignore
            SSL::cert mode require
            if { [info exists client_cert_validated] } {
                # Certificate was present AND validated...do stuff here
            }
    }

    Noticed there are other requests of similar nature from you elsewhere, we might want to summarize the ask in a single thread to keep it all straight so we're not solving issues in one that creates issues in others.

    • Andreia's avatar
      Andreia
      Icon for Cirrus rankCirrus

      Hello, JRahm.

      First, thanks for replying. I really like your videos on F5 DevCentral! You rock!

      And I'm sorry, I was wrong about what I wrote above: /auth DOES NOT authenticate the client's certificate, the other requests do validate the client's certificate.

      Telling the WHOLE story, here we go:

      TODAY the company I provide services for has the following scenario:
      Internet -> Virtual Server with a Client SSL Profile with SSL Proxy-> Pool with NGINX servers that make a reverse proxy (so, this is where you have the application certificate) -> URL of the API service, incrementing BEFORE /auth something like /abc /xyz/auth

      In this scenario you have the following rule on the reverse proxy (NGINX):
      If URI starts with /auth, nginx does not validate client certificate; it just forwards the request to the API URL, incrementing the URI /abc/xyz/auth, for example.
      Any other request, it validates the client's certificate. If the client's certificate is not in a file.crt (CA Bundle), the client receives a 403 response.

      I want to do the EXACT SAME THING with BIG-IP. I want to remove the NGINX reverse proxy from the scenario.

      The application's Virtual server already has the client's ssl profile with the settings for validating the certificates in the ca-bundle.


      The problem is that I can't make an iRule like:
      If URI starts with "/auth" then SSL::cert mode ignore, or something like that.
      I made a rule with datagroup, that's why I'm asking about how to read the list in the Trusted Certificate Authorities via iRule, but it didn't help much because the iRule only accepts manipulating which Client SSL Profile will be used in the CLIENT_ACCEPT, but in this case, it doesn't handle URI.

      Developers are complaining a lot about the browser pop-up asking to choose which client certificate to use, and this is configurable in the NGINX code, but I didn't find anything similar in the iRule to handle this.

      And that's it. I'm sorry for "spreading" the same question in several different topics.

      Thanks for your time!