Forum Discussion

Stephan_Manthey's avatar
Stephan_Manthey
Historic F5 Account
Nov 14, 2004

irule to insert a client-cert into a proxy-request

we want to use the big-ip to act as a

 

https-proxy that inserts a client-cert

 

to request a server via another proxy.

 

can this be solved by in irule?

 

the issue here from my perspective is

 

the initial session setup between the

 

client and a proxy if using https. by

 

"connect" (in clear text) the client

 

tells where it wants to be connected

 

to.

 

its different from the usual procedure

 

in a direct communication between a

 

client and a server. there the rsa-

 

handshake happens first. from that

 

point everything is encrypted.

 

thanks in advance.

 

stephan

 

  • gomes_127447's avatar
    gomes_127447
    Historic F5 Account
    Why not use a serverssl profile to handle the encrypted connection between the BIG-IP and the Proxy server?
  • gomes_127447's avatar
    gomes_127447
    Historic F5 Account
    does it fail on the SSL level? If so you need a valid signed certificate on the BIG-IP.

     

     

    Or is the problem because you are not re-writting the http requests in a format that an HTTP proxy server can understand?

     

     

    What does your iRule look like?
  • Stephan_Manthey's avatar
    Stephan_Manthey
    Historic F5 Account
    for auth on the destination-proxy a valid

     

    client cert in pem-format and a passphrase

     

    are required.

     

    both are configured on the server-side

     

    ssl-profile.

     

    i dont have access to the destination-proxy/

     

    server and the private key because its a 3rd

     

    party institution.

     

    thats why i cant use ssldump to monitor

     

    whats happening inside the server-side session.

     

    pls correct me if i am wrong at this point.

     

    the virtual server on the big-ip has to

     

    accept encrypted and un-encrypted data,

     

    because the session-setup starts with a

     

    cleartext "connect". so the irule described

     

    in this forum needs to be enhanced by a

     

    "connect" method.
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    We have had a hard time figuring out exactly what you are trying to solve. So, I suggest we try to break apart the problem into some smaller pieces.

    So, let's first discuss the proxy part of this. I think that you are asking for help on writing a rule that parses the "connect" of a proxy-tunneled ssl request. The format of this type of request is:

    connect HTTP/1.0

    User-Agent: foo

    So, the rule must first parse the proxy connect header, before passing the request on to the SSL layer. In this example, we always terminate uri requests to port 443 but not other ports. This can additionally be modified to pass encrypted data through to the node depending on the uri (see the SSL::disable command which disables SSL termination and/or re-encryption).

           
           rule proxy-connect {       
              when CLIENT_ACCEPTED {       
                 set proxied 0       
                 TCP::collect       
              }       
              when CLIENT_DATA {       
                 binary scan [TCP::payload] a* request       
                 set req_len [string first "\r\n\r\n" $request]       
                 if { $req_len == -1 } {       
                     Couldn't find the complete request, must not have it all yet       
                    TCP::collect       
                    return       
                 }       
                  include the closing  in the request length      
                 set request [string range $request 0 $req_len]       
                 incr req_len 4       
                  
                  Save the URI, port, version and headers       
                 if { not [regexp -nocase "^CONNECT (.+)(?::(\d+)) (HTTP/1\.[01])\r?\n(.*)$" $request -> uri port version headers] } {       
                     Not a proxy connect request, just release the data       
                     (could also reject the connection here using "reject")       
                    TCP::release       
                    return       
                 }       
                  
                 if { $port != 443 } {       
                     Don't SSL terminate connect requests to non-443 ports       
                    SSL::disable       
                 }       
                  
                  Remember that we found a "CONNECT" request       
                 set proxied 1       
                  
                  Remove the connect request header       
                 TCP::payload replace 0 $req_len {}       
                       
                  If name resolution is needed on the uri use the NAME::lookup cmd like so:       
                 NAME::lookup [URI::host $uri]       
              }       
              when NAME_RESOLVED {       
                  Use the resolved uri's address       
                 node [NAME::response] $port       
                 TCP::release       
              }       
              when SERVER_CONNECTED {       
                 if { $proxied } {       
                    clientside { TCP::respond "$version 200 Connection Established\r\nProxy-Agent: BigIP v9\r\n\r\n" }       
                 }       
              }       
           }       
           

    Note: this rule has not be tested.