Forum Discussion

Christopher_J_B's avatar
Christopher_J_B
Icon for Nimbostratus rankNimbostratus
Sep 24, 2010

Is it possible to collect HTTP payload information with SSL/Client side enabled on the VIP?

I am creating iRules to parse HTTP Post requests/XML pulling web services call, information, etc.. The method I am using to collect/parse the HTTP payload is not working with SSL termination on the F5 (SSL Profile/Client enabled).

 

 

Is it possible? If so which event should I use?

 

 

For non-SSL terminate connections using HTTP_REQUEST_DATA using a HTTP:payload function

 

 

Here are snippets of the configuration of the VIP

 

 

virtual sandapcspapl-ssl-vip {

 

snat automap

 

pool sandapcspapl-80

 

destination 10.12.0.101:https

 

ip protocol tcp

 

rules

 

tcp_CSPRTAPL

 

xml_CSPRTAPL

 

profiles

 

http-x-forwarded-for

 

sandapcspaplv2

 

tcp

 

}

 

profile clientssl sandapcspaplv2 {

 

defaults from clientssl

 

key "sandapcspaplv2.key"

 

cert "sandapcspaplv2.crt"

 

}

 

 

3 Replies

  • You should be able to use HTTP::collect and HTTP::payload with a virtual server that accepts encrypted SSL traffic and decrypts it with a client SSL profile. The HTTP related iRule functionality should work the same with a client SSL profile and encrypted traffic as unencrypted traffic without a client SSL profile.

     

     

    Can you post the iRule(s) you're testing and more detail of what you're trying to accomplish versus what's happening?

     

     

    Thanks, Aaron
  • I have 2x VIP - one SSL terminated and the other not. The iRule is the same for both VIP - all traffic that is dest'd to the non-SSL VIP works - SSL nada

     

    when HTTP_REQUEST {

     

     

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

     

    event disable all

     

    return

     

    }

     

    if { (not [HTTP::header exists "Content-Length"]) or ([HTTP::header "Transfer-Encoding"] contains "chunked") } {

     

    event HTTP_REQUEST disable

     

    event HTTP_REQUEST_DATA disable

     

    event HTTP_RESPONSE disable

     

    } else {

     

    set http_request_time [clock clicks -milliseconds]

     

    set uri [HTTP::uri]

     

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

     

    }

     

    }

     

    when HTTP_REQUEST_DATA {

     

     

    if { [HTTP::uri] contains "csp-authentication" } {

     

    set id [findstr [HTTP::payload] "systemId>" 9 " if {$id contains "IVR"} {

     

    set call [string trim [findstr [HTTP::payload] "" 20 "xmlns="]]

     

    set output "CALL=$call SYSID=$id"

     

    } elseif {$id contains "MYCRICKET"} {

     

    set call [findstr [HTTP::payload] " set output "CALL=$call SYSID=$id"

     

    } else {

     

    set output "SYSID=$id"

     

    }

     

    } elseif { [HTTP::uri] contains "csp-apl" } {

     

    if { [matchclass [IP::client_addr] equals $::net_internal] }{

     

    set tmp [findstr [HTTP::payload] "<" 16 ":"]

     

    if {$tmp contains "ns1"} {

     

    set call [findstr [HTTP::payload] " set output "CALL=$call"

     

    } elseif {$tmp contains "ns0"} {

     

    set call [findstr [HTTP::payload] " } else {

     

    set output "CALL=UNKNOWN"

     

    }

     

    } else {

     

    set tmp [findstr [HTTP::payload] "" 21 ">"]

     

    set tmp [findstr [string map {" " "" "\n" ""} [HTTP::payload]] "" 21 ">"]

     

    set output "CALL=$tmp"

     

    }

     

    }

     

     

    HTTP::release

     

    }

     

    when HTTP_RESPONSE {

     

    set response "POOL=[LB::server pool] NODE=[LB::server addr] STATUS=[HTTP::status] RESPONSETIME=[expr [clock clicks -milliseconds] - $http_request_time]"

     

    }

     

    when CLIENT_CLOSED {

     

    if { [info exists output] and [info exists response] } { log -noname 10.66.48.45:514 local0.warning "DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=XML SRC=[IP::client_addr] DST=[IP::local_addr] URI=$uri $output $response" }

     

    }

     

     

    Here is a sample of working output

     

    Sep 27 13:25:19 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=TCP SRC=208.45.140.93 SRCPORT=40257 DST=10.12.0.101 DSTPORT=443 OPEN=92502

     

    Sep 27 13:25:19 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=XML SRC=208.45.140.93 DST=10.12.0.101 URI=/csp-apl/APL CALL= POOL=sandapcspapl-80 NODE=10.12.18.18 STATUS=500 RESPONSETIME=387

     

     

    Sep 27 13:25:25 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=TCP SRC=199.38.44.8 SRCPORT=53430 DST=10.12.0.101 DSTPORT=80 OPEN=614

     

    Sep 27 13:25:25 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=XML SRC=199.38.44.8 DST=10.12.0.101 URI=/csp-apl/APL CALL=getCustomerInformation POOL=sandapcspapl-80 NODE=10.12.18.16 STATUS=200 RESPONSETIME=416

     

    Sep 27 13:25:25 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=TCP SRC=199.38.44.8 SRCPORT=52511 DST=10.12.0.101 DSTPORT=80 OPEN=181

     

    Sep 27 13:25:25 10.3.0.61 tmm[1871]: DEVICE=SANPRODF5 ENV=PROD APP=CSPRTAPL COMMENT=XML SRC=199.38.44.8 DST=10.12.0.101 URI=/csp-authentication/CSPAuthenticate CALL=createSession SYSID=IVR POOL=sandapcspapl-80 NODE=10.12.18.17 STATUS=200 RESPONSETIME=31

     

     

     

     

     

  • So nothing gets logged at all when you add this iRule to a virtual server with a client SSL profile enabled? Can you add some debug logging to CLIENT_ACCEPTED to check that the TCP connection from the client to the SSL VS has been established and in HTTP_REQUEST to see whether the criteria for collecting they payload is being met?

    Also, you should add logic to prevent the iRule from trying to collect more than 4Mb of data as this will cause TMM to crash. You can check this solution for details:

    SOL6578: TMM will crash if an iRule collects more than 4MB of data

    http://support.f5.com/kb/en-us/solutions/public/6000/500/sol6578.html

    And here is an example of restricting the payload collection:

    
     From: http://devcentral.f5.com/wiki/default.aspx/iRules/CreditCardScrubber.html
    
       Only check responses that are a text content type (text/html, text/xml, text/plain, etc).
      if { [HTTP::header "Content-Type"] starts_with "text/" } {
    
         Get the content length so we can collect the data (to be processed in the HTTP_RESPONSE_DATA event)
         Limit collection to 1Mb (1048576 minus a little to spare) - See SOL6578 for details
        if { [HTTP::header exists "Content-Length"] } {
          if { [HTTP::header "Content-Length"] > 1048000 }{
             Content-Length over 1Mb so collect 1Mb
            set content_length 1048000
          } else {
             Content-Length under 1Mb so collect actual length
            set content_length [HTTP::header "Content-Length"]
          }
        } else {
           Response did not have Content-Length header, so use default of 1Mb
          set content_length 1048000
        }
         Don't collect content if Content-Length header value was 0
        if { $content_length > 0 } {
           HTTP::collect $content_length
        }
      }
    

    Aaron