Forum Discussion
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
}
}
}
- SebScottNimbostratus
Thanks I will try that tomorrow and let you know.
I think I may need to add the following to get an alternative client profile to ask for the client cert though. Is that right?
.......
# Redirect to a special URI that will prompt for a client certificate
HTTP::redirect "/require-cert$httpUri"SSL::session invalidate
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
set cmd "SSL::profile /Common/ClientSSL-RequireCert-Profile"
SSL::renegotiatereturn
........
- SebScottNimbostratus
Hi.
I did try this method, but got hit with a few little snags that I think are telling me I can't run these HTTP commands in the CLIENTSSL_CLIENTCERT event. Although the last line suggests I have not got the syntax right for the variable, which I could fix it is the first 3 lines that suggest I can't make this work because they need to be in the HTTP_REQUEST event, is that correct?
I am going to try and fire off a subroutine(Proc) to re-initiate the the ssl negotiation against different client SSL profile and then execute another Irule to trigger the CLIENT_SSL event and subsequent HHTP_REQUEST event which all seems very complicated so open to other simpler suggestions like this previous one from susan789wolf that showed real promise in the simpler logic
[command is not valid in current event context (CLIENTSSL_CLIENTCERT)][HTTP::redirect $original_uri] /Common/API-CNCheck-New-v2:53: error: [command is not valid in current event context (CLIENTSSL_CLIENTCERT)][HTTP::uri] /Common/API-CNCheck-New-v2:51: error: [command is not valid in current event context (CLIENTSSL_CLIENTCERT)][HTTP::uri] /Common/API-CNCheck-New-v2:3: error: [wrong # args][set static::client_cert_required "/BlahBlah" "/YadaYada/*"]
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