Forum Discussion

caz's avatar
caz
Icon for Nimbostratus rankNimbostratus
Apr 15, 2024

Disacard SSL::cert mode to ignore when default SSLClient profile is set to request or require

My need: I want to have one unique VIP to handle both non-secure traffic for UI service and also to secure API services.

For the API, I have 2 cases:

  1. jwt is provided, I need to have the SSL::cert mode to require only if I have clientId in the claims (I have the logic to handle this already), if no clientId in the claims, I need to have the SSL::cert mode to ignore.
  2. jwt is not provided, I need to have SSL::cert mode to require.

 

In F5 I have a sslClientProfile set to request or require and I would like to set it to ignore on a certain condition (URL path based). When doing so in an iRule, it doesn't work to me. I found no way to make the SSL::cert mode ignore to work.

I tried to do the opposite, setting the sslClientProfile to ignore in F5 and elevate the SSL::cert mode to request or ignore depending on my need, but when doing so, the certificates I pass in the query are not taken and I can't add them in a Header.

 

Here's what I tried with the F5's sslClientProfile set to ignore:

when HTTP_REQUEST {
  if { [HTTP::header exists "Authorization"] } {
    if { ([HTTP::header value Authorization] starts_with "Bearer ") } {
      set jwt_header_b64_url [string range [getfield [HTTP::header value Authorization] "." 1] 7 end]
      set jwt_body_b64_url [getfield [HTTP::header value Authorization] "." 2]
      set jwt_sig_b64_url [getfield [HTTP::header value Authorization] "." 3]

      if { $jwt_header_b64_url ne "" and  $jwt_body_b64_url ne "" and $jwt_sig_b64_url ne "" } {
        set jwt_header [call b64url_decode $jwt_header_b64_url]
        set jwt_body [call b64url_decode $jwt_body_b64_url]
        set jwt_sig [call b64url_decode $jwt_sig_b64_url]

        if { $jwt_header ne "" and $jwt_body ne "" and $jwt_sig ne ""} {
          set jwt_clientId [call get_json_str "clientId" $jwt_body]

          if {[string trim $jwt_clientId] ne ""} {
            if { [SSL::cert count] <= 0 } {
              HTTP::collect
              SSL::authenticate always
              SSL::authenticate depth 9
              SSL::cert mode require
              SSL::renegotiate
            }
          }
        }
      }
    }
  }

  if { [HTTP::uri] matches_regex {/auth|/.*/.*/.*/auth/.*|/.*/ua-ui/.*|/favicon.ico|/federation.*|/f5/health} } {
    set uri [regsub -nocase {/.*/.*/.*/auth/} [HTTP::uri] "/auth/"]
    HTTP::uri $uri
  } else {
    if { [SSL::cert count] <= 0 } {
      HTTP::collect
      SSL::authenticate always
      SSL::authenticate depth 9
      SSL::cert mode require
      SSL::renegotiate
    }
  }
}

when HTTP_REQUEST_SEND {
  clientside {
    if { [SSL::cert count] > 0 } {
      set thecert [X509::whole [SSL::cert 0]]
      HTTP::header insert "HTTP_HEADER_CLIENT_CERT" [X509::whole [SSL::cert 0]]
      HTTP::header insert "X-SSL-Client-Cert-S-Dn" [X509::subject [SSL::cert 0]]
      HTTP::header insert "X-SSL-Client-Cert-I-Dn" [X509::issuer [SSL::cert 0]]
      set sslresult [X509::verify_cert_error_string [SSL::verify_result]]
      HTTP::header insert "X-SSL-Client-Cert-Verify" [string map -nocase {"ok" "success"} $sslresult]
    } else {
      if { [HTTP::header exists "HTTP_HEADER_CLIENT_CERT"] } {
        HTTP::header replace "HTTP_HEADER_CLIENT_CERT" ""
      }
      HTTP::header insert "HTTP_HEADER_CLIENT_CERT" ""
    }
  }
}

 

I tried to reverse the logic but I couldn't get it work.

Is there another way to handle the downgrade of SSL::cert mode to ignore?

 

Note: I tried also something proposed in Requiring an SSL Certificate for Parts of an Application | DevCentral with no luck...

  • In the HTTP_REQUEST event, we check if the clientId exists in the JWT claims. If it does, we require an SSL certificate. Otherwise, we ignore it. The URL path-based logic ensures that specific paths are handled differently. In the HTTP_REQUEST_SEND event, we handle the client certificate details. 

    • caz's avatar
      caz
      Icon for Nimbostratus rankNimbostratus

      Thanks for the insight, any chance you share your irule logic?