2

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?

masegaloeh
  • 17,978
  • 9
  • 56
  • 104
Derek Hunziker
  • 197
  • 1
  • 1
  • 8
  • 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](http://webmasters.stackexchange.com/a/28443/11628) for more details.) – Bruno Jun 07 '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 07 '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 09 '12 at 20:21

1 Answers1

1

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

eey0re
  • 431
  • 4
  • 5
  • 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: http://serverfault.com/questions/396939/possible-to-redirect-from-https-to-http-behind-load-balancer – Derek Hunziker Jun 08 '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 08 '12 at 21:45