Forum Discussion
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:
- 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.
- 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...
- doria786Nimbostratus
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.
- cazNimbostratus
Thanks for the insight, any chance you share your irule logic?
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com