Forum Discussion
AndOs
Dec 25, 2016Cirrostratus
To allow only specific certificates you can use an iRule.
There are a few examples in the code share.
Validate Certificate Common Name and Revocation Status
Request Client Certificate And Pass To Application
Client Certificate CN Checking
Here is a version of an iRule I've used in the past.
Looking at the code now I see that there's room for improvements here and there 🙂 But hopefully this, or any of the examples above can get you started.
Derived from http://devcentral.f5.com/wiki/default.aspx/iRules/ClientCertificateCNChecking.html
when RULE_INIT {
set static::certinspect_debug 0
log local0. "iRule updated or initialized. debug = $static::certinspect_debug"
}
when CLIENTSSL_CLIENTCERT {
init allowed/disallowed flag
default to not trusted.
set client_cert_ok 0
Check if client provided a cert
if {[SSL::cert 0] eq ""} {
if { $static::certinspect_debug } { log local0. "No client cert sent from client. Client='[IP::client_addr]:[TCP::client_port]'" }
Reset the connection
reject
} else {
if { $static::certinspect_debug } { log local1. "SSL SessionID='[SSL::sessionid]' | Client='[IP::client_addr]:[TCP::client_port]'" }
Get the subject DN from cert.
set subject_dn [X509::subject [SSL::cert 0]]
Check trusted certs.
switch -glob [string tolower $subject_dn] {
"serialnumber=xyz,cn=name.domain.com,o=org,c=se" {
Client cert is trusted. Set flag. Need to be set to 1 for logic in HTTP_REQUEST to work.
set client_cert_ok 1
if { $static::certinspect_debug } { log local1. "Matching client cert: $subject_dn | Client='[IP::client_addr]'" }
}
default {
log local0. "NO MATCHING CLIENT CERTIFICATE!: $subject_dn | Client='[IP::client_addr]:[TCP::client_port]'"
reject
}
}
}
}
when HTTP_REQUEST {
Client sent an HTTP request.
if { $static::certinspect_debug } { log local1. "URI='[HTTP::uri]' | SSL SessionID='[SSL::sessionid]' | Client='[IP::client_addr]:[TCP::client_port]'" }
check if the client cert for this connection was trusted.
if it was not, send an error message to the client.
if { ( [info exists client_cert_ok ] && $client_cert_ok == 1 ) } {
request accepted
} else {
if { $static::certinspect_debug } { log local1. "Sending deny to client | URI='[HTTP::uri]' | SSL SessionID='[SSL::sessionid]' | Client='[IP::client_addr]:[TCP::client_port]'" }
HTTP::respond 403 content "Bad client certificate!"
}
}
/Andreas