17-Jan-2022 04:47
Hello Group,
My curent setup is as follows:
I have a HTTPS VS with Clinet SSL profile that has Client Authentication set to Request with Trusted CA and Advertised CA set to appropriate CA.
What I need to achieve is to insert the client Cert into the HTTP Header with the following conditions:
1) If there is no client Cert in the request, LTM should simply establish the connection.
2) If there is a client cert and it is signed by the Trunster CA, I should inser the ssl cert in X-Client-Cert and establish the connection.
3) If there is a client cert and it is not signed by the Trunster CA, I should reject the connetion.
4) if the reqest alredy has a X-Client-Cert header, I should drop the connection.
I do not have much experience in creating iRules but thied something like this:
when RULE_INIT {
set static::debug 1
}
when CLIENTSSL_CLIENTCERT {
set subject_dn [X509::subject [SSL::cert 0]]
if { $subject_dn != "" }{
if { $static::debug }{ log "Client Certificate received: $subject_dn"}
}
}
when HTTP_REQUEST {
if { ($subject_dn contains "CN=blah-blah") } {
HTTP::header insert X-Client-Cert [b64encode [SSL::cert 0]]
}
else {
continue
}
}
Needless to say, it did not work 😄
Scenarios 1) and 4) returned „SSL_connect: Connection reset by peer in connection to test-site:443“
Scenarios 2) adn 3) returned „SSL_read: Connection reset by peer, errno 54“
Any suggestions would be great.
Thanks in advance!
Solved! Go to Solution.
18-Jan-2022 05:50
I modified the rule and also added a check for existing x-client-cert. Now it seem to work.
when RULE_INIT {
set static::org "O=MON"
}
when CLIENTSSL_CLIENTCERT {
if {[SSL::cert 0] eq ""}{
return
}
else {
set issuer_dn [X509::issuer [SSL::cert 0]]
log "Client Certificate Received: $issuer_dn"
if { ($issuer_dn contains $static::org) } {
log "Client Certificate Accepted: $issuer_dn"
}
else {
log "No Matching Client Certificate Was Found Using: $issuer_dn"
reject
}
}
}
when HTTP_REQUEST {
foreach header_name [HTTP::header names] {
if {[string match -nocase x-client-cert $header_name]}{
HTTP::header remove $header_name
}
}
HTTP::header insert X-Client-Cert [b64encode [SSL::cert 0]]
}
I am leaving the full rule here, so if anyone need something similar, it can be used.
18-Jan-2022 00:00
I updated the iRule as follows:
when RULE_INIT {
set static::org "OU=<neededOU>"
}
when CLIENTSSL_CLIENTCERT {
if {[SSL::cert 0] eq ""}{
return
}
else {
set subject_dn [X509::subject [SSL::cert 0]]
log "Client Certificate Received: $subject_dn"
if { ($subject_dn contains $static::org) } {
log "Client Certificate Accepted: $subject_dn"
}
else {
log "No Matching Client Certificate Was Found Using: $subject_dn"
reject
}
}
}
when HTTP_REQUEST {
HTTP::header insert X-Client-Cert [b64encode [SSL::cert 0]]
}
Now I get somehow mixed results -
1 is OK
2 is OK
3 is Kinda OK - connection is reset
4 is not OK (which at time point is obvious as I am not actually trying to correct it - I want to get first 3 working first)
So what Is left is how to check if there is already and inserted spoofed X-Client-Cert in the header.
Any suggestions?
18-Jan-2022 05:50
I modified the rule and also added a check for existing x-client-cert. Now it seem to work.
when RULE_INIT {
set static::org "O=MON"
}
when CLIENTSSL_CLIENTCERT {
if {[SSL::cert 0] eq ""}{
return
}
else {
set issuer_dn [X509::issuer [SSL::cert 0]]
log "Client Certificate Received: $issuer_dn"
if { ($issuer_dn contains $static::org) } {
log "Client Certificate Accepted: $issuer_dn"
}
else {
log "No Matching Client Certificate Was Found Using: $issuer_dn"
reject
}
}
}
when HTTP_REQUEST {
foreach header_name [HTTP::header names] {
if {[string match -nocase x-client-cert $header_name]}{
HTTP::header remove $header_name
}
}
HTTP::header insert X-Client-Cert [b64encode [SSL::cert 0]]
}
I am leaving the full rule here, so if anyone need something similar, it can be used.