Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Is there a preferred method of detecting HTTP vs. HTTPS on an incoming request to an F5 load-balancer? We are attempting to detect secure vs. non-secure with an iRule and pass a corresponding header flag along to my web servers.

Here's what we have so far (untested):

when HTTP_REQUEST_SEND {
   clientside {
      if {[TCP::local_port] == 443} {
         HTTP::header replace HTTP_X_FORWARDED_PROTO "https"
      }
      else {
         HTTP::header replace HTTP_X_FORWARDED_PROTO "http"
      }
   }
}

As you can see, we are using if {[TCP::local_port] == 443} { ... } to detect SSL, but it feels clunky with the port hard-coded into the rule. Is there a better way?

Perhaps inspecting: SSL::mode, HTTP:uri, or something else?

share|improve this question
1  
As a side node, as a service provider, you have no way to be 100% sure that your (legitimate) user is connecting via a secure connection (unless perhaps when using client-certificates too). Checking this is ultimately the sole responsibility of the client. (See this discussion for more details.) –  Bruno Jun 7 '12 at 16:17
    
Thanks for the clarification. For my situation, the purpose of detecting secure vs. nonsecure is to allow my application (which is behind a load-balancer) to perform the redirect to-and-from HTTPS. This only happens on the initial request - before authentication, and no sensitive data is being passed at that point in the HTTP post, query string, cookies, etc. I believe this mitigates the risk of a MITM attack? –  Derek Hunziker Jun 7 '12 at 18:01
    
Sure, this will mitigate the risk... provided there isn't an active MITM attacker already. What's useful with redirections is to make the user aware that you application is HTTPS-capable (so that they can expect to use it on the next visit) and possibly to turn on HSTS (so that the browser does it automatically on the next visits, if it's supported). –  Bruno Jun 9 '12 at 20:21

1 Answer 1

up vote 1 down vote accepted

What you want to detect is whether the connection is using a Client SSL profile. The DevCentral page for PROFILE::exists shows how to do this:

when CLIENT_ACCEPTED {
   if { [PROFILE::exists clientssl] == 1} {
      log local0. "client SSL profile enabled on virtual server"
   }
}

Oliver

share|improve this answer
    
Thanks, that worked, but I had to change the event to HTTP_REQUEST. It appeared that PROFILE::exists was not available under that event context. I've posted a related question here: serverfault.com/questions/396939/… –  Derek Hunziker Jun 8 '12 at 14:37
    
That's interesting. CLIENT_ACCEPTED fires when TCP is established, but before SSL is negotiated. Yet all we're doing is checking the profile is associated with the VS (not actually interacting with the SSL itself), so it's supposed to work in CLIENT_ACCEPTED. But of course since you are wanting to insert an HTTP header into the request, you need to do that in HTTP_REQUEST not CLIENT_ACCEPTED. Maybe that was the issue. –  eey0re Jun 8 '12 at 21:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.