Forum Discussion
Remco
Nimbostratus
Nov 03, 2011Redirecting http request to external url via proxy
Hi,
we are using F5 load balancers for our Internet environment. There is now a requirement during customer login to download a trojan detection script at an external company. But for the client point of view this script should be hosted from our own domain otherwise personal firewalls will block this script.
The plan is to create a pool an add this external website as a poolmember and have the F5 based on a specific URI to rewrite the URL to the external website and using SNAT to get the external script.
The problem is we are now doing a POC in our DTA environment but here the F5 does not have a direct Internet connection. The only option is to go via our browser proxies.
So I have created a pool wiht the proxy as a member and are using TCP 8080, redirecting normal HTTP traffic via the proxy is working, but the website hosting the external script is running on HTTPS.
The problem is that the proxy for HTTPS traffic is expecting a HTTP CONNECT request instead of a GET which is standard used for HTTP.
Is there anyway to change the HTTP method on the F5 from GET to CONNECT?
I know you can read the method via HTTP::method but I have not found an option to actually change the method to CONNECT.
Regards,
Remco
22 Replies
- Hamish
Cirrocumulus
Hmm... You're wanting the LTM to be an HTTP client to a proxy...
OOTB this isn't going to happen. Hwoever you should be able to get something up & running with an iRule. But at first glance, it's not going to be terribly simple one as the iRule is going to have to negotiate a TLS/SSL connection on the fly after the CONNECT (The SMTPTLS iRule shows how this can be done on the client side, it should be possible to manipulate the iRule to doit on the server side instead).
Do your proxies have a transparent option?
H - Remco
Nimbostratus
Hi Hamish,
I think setting up the F5 to be a SSL client shouldn't be a problem, this should be accomplished by using a standard serverssl profile without any key or certificate specified. The F5 should than act as an client in the SSL handshake.
Since we already use an iRule to select the pool based on the URI, I can disable ssl for all other URI's in the irule.
The proxies have been setup in transparent mode for SSL traffic, so they should not be involved in the SSL process. I think my biggest problem is getting the F5 to use a HTTP CONNECT method instead of the standard GET. - The proxies have been setup in transparent mode for SSL traffic, so they should not be involved in the SSL process. I think my biggest problem is getting the F5 to use a HTTP CONNECT method instead of the standard GET.
If the proxies really do work in transparent mode for SSL you won't need the CONNECT method. CONNECT is only used by HTTP clients when they know about the proxy. In transparent mode the clients don't know there is a proxy and they will just try to connect directly to the target, by issuing a tcp connection to server:443.
So, your ssl server profile should work out of the box.
Let's assume the SSL connection works, then you still need to do this:
1.) Rewrite the URI to the location of the script "[HTTP::uri]"
2.) Rewrite the HOST header "[HTTP::header Host] replace", otherwise the target server might not accept the request.
Regards
Kurt Knochner - nitass
Employee
not sure if i understand correctly. this is my testing.[root@iris:Active] config b virtual bar list virtual bar { snat automap pool squid destination 172.28.17.33:https ip protocol tcp rules myrule } [root@iris:Active] config b pool squid list pool squid { members 192.168.12.105:squid {} } [root@iris:Active] config b rule myrule list rule myrule { when SERVER_CONNECTED { set bypass 0 TCP::respond "CONNECT www.google.com:443 HTTP/1.0\r\n\r\n" TCP::collect } when SERVER_DATA { if { $bypass eq 1 } { TCP::release return } if { [TCP::payload] starts_with "HTTP/1.0 200" } { TCP::payload replace 0 [TCP::payload length] "" TCP::release set bypass 1 } else { TCP::close } } } [root@iris:Active] config curl -Ik https://172.28.17.33/ HTTP/1.1 200 OK Date: Fri, 04 Nov 2011 09:18:10 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Transfer-Encoding: chunked - nitass
Employee
sorry i forgot to put the reference.
Virtual_to_enable_proxy-unaware_applications_to_make_outbound_TCP_connections_via_a_HTTP_CONNECT_method by kozlowc - kozlowc at ms.com
http://devcentral.f5.com/wiki/iRules.Virtual_to_enable_proxy-unaware_applications_to_make_outbound_TCP_connections_via_a_HTTP_CONNECT_method.ashx - "TCP::respond" to send the CONNECT command. Very nice. Thanks for that one!!
Now, to enable SSL using a server ssl profile, just use ssl:disable and ssl:enable at the right moment (samples are available on devcentral) and it would be possible to create what Remco was asking for, at least as I understood it:
Client --- HTTP --- LB --- HTTPS ---- Proxy:8080 --- HTTPS ---Server
However that's not even necessary if the clients are using SSL themselves. The SSL handshake would then take place between the clients and the HTTPS servers directly (as shown with your curl example).
Client --- HTTPS --- LB --- HTTPS ---- Proxy:8080 --- HTTPS ---Server
Regards
Kurt Knochner - Remco
Nimbostratus
sorry site was not responding, my message was posted multiple times
- Remco
Nimbostratus
sorry site was not responding, my message was posted multiple times
- Remco
Nimbostratus
I have managed to indeed get the CONNECT message towards the proxy and getting the 200 OK reply indicating the proxy is in SSL transparent mode.
My next challenge is getting the F5 to start the ssl handsake with the target web-server.
Our challenge is exaclty a little bit more complicated than described in the last post. I will try to explain what we are trying to do.
For our main domain the F5 is setup to do SSL offloading, so the client SSL connection is termintated on the F5. A iRule is than used to load balance to different application pools based on the URI requested. For all normal pools no SSL is used.
One URI is used to download a java script for trojan detection on the client PC, so the F5 should do the following task when the URI is matching in the HTTP_REQUEST event:
1. change the host to the URL of the external company providing the script (rewrite HTTP host header)
2. remove specific application session cookie (cookie remove)
3. send CONNECT message to proxy pool to tell proxy SSL session is coming up
4. start SSL handsake with external website.
5. reply of external website should be directed back to the orginal client requesting the uri.
I have been trying to use the suggested iRule in combination with the already configured HTTP_REQUEST event but no success yet.
In the SERVER_CONNECTED event I have disabled SSL SSL::disable to have the CONNECT message send as normal TCP traffic. But the problem is once the 200 OK has been received from the proxy SSL should be enabled again and the HTTP request with the change host should be send to the proxy.
I am struggling in finding the correct spot to enable SSL again.
In a tcpdump I did, it looks like the F5 is sending the rewritten HTTP request immediatly after the CONNECT message before the SSL handsake is started. Causing the proxy to reply with a 400 bad request message. - nitass
Employee
not sure if it is what you are looking for. anyway, hope it is helpful.[root@ve1023:Active] config b virtual bar list virtual bar { snat automap pool foo destination 172.28.65.152:https ip protocol tcp rules myrule profiles { clientssl { clientside } http {} serverssl { serverside } tcp {} } } [root@ve1023:Active] config b pool foo list pool foo { members 200.200.200.101:http {} } [root@ve1023:Active] config b rule myrule list rule myrule { when CLIENT_ACCEPTED { SSL::disable serverside } when HTTP_REQUEST { if {[HTTP::uri] equals "/test"} { HTTP::uri "/" SSL::enable serverside virtual bar2 } } } [root@ve1023:Active] config b virtual bar2 list virtual bar2 { snat automap pool squid destination 1.1.1.1:https ip protocol tcp rules myrule2 } [root@ve1023:Active] config b pool squid list pool squid { members 192.168.12.105:squid {} } [root@ve1023:Active] config b rule myrule2 list rule myrule2 { when SERVER_CONNECTED { set bypass 0 TCP::respond "CONNECT www.google.com:443 HTTP/1.0\r\n\r\n" TCP::collect } when SERVER_DATA { if { $bypass eq 1 } { TCP::release return } if { [TCP::payload] starts_with "HTTP/1.0 200" } { TCP::payload replace 0 [TCP::payload length] "" TCP::release set bypass 1 } else { TCP::close } } }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
