Forum Discussion

LyonsG_85618's avatar
LyonsG_85618
Icon for Cirrostratus rankCirrostratus
Nov 16, 2012

Passing decoded certficates in HTTP header

Hi folks.

 

 

I have been requested to setup BIG-IP to request certificate authentication and then insert the WHOLE UNENCODED certificate into the HTTP header and pass it to a differnt virtual server.

 

I have trawled the forum already but can't find the resolution anywhere.

 

 

The IRULE I have set-up at present is:

 

 

 

First check to see whether cert is present then validate it

 

 

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]] }

 

Check if the certificate contains valid CN

 

if { ($subject_dn contains "CN=Company A") or ($subject_dn contains "CN=Company B")} {

 

Accept the client cert

 

log "Client Certificate Accepted:$subject_dn [X509::whole $ssl_cert]"

 

} else {

 

log "No Matching Client Certificate Was Found Using: $subject_dn"

 

reject

 

}

 

}

 

 

Then re-write and pass to a different VIP

 

 

when HTTP_REQUEST {

 

set requestedhost [string tolower [HTTP::host]]

 

set requestedURI [HTTP::uri]

 

 

if { $requestedhost equals "string1.domainA.com"} {

 

HTTP::header replace Host "string2.domainA.com"

 

HTTP::header insert "X509Certificate" [X509::whole [b64decode [SSL::cert 0]]]

 

virtual VS_SYST_SOA_EXTERNAL_LIVE_HTTPS

 

}

 

}

 

 

Any help or suggestions would be gratefully received.

 

Thanks

 

 

Graham

 

15 Replies

  • Hi Graham,

     

     

    That $WSCC value in the trace log is base64 encoded. You could do this in an iRule using:

     

     

    HTTP::header insert \$WSCC [b64encode [SSL::cert 0]]

     

     

    Also, I suggest editing your post so you don't leave a copy of a copy of that client cert here :).

     

     

    Aaron
  • Thanks Aaron!

     

     

    The application team are now getting the certificate ok.

     

    They have changed their requirements (again) and now want the request content sent via a cookie.....

     

     

    To the search button i go....

     

     

    Many thanks for all the help on this. Cheers

     

  • HTTP::cookie insert name "BIGIPCOOKIE" value [HTTP::payload]

     

     

    Can anyone see a problem with doing this?
  • now want the request content sent via a cookie.....what does the request content mean? is it http request headers (GET request does not have payload)?

    ---------------

    The value of a cookie may consist of any printable ascii character (! through ~, unicode \u0021 through \u007E) excluding , and ; and excluding whitespace. The name of the cookie also excludes = as that is the delimiter between the name and value. The cookie standard RFC2965 is more limiting but not implemented by browsers.

    ---------------

    HTTP cookie

    http://en.wikipedia.org/wiki/HTTP_cookie

    will you do base64 encoding of http request headers?

    e.g.

    [root@ve10:Active] config  b virtual bar list
    virtual bar {
       destination 172.28.19.79:80
       ip protocol 6
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve10:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
       HTTP::cookie insert name BIGIPCOOKIE value [b64encode [HTTP::request]]
       virtual backend_vs
    }
    }
    [root@ve10:Active] config  b virtual backend_vs list
    virtual backend_vs {
       snat automap
       pool foo
       destination 1.1.1.1:80
       ip protocol 6
       rules backend_rule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve10:Active] config  b rule backend_rule list
    rule backend_rule {
       when HTTP_REQUEST {
       log local0. [b64decode [HTTP::cookie value BIGIPCOOKIE]]
    }
    }
    
    [root@ve10:Active] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.20.11(44909) <-> 172.28.19.79(80)
    1354270186.3077 (0.0030)  C>S
    ---------------------------------------------------------------
    GET /something HTTP/1.1
    User-Agent: curl/7.19.7 (i686-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8x zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: test.com
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 172.28.20.11(44909) <-> 1.1.1.1(80)
    1354270186.3078 (0.0000)  C>S
    ---------------------------------------------------------------
    GET /something HTTP/1.1
    User-Agent: curl/7.19.7 (i686-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8x zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: test.com
    Cookie: BIGIPCOOKIE=R0VUIC9zb21ldGhpbmcgSFRUUC8xLjENClVzZXItQWdlbnQ6IGN1cmwvNy4xOS43IChpNjg2LXJlZGhhdC1saW51eC1nbnUpIGxpYmN1cmwvNy4xOS43IE9wZW5TU0wvMC45Ljh4IHpsaWIvMS4yLjMgbGliaWRuLzAuNi41DQpBY2NlcHQ6ICovKg0KSG9zdDogdGVzdC5jb20NCg0K;
    
    ---------------------------------------------------------------
    
    [root@ve10:Active] config  cat /var/log/ltm
    Nov 30 18:14:12 local/tmm info tmm[7926]: Rule backend_rule : GET /something HTTP/1.1  User-Agent: curl/7.19.7 (i686-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8x zlib/1.2.3 libidn/0.6.5  Accept: */*  Host: test.com
    
    
  • The customer now needs the entire payload passed therough in the cookie.

     

     

    I have searched forums and comup with the following:

     

     

    However - it would appear that payload is still not being seen.

     

     

    Any ideas?

     

     

    when HTTP_REQUEST {

     

    set requestedhost [string tolower [HTTP::host]]

     

    set requestedURI [HTTP::uri]

     

     

    Collect up to the first 1MB of POST data

     

    log local0. "Checking post method [HTTP::method] uri: [HTTP::uri] http_version: [HTTP::version] IP: [IP::client_addr]"

     

    log local0. "Headers: [HTTP::request]"

     

    log local0. "Payload [HTTP::payload]"

     

     

    if {[HTTP::method] eq "POST"}{

     

     

    Check if there is a content-length header and the value is set to less than 1Mb

     

    if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{

     

    set clength [HTTP::header "Content-Length"]

     

    } else {

     

    set clength 1048576

     

    }

     

    log local0. "Checking content length $clength IP: [IP::client_addr]"

     

    if { $clength > 0} {

     

    if {$debug}{log local0. "[virtual name]: Collecting $clength bytes IP: [IP::client_addr]"}

     

    HTTP::collect [HTTP::header "Content-Length"]

     

    log local0. "[HTTP::payload]"

     

    }

     

     

     

    if { $requestedhost equals "oldname.companyname.com"} {

     

    HTTP::header replace Host "newname.companyname.com"

     

    HTTP::header insert "\$WSCC" [X509::whole [SSL::cert 0]]

     

    HTTP::cookie insert name "BIGIPCOOKIE" value [HTTP::payload]

     

    pool POOL_A_HTTPS

     

    log local0. "after cookie payload=[HTTP::payload] host=[HTTP::host] uri=[HTTP::uri] cert[X509::whole [SSL::cert 0]]"

     

    }