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):

   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?

  • 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, 2012 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? Jun 7, 2012 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, 2012 at 20:21

1 Answer 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:

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


  • 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/… Jun 8, 2012 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, 2012 at 21:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .