Selective URL client cert authentication with OU check
I'm trying to write an iRule which requires client cert for selected URLs - similar to this one: https://devcentral.f5.com/s/articles/selective-client-cert-authentication.
I need to add one extra check though: when client provides the certificate, only clients with specific OU in the certificate (or the ones coming from certain source IP, which isn't relevant to the problem though described below) are allowed. It doesn't work, I see errors in the log when trying to call the certificate value. Although it should be possible to use certificate commands [X509::subject [SSL::cert 0]] or call the variable holding the same info in the HTTP_REQUEST event, everytime I try to call it from within Event HTTP_REQUEST I see TCL errors, even when I remove the OU check condition and just try to log the cert info. I am able to use the cert info in HTTP_REQUEST_SEND event though.
I am migrating this functionality from existing Apache Reverse Proxy config, where they achieved that quite easily, so there must be a way to replicate it to F5.
when CLIENTSSL_CLIENTCERT {
set cert_subject [X509::subject [SSL::cert 0]]
set cert_issuer [X509::issuer [SSL::cert 0]]
# release any stored data just in case
HTTP::release
# if there is still no cert after the SSL renegotiation kill the connection by sending a reset back to the client
if { [SSL::cert count] < 1 } {
reject
}
}
when HTTP_REQUEST {
set uri [HTTP::uri]
switch -glob $uri {
"/test1/*" {
if { [SSL::cert count] <= 0 } {
HTTP::collect
SSL::authenticate always
SSL::authenticate depth 10
SSL::cert mode require
SSL::renegotiate
if { ($cert_subject contains "OU=Department1") || (($cert_subject contains "OU=Department2") && ($cert_subject contains "OU=PROD")) || ( [IP::addr [getfield [IP::client_addr] "%" 1] equals 192.168.20.1 ] ) } {
pool pool1
} else {
reject
}
}
}
}
}