Forum Discussion

Blueluke_85810's avatar
Blueluke_85810
Icon for Nimbostratus rankNimbostratus
Oct 29, 2012

HTTP Profile breaking HTTPS site

If I apply a vanilla HTTP Profile to my HTTPS VIP it stops the page from being returned. As soon as I remove the profile it starts working again. I am not offloading at the LTM. What could be causing the problem with the profile blocking my site?

 

  • Hi,

     

     

    When you add an HTTP profile to a virtual server you're instructing TMM to parse the traffic to that VS as HTTP. If it's HTTPS traffic being sent you need use a client SSL profile on the virtual server to decrypt the traffic. Else, TMM resets the client connection because the encrypted traffic can't be parsed as HTTP.

     

     

    So you need to either add a client SSL profile to the virtual server or remove the HTTP profile.

     

     

    Aaron
  • So is there another way to redirect http to https on the LTM without using a redirect iRule? I'm running into a similar issue where I'm not terminating SSL, yet I want to redirect port 80 requests to 443. I was going to use an iRule, but that needs a http profile to be applied to the VS.

     

  • You only need to apply the HTTP profile and iRule to the port 80 VIP. You can absolutely still perform an HTTP redirect with an iRule without an HTTP profile, but the other way is much easier.

     

  • Think of the various profiles (TCP, HTTP, etc.) as "filters". When you want to evaluate HTTP traffic (as in use the HTTP events and commands), you need to apply an HTTP profile. When you want to evaluate TCP traffic, you apply a TCP profile. When you want to evaluate SSL events, you apply SSL profiles, and so forth for other protocols. iRules are actually global to the stack (layer 4 - 7). The events and commands you can use, however, are dependent on the filters you apply.

     

  • Great question. You also have to think of iRules in relation to the OSI layers. So by the time you get to layer 7 HTTP in the protocol stack, and can use HTTP profile events and commands, you've already processed layer 4 TCP. Assuming the traffic isn't encrypted, the TCP events should be able to see the same thing that the HTTP events see, and can act on the data as well. The HTTP profile filter adds an "ease-of-use" feature set so that you can JUST act on the HTTP data elements (headers, cookies, payload, etc.). From TCP's perspective, however, all of HTTP is just payload. So to do an HTTP redirect in a TCP event (in the absence of an HTTP profile), you have to carefully craft your responses.

    So for example, to do a redirect in an HTTP_REQUEST event (with an HTTP profile applied to the VIP), you'd do something like this:

    when HTTP_REQUEST {
        HTTP::redirect "https://[HTTP::host][HTTP:uri]"
    }
    

    That takes care of all the HTTP semantics under the hood. To do the same thing with the CLIENT_ACCEPTED event, this is what it might look like:

    when CLIENT_ACCEPTED {
        TCP::collect
    }
    when CLIENT_DATA {
        set HOST [findstr [TCP::payload] "Host: " 6 "\r\n"]
        switch -glob [TCP::payload] {
            "GET*" {
                set URI [findstr [TCP::payload] "GET " 4 "HTTP/1."]
            }
            "POST*" {
                set URI [findstr [TCP::payload] "POST " 5 "HTTP/1."]
            }
            "HEAD*" {
                set URI [findstr [TCP::payload] "HEAD " 5 "HTTP/1."]
            }
        }
    
        TCP::respond "HTTP/1.1 302 Found\r\nLocation: https://${HOST}${URI}\r\n\r\n"
        TCP::release
    }
    

    Because all of HTTP is just payload in the TCP event, you have to manually parse out the HTTP elements (host, uri) and then craft the HTTP redirect payload by hand. The good news is that you could do this sort of thing to support basically ANY protocol.

  • That's actually pretty cool that you can search inside the TCP payload like that

    I realized after my last post that I gave you an egregious example. The following is perhaps more succinct.

    when CLIENT_ACCEPTED {
        TCP::collect
    }
    when CLIENT_DATA {
        set HOST [findstr [TCP::payload] "Host: " 6 "\r\n"]
        scan [TCP::payload] "%s %s HTTP/1" METHOD URI
    
        TCP::respond "HTTP/1.1 302 Found\r\nLocation: https://${HOST}${URI}\r\n\r\n"
        TCP::release
    }
    

    It's shorter of course, but it still doesn't displace the notion that you have to physically parse the HTTP payload out of the TCP packet, and that you have to have a much better understanding of how the layer 7 protocol works. For things like HTTP, it just makes sense from a management and ease-of-use perspective to use HTTP-level events and commands (with an associated HTTP profile). Where it gets REALLY useful is when you have to support a protocol that isn't built-in.