Forum Discussion
Ron_Kim_110696
Nimbostratus
Jan 11, 2007iRule example to extract specific X509 information: SOL5171
I can't get this iRule to work.
The variable $sn in the HTTP_REQUEST section does not have a value.
It is working in the CLIENTSSL_CLIENTCERT section.
Variables do not seem to pass from the CLIENTSSL_CLIENTCERT to the HTTP_REQUEST sections.
================
iRule example to extract specific X509 information: SOL5171
In the following example, a variable value is set using an SSL command to identify the X509 certificate. Once the X509 certificate is identified, another variable value is set using an X509 command to extract the certificate serial number. The client certificate's serial number is then inserted into an HTTP header with the name Serial.
when CLIENTSSL_CLIENTCERT {
set cert [SSL::cert 0]
set sn [X509::serial_number $cert]
}
when HTTP_REQUEST {
if { [info exists sn] } {
HTTP::header insert Serial $sn
}
}
8 Replies
- Colin_Walker_12Historic F5 AccountWhen you say that the $sn variable doesn't have a value, are you saying that because the "Serial" header being inserted is blank? Is the Serial header even being inserted?
I'd add a few logging statements to the rule to be sure things are functioning, or in this case malfunctioning, the way you think they are, and to give us a bit more insight if things are still failing as to what the problem might be.
Something like:when CLIENTSSL_CLIENTCERT { set cert [SSL::cert 0] set sn [X509::serial_number $cert] log local0. "cert is $cert" log local0. "sn is $sn" } when HTTP_REQUEST { if { [info exists $sn] } { HTTP::header insert Serial $sn log local0. "sn is $sn" } }
HTH,
Colin - Ron_Kim_110696
Nimbostratus
Thank you.
We tried this.
when CLIENTSSL_CLIENTCERT {
set cert [SSL::cert 0]
set sn [X509::serial_number $cert]
log local0. "cert is $cert" ; This works
log local0. "sn is $sn" ; This works
}
when HTTP_REQUEST {
if { [info exists $sn] } {
HTTP::header insert Serial $sn
log local0. "sn is $sn" ; This DOES NOT work. Blank Value
}
}
Any variable that is set in the CLIENTSSL_CLIENTCERT section, does not pass to the HTTP_REQUEST section.
We tried this with multiple different X509 variables.
We are running version 9.1.2, could this be a bug? - Deb_Allen_18Historic F5 AccountI talked to one of my co-workers who encountered this difficulty, and he worked around it by saving the value in the session table in CLIENTSSL_CLIENTCERT with a key of ssl-id, then pulled it out of the session table in HTTP_REQUEST as in this codeshare example:
http://devcentral.f5.com/wiki/default.aspx/iRules/InsertCertInServerHeaders.html (Click here)
HTH
/deb - Ron_Kim_110696
Nimbostratus
Thanks.
We now have an iRule that works.
Now how do we use the "SSL:cert mode request" command to toggle ON and OFF depending on the URI?
And how do we handle the case when the client does not have an Client SSL cert.
What would be the best way to achieve the following?
* Create a Class that has a list of URI's.
* If the URI is listed in the Class, then do not Request the Client SSL cert.
* If the URI is NOT in the Class, then ask for the Client SSL cert.
- Client does NOT have or does NOT have the proper Client SSL cert, then sent them to an error page. (I guess a good filter for the Proper SSL cert would be based on the Issuer.)
- The Client DOES have a valid SSL cert, then insert information into an HTTP header. - Colin_Walker_12Historic F5 AccountIf it were me, I would create a class of URIs (assuming you have more than 10-15 or so, otherwise an if/else chain or switch is more efficient), and check to see if the incoming URI is in that class. On success, I'd force the cert mode to require.
It would look something like this (assuming you created a class of desired URIs as "certURIs"):when HTTP_REQUEST { if { [matchclass [HTTP::uri] starts_with $::certURIs] } { SSL::authenticate always SSL::authenticate depth 9 SSL::cert mode require SSL::renegotiate } }
Which is distilled from this earlier post where a community member got a slightly more involved version of the above working: Click here
HTH,
Colin - Ron_Kim_110696
Nimbostratus
Thanks Colin.
Questions:
Will the below work?
Do we need to initialize the variables in the beginning of the rule?
What happens if a hacker inserted his own HTTP header insterts?
Where and how would I add the ability to check for "[X509::verify_cert_error_string" and do a redirect if there is an error?
===================================
class certURIs {
"/uri1/"
"/uri2/"
"/uri3/"
"/uri4/"
}
===================================
when HTTP_REQUEST {
if { [matchclass [HTTP::uri] starts_with $::certURIs] } {
SSL::authenticate always
why not 'SSL::autenticate once' ??
SSL::authenticate depth 9
SSL::cert mode request
SSL::renegotiate
}
}
when CLIENTSSL_CLIENTCERT {
set cert [SSL::cert 0]
set sn [X509::serial_number $cert]
set subject [X509::subject $cert]
set issuer [X509::issuer $cert]
set version [X509::version $cert]
session add uie [SSL::sessionid] [list $sn $issuer $subject $version] 1800
log local0. "in SSLid_F5 [SSL::sessionid]"
}
when HTTP_REQUEST {
set values [session lookup uie [SSL::sessionid] ]
if { [lindex $values 0] != "" } {
HTTP::header insert ClientSSL_Serial_F5 [lindex $values 0]
log local0. "in inserting Serial_F5 [lindex $values 0]"
HTTP::header insert ClientSSL_Issuer_F5 [lindex $values 1]
log local0. "in inserting Issuer_F5 [lindex $values 1]"
HTTP::header insert ClientSSL_Subject_F5 [lindex $values 2]
log local0. "in inserting Subject_F5 [lindex $values 2]"
HTTP::header insert Version_F5 [lindex $values 3]
log local0. "in inserting Version_F5 [lindex $values 3]"
}
} - Ron_Kim_110696
Nimbostratus
High Level Goals of the iRule for a virtual server with HTTPS are:
- Examine URI
- Request Client SSL Cert
- Insert Client SSL Cert info into the HTTP Headers sent to the web server.
Attached is a image of a flow chart of what we are trying to achieve.
If we want to parse the client requested URI, would it be better to use "CLIENTSSL_HANDSHAKE" in addition to "CLIENTSSL_CLIENTCERT"?
Or do we need two iRules? - kolejarz
Nimbostratus
There is a sample irule from F5 support:when CLIENTSSL_CLIENTCERT { HTTP::release if { [SSL::cert count] < 1 } { reject } } when HTTP_REQUEST { if { [matchclass [HTTP::uri] starts_with $::requires_client_cert] } { if { [SSL::cert count] <= 0 } { HTTP::collect SSL::authenticate always SSL::authenticate depth 9 SSL::cert mode require SSL::renegotiate } } } when HTTP_REQUEST_SEND { clientside { if { [SSL::cert count] > 0 } { HTTP::header insert "X-SSL-Session-ID" [SSL::sessionid] HTTP::header insert "X-SSL-Client-Cert-Status" [X509::verify_cert_error_string [SSL::verify_result]] HTTP::header insert "X-SSL-Client-Cert-Subject" [X509::subject [SSL::cert 0]] HTTP::header insert "X-SSL-Client-Cert-Issuer" [X509::issuer [SSL::cert 0]] } } }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects
