Forum Discussion

swarnim_131291's avatar
swarnim_131291
Icon for Nimbostratus rankNimbostratus
Aug 08, 2013

Modifying HTTP header on the basis of SSL certificate

Hello,

 

So this is what my use case looks like. I am building a service to which users can upload their files via cURL. The service is load balanced by F5. In order to authenticate themselves, users provide a signed certificate while uploading. I would like to do two things in F5:

 

1. Do a validation of the certificate presented by the client.

 

2. Once validated, extract some custom fields from the certificate and send them to my web service embedded within the HTTP header.

 

With my initial research, I feel like an iRule should be a good way to achieve this, atleast do the modification of the HTTP header and add fields to it. Any suggestions/hints on how that can be done would be highly appreciated. I am a very newbie to F5.

 

Thanks in advance,

 

 

3 Replies

  • 1. This depends on what you mean by validation. The client SSL profile is going to provide some preliminary validation (trust chain, expiration, etc.), but anything beyond that (OCSP, CRLDP) is going to require the Access Policy Manager (APM) module. You can, however, insert a static CRL into the client SSL profile for local revocation checking.

    2. Take a look at the X509:: wiki page (https://devcentral.f5.com/wiki/iRules.X509.ashx). Once you've terminated SSL and received the client certificate, the X509 values of that certificate will be available via a set of X509:: commands. You can them simply insert those values into HTTP headers.

    *Crude* example:

    
    when HTTP_REQUEST {
        if { [SSL::cert count] > 0 } {
            HTTP::header insert CERTSUBJECT [X509::subject [SSL::cert 0]]
        }
    }
    

  • This is better!

    when CLIENTSSL_CLIENTCERT {  
      set debug 0
    
       Check if client provided a cert  
        if {[SSL::cert 0] eq ""}{  
          Reset the connection if no cert present 
             reject 
        } else {  
          Example Subject DN:  /C=AU/ST=NSW/L=Syd/O=Your Organisation/OU=Your OU/CN=John Smith  
           set ssl_cert [SSL::cert 0]    
           set subject_dn [X509::subject [SSL::cert 0]]}
           set issuer [X509::issuer $ssl_cert]   
             Check if the certificate contains valid CN 
           if { ($issuer contains "Origo Root CA - G2M")  or ($issuer contains "OSIS Customer CA")} {  
              Accept the client cert  
              log "Client Certificate Accepted:$issuer" 
           } else {  
              log "No Matching Client Certificate Was Found Using: Cert issuer - [X509::issuer $ssl_cert]" 
                 reject  
                   }
            }
    
     Then re-write HOST name
    
    when HTTP_REQUEST {  
        set requestedhost [string tolower [HTTP::host]]
        set requestedURI [HTTP::uri]
        set content_length [HTTP::header "Content-Length"]
        set method [HTTP::method]
    
           log "ip address=[IP::client_addr] before cookie HTTP method=$method host=$requestedhost uri=$requestedURI payload=[HTTP::payload] content length=$content_length"
        if { $requestedhost equals "test1.domain.com"} {
            HTTP::header replace Host "test2.newdomain.com"
            HTTP::header insert "CIACertHeader" [X509::whole  [SSL::cert 0]]
        HTTP::cookie insert name "BIGIPCOOKIE" value BIGIPTEST
        virtual VIRTUAL_SERVER_HTTPS                        
               log local0. "after cookie cookie host=[HTTP::host] uri=[HTTP::uri]  cert[X509::whole [SSL::cert 0]] "
      }
    }