Cert Information in your HTTP Headers
SSL is everywhere. In your browser, in your email client, in your auth setup; the chances are, if you're using the internet today, you're going to run across something, somewhere that invokes an SSL cert for encryption or authentication. This is a common theme we've seen progressing for some time now. I've written about it multiple times here on DevCentral, and it's not news anywhere else, either.
With all widely adopted security measures there are technological hurdles to get over. With SSL we've dealt with issues from performance to management to information obfuscation. Today I'm going to give you a hand with the latter of those: information obfuscation. The many, many pros of using SSL in these fashions aside, there are a few cons, or at least areas that need to be addressed to maintain the desired functionality in your deployment. One such issue is getting the needed SSL data to the back-end servers. This is pretty straight-forward if you've got a basic setup with no offloading being done, but it gets a little more complex if you have a device like the BIG-IP that is able to offload the SSL transactions from your back-end servers to improve your performance.
In the case that you are offloading the SSL processing, the SSL information (I.E. the cert information itself) is not readily available to the back-end servers after the fact. This is problematic in some situations. Perhaps you want to log the info for statistical tracking. More importantly, maybe you're using that information somewhere in your application for access restriction or even user authentication/tracking. Not having that data presents a serious issue in these cases, but the need for SSL offloading for the sake of performance is still present. In this situation there often times has to be a trade-off of functionality vs. performance. Luckily, if you're using a BIG-IP, you've got iRules on your side, so you get to have both.
The below example SSL auth iRule inspects the presented certificate when it is delivered and stores the desired information (in this case the Serial Number, Subject, Issuer and Version) in variables which are then loaded into the BIG-IP's session table. This intermediate step is done to work-around the fact that currently the local variables aren't able to pass data between this particular SSL event and the standard HTTP events, though this may not always be the case. As you can see, the information is stored in the CLIENTSSL_CLIENTCERT event, then later retrieved in the HTTP_REQUEST event where it is then stored in custom HTTP headers. The back-end systems then read in those header values and you no longer have to worry about losing the relevant cert data to gain the improved performance of offloading your SSL processing.
It's worth noting, also, that because we're dealing with iRules we don't have to just address one desire or issue at a time with our code. This example also does a little resiliency enforcement by checking to ensure that there was indeed a cert presented before it tries to push in the HTTP headers and send the request on its way. If there was no cert presented, it will renegotiate the SSL transaction to give the client the opportunity to do so. This could easily be expanded to only request authentication on certain portions of your site, or only from certain users, etc. With iRules the power to truly customize is in your hands.
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 } when HTTP_REQUEST { if { [SSL::cert count] < 1 } { SSL::authenticate once SSL::authenticate depth 9 SSL::cert mode request SSL::renegotiate } else { set values [session lookup uie [SSL::sessionid] ] if { [lindex $values 0] != "" } { HTTP::header insert XClientSSL_Serial [lindex $values 0] log local0. "Inserting Serial [lindex $values 0]" HTTP::header insert XClientSSL_Issuer [lindex $values 1] log local0. "Inserting Issuer [lindex $values 1]" HTTP::header insert XClientSSL_Subject [lindex $values 2] log local0. "Inserting Subject [lindex $values 2]" HTTP::header insert XVersion [lindex $values 3] log local0. "Inserting Version [lindex $values 3]" } } }
So there you have it, SSL offloading for performance, SSL renegotiation for resiliency and SSL information gathering via HTTP headers for tracking or application logic, whatever the case may be. Take a look at the X509 page in the iRules wiki as well to see all the different pieces of SSL information you have access to via iRules. This is just one example, exploring the possibilities is up to you.