Re-execute iRule to read CN value of client cert, but after you know URI.
Hi We have been dealing with a new implementation where we need to either accept or reject access to a certain path/URI of a VIP based on the CN of the client cert.........and for other paths that either don't have a client cert or the CN of a client cert does not match our Data-group allow access to other URIs.
We have a iRule below which works great, but it has to request a user for a client cert in which we only want to do when required to go to the target URIs. The only way we can get this to work is to have the "request" option enabled in the SSL client profile so it reads the subject under "when CLIENTSSL_CLIENTCERT' which obviously happens before we can read the path under "when HTTP_REQUEST" which is not great as it requests the client using a browser for a client certificate, which is what we want to avoid.
What we want to do is renegotiate SSL when going to a certain path so only those trying to get to a special path get requested for a client cert and then the subject is read and decision made based on CN of cert as to whether they can get to that path
We have tried to trigger a renegotiate ssl in a Proc, but the problem is we need to read the subject that you can only do in "when CLIENTSSL_CLIENTCERT" and don't know how to do that after a renegotiation ssl. We thought hat maybe we could restart the whole iRule again from the proc, but don't know how to do that. Maybe we could call another iRule, but it looks like that is just a proc too and we can't nest "when CLIENTSSL_CLIENTCERT" in anything. We have asked a TCL guru in our organisation and they are a little stumped too, so any help would be greatly appreciated.
As far as we can tell that can't be nested in a proc or any other stanza. Maybe there is a better way or there is a simple line of code we are missing. Here is a our script that does everything we need , but requests human clients using a browser for a client cert.
when RULE_INIT {
set static::debug 1
}
when CLIENTSSL_CLIENTCERT {
# Check if client provided a cert
if {[SSL::cert 0] eq ""}{
set subject_dn void
log local0.info "NoCert: $subject_dn"
} else {
#Example Subject DN: /C=AU/ST=NSW/L=Syd/O=Your Organisation/OU=Your OU/CN=John Smith
set subject_dn [X509::subject [SSL::cert 0]]
set client_cert [SSL::cert 0]
set ssl_client_cert_value [X509::whole $client_cert]
set client_cert_validated 1
log local0.info "Client Certificate Accepted: [SSL::cert 0]"
log local0.info "Client Certificate Received: $subject_dn"
#Check if the client certificate contains the correct O and a CN from the list
}
}
when HTTP_REQUEST {
set httpUri [HTTP::uri]
switch -glob [HTTP::uri] {
"/BlahBlah" -
"/YadaYada/*" {
##This is where we want to renegoiate a new SSL profile and read the client cert"
if { [info exists client_cert_validated] and ([matchclass $subject_dn contains API-CN_List]) } {
#Accept the client cert
log local0.info "ClientCertAccepted: $subject_dn"
return
}
else {
log local0.info "nugh 2.1"
###Or here
}
}
"/FreeForAll" -
"/NoNeedForCertHere" {
log local0.info "NoCertRequired"
return
}
default {
log local0.info "NoMatchingPath"
reject
return
}
}
}