For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Mate_132781's avatar
Mate_132781
Icon for Cirrostratus rankCirrostratus
Sep 12, 2014

SSL Proxy with sending data to 3rd party security device for inspection

Hi,

 

we have request to implement 3rd party security device (sandbox) for traffic inspection but problem is that traffic is SSL encrypted and we must use direct client-server SSL encryption (SSL session must be terminated between client and server, without reencryption).

 

Is there any possibility to use BIG-IP to decrypt traffic, send it unencrypted to 3rd party security device and returned traffic from security device encrypt again and send it to server? SSL encryption need to be end-to-end between server and client. Feature that enables view to encrypted data without SSL termination is Proxy SSL but, is there any possibility to send decrypted traffic to 3rd party device for inspection?

 

Please look picture for clearance:

 

 

1 Reply

  • Yes...but...it's not the easiest thing in the world to do. The primary issues here are that:

    1. ProxySSL only works within the confines of a single VIP and its corresponding client and server SSL profiles, so there's a very small layer 7 window where data is in the clear text, and that is only in memory.

    2. There are no iRule events (other than layer 4 TCP) that get triggered below layer 7 when using proxySSL, so to use an iRule you're going to be limited to the set of available layer 7 events. In most cases you're going to be passing HTTP data, so all is not lost.

    3. A clone pool won't work here either because it simply mirrors the whole port, which is encrypted below layer 7.

    So, frightfully, you're left with an iRule that grabs HTTP data (request and response headers and payload) and sprays that to an external source via sideband call. And by virtue of the need to get a response, that remote source should be another VIP that "reflects" some data back to its source. Here's what the "intercept" iRule might look like:

    proc send_to_sideband { data server } {
         this is the sideband processing procedure (function)
    
         send the sideband request
        send -status send_status -timeout 100 $sbserver $data
    
         return the sideband response
        return [recv -status recv_status -timeout 300 $sbserver]
    }
    when RULE_INIT {
         user-defined: IPSFUNC = enabled if this is an IPS function (possible value: 1 = yes, 0 or blank = no)
        set static::IPSFUNC 1
    
         user-defined: BADRESPONSE = HTML content to display if IPS blocks request/response
        set static::BADRESPONSE "ForbiddenThis content has been blocked"
    
         user-defined: REFLECTORRESPONSE = the expected (good) response from the reflector VIP
        set static::REFLECTORRESPONSE "HTTP/1.0 204 OK\r\n\r\n"
    
         user-defined: SBSERVER = IP:port of the reflector VIP
        set static::SBSERVER "11.11.11.12%1:8888"
    }
    when HTTP_REQUEST {
         remove the Accept-Encoding header from the request to prevent sever from compression response
        HTTP::header remove Accept-Encoding
    
         inject source and destination headers into sideband data
        set CIXFFS [IP::client_addr]
        set CIXFFD [IP::local_addr]
        set mapfrom "user-agent"
        set mapto "CIXFFS: $CIXFFS\r\nCIXFFD: $CIXFFD\r\nUser-Agent"
        set req [string map -nocase [list $mapfrom $mapto] [HTTP::request]]
    
        if { [HTTP::payload] eq "" } {
             if this a request with no payload (usually a GET request), initiate the sideband process here
            set sb [call send_to_sideband $req $static::SBSERVER]
    
             if this is an IPS function and the sideband does not return the correct response, generate error response, else ignore the sideband response
            if { ( $static::IPSFUNC ) and ( $sb ne $static::REFLECTORRESPONSE ) } {          HTTP::respond 200 content $static::BADRESPONSE }
        } else {
             if this is a request with payload (usually a POST request), collect the payload and trigger the HTTP_REQUEST_DATA event
            HTTP::collect [HTTP::header Content-Length]
        }
    }
    when HTTP_REQUEST_DATA {
         call the sideband proc
        set sb [call send_to_sideband "${req}[HTTP::payload]" $static::SBSERVER]
    
         if this is an IPS function and the sideband does not return the correct response, generate error response, else ignore the sideband response
        if { ( $static::IPSFUNC ) and ( $sb ne $static::REFLECTORRESPONSE ) } { HTTP::respond 200 content $static::BADRESPONSE }
    }
    when HTTP_RESPONSE {
         all responses will have a payload, so collect the payload and trigger the HTTP_RESPONSE_DATA event
        if { [HTTP::header exists Content-Length] } {
            HTTP::collect [HTTP::header Content-Length]
        }
    }
    when HTTP_RESPONSE_DATA {
         compile the components of the HTTP response (version, status)
        set version [HTTP::version]
        set status "[HTTP::status]\r\n"
    
         build a string of response headers
        foreach x [HTTP::header names] {
            append hdr "$x: [HTTP::header $x]\r\n"
        }
    
         add source and destination address headers
        append hdr "CIXFFS: $CIXFFS\r\n"
        append hdr "CIXFFD: $CIXFFD\r\n"
    
         call the sideband proc with the combined response data
        set sb [call send_to_sideband "HTTP/$version $status$hdr\r\n[HTTP::payload]" $static::SBSERVER]
    
         if this is an IPS function and the sideband does not return the correct response, generate error response, else ignore the sideband response
        if { ( $static::IPSFUNC ) and ( $sb ne $static::REFLECTORRESPONSE ) } { HTTP::respond 200 content $static::BADRESPONSE }
    }
    

    And the VIP that it points to, the "reflector" VIP:

    when CLIENT_ACCEPTED {
        TCP::respond "HTTP/1.0 204 OK\r\n\r\n"
    }
    

    Because you're basically scraping HTTP data and sidebanding it, you also lose the source and destination addresses. I take the liberty here to add them as custom headers in the data sent to the reflector VIP. I should stop at this point and caveat all of this by saying that I built this a few months ago, and well, it worked then, so...

    The reflector iRule will simply return with a 204 response. If you've set this up in "IPS" mode, the intercept iRule will block the traffic and send an error HTML page. If in "IDS" mode, it'll simply ignore the response. Whatever device you put between the intercept and reflector VIPs can simply block any bad data from getting back to the intercept VIP.

    Which brings me to the next point:

    set static::SBSERVER "11.11.11.12%1:8888"
    

    In order to get traffic to leave the device, you need to employ at least one route domain. Here's a basic configuration (modify as required):

    1. Connect external traffic line to 1.1

    2. Insert a cable between 1.2 and 1.3

    3. Optionally connect internal traffic line to 1.4

    4. Create the external (and optionally internal) VLAN(s) for normal application traffic.

    5. Create a second VLAN for interface 1.2 (ex. “to-sideband-vlan”)

    6. Create a third VLAN for interface 1.3 (ex. “sideband-vlan”)

    7. Create a single route domain (ex. 1) and bind it to the sideband VLAN (ex. 1.3)

    8. Create a self-IP for the external VLAN and optionally the internal VLAN (ex. 10.80.0.50).

    9. Create a self-IP for the sideband VLAN (ex. 11.11.11.11%1)

    10. Create a self-IP for the “to-sideband” VLAN on the same network as the sideband, but without the route domain (ex. 11.11.11.10)

    11. Create the intercept iRule

    12. Create the reflector IRule

    13. Create the reflector virtual server

      Destination IP on route domain 1 (ex. 11.11.11.12%1)
      Destination port (ex. 8888)
      Enabled on sideband VLAN
      Reflector iRule
      
    14. Create a sideband pool that points to the sideband virtual server, but without the route domain designator (ex. 11.11.11.12:8888)

    15. Create the sideband (intermediate) virtual server

      Destination IP
      Destination port
      Sideband pool (step 4)
      

    Yes, I know it's ugly and complicated, but ProxySSL imposes some unforgivable limitations here. And this is just one solution that I've been able to make work. Your mileage may vary.