Forum Discussion

ramr_261905's avatar
ramr_261905
Icon for Nimbostratus rankNimbostratus
May 05, 2016

How to configure a virtual server with serverssl profiles to talk to both HTTP and HTTPS backends?

In our F5 (version: 11.6.0) setup: 1. SSL is being terminated on the F5 end. 2. Connections on the serverside (to the backend pool) can be either HTTP or HTTPS. Each pool can contain backends that either "talk" plain HTTP or HTTPS (one or the other not both). 3. We have a policy attached to the Virtual Server (that's terminating SSL/TLS) that selects a backend pool based on the HTTP host header. Rule: http-host host equals forward select pool 4. The VirtualServer (terminating https) has both client and server ssl profiles. 5. The clientssl profiles serve the appropriate certs based on SNI - that part's working well. 6. For the backend HTTPS case, we have a serverside SSL profile created and attached to the Virtual Server. In addition, we needed to add a default serverside SSL profile created [default-serverssl] with the default SSL profile for SNI checkbox checked. Otherwise we couldn't add multiple serverside ssl profiles. Note: As you'd expect, there is no serverside SSL profile for the HTTP backend case (only exists if backend talks HTTPS). 7. The HTTPS backends serve certificates with the name matching what is set in the serverside SSL profile.

 

What we were looking to do was to have the virtual server talk HTTPS to backends with an serverside ssl profile (SNI matches) and falling back to talking HTTP if there was no profile?

 

Really SSL::{enable,disable} serverside based on a profile but were struggling to find the right combination of events/way to do this with an iRule. We did see that the "PROFILE::exists serverssl" and "PROFILE::serverssl name" are not properly set but I suspect it was because we looked at it at: when SERVER_CONNECTED { ... }

 

Having a default-serverssl profile does complicate things a bit plus its sort of a chicken-and-egg thingy, if we add any serverssl profiles, the F5 only talks HTTPS to the backends (because of the default-serverssl profile) and if we have none, then F5 only talks HTTP to the backends. We wanted a combination of both.

 

Any suggestions on how to do this would be greatly appreciated. Thanks in advance.

 

  • my formatting-fu sucks!! And I have no idea how to fix it. Apologies for that.
  • BinaryCanary_19's avatar
    BinaryCanary_19
    Historic F5 Account

    You can use an irule with LB_SELECTED event. Obtain information about which pool was selected via the LB::server command. Then all you need to do is Disable server-SSL, or enable it depending on your logic.

     

    I would suggest to attach a Oneconnect profile to the VIP for this kind of use case, so that load balancing checks are performed on every request (instead of once at the start of connection) due to the influence that http keepalive can have.

     

    • ramr_261905's avatar
      ramr_261905
      Icon for Nimbostratus rankNimbostratus
      Thanks for the response @FKnuckles - yeah we would also need to do some "bookkeeping" on the pools to know when to do that. We programmatically add the pools/rules/profiles, so the serverssl profile is the sole indicator we have as of now that the backends "speaks" only HTTPS. One solution/suggestion we had was to create and update a new datagroup with all HOSTs that need HTTPS and based on an entry in that map, enable/disable SSL. Thx
  • BinaryCanary_19's avatar
    BinaryCanary_19
    Historic F5 Account

    You can use an irule with LB_SELECTED event. Obtain information about which pool was selected via the LB::server command. Then all you need to do is Disable server-SSL, or enable it depending on your logic.

     

    I would suggest to attach a Oneconnect profile to the VIP for this kind of use case, so that load balancing checks are performed on every request (instead of once at the start of connection) due to the influence that http keepalive can have.

     

  • If I may expand, I'd make a few additional points.

    1. Do you need SNI information applied to the server SSL profile(s)? Do you even really need multiple server SSL profiles? Most SSL sessions are client-initiated, so on the server side, the server SSL profile is responsible for initiating the SSL handshake to the server. In other words, it speaks first. The Server Name (SNI) field in the server SSL profile is used to inject a Server Name Indication extension in the F5's ClientHello message to the server. You'd only need this if the server actually required it, which they usually don't.

    2. Switching and/or enabling/disabling server side attributes needs to happen before the server side context (SERVER_CONNECTED), so LB_SELECTED would work, but for what you're doing HTTP_REQUEST would probably be more appropriate. SO basically, assign a server SSL profile to the VIP, and selectively disable it based on the client side HTTP request. Something like this:

      when CLIENT_ACCEPTED {
          SSL::disable serverside
      }
      when HTTP_REQUEST {
          switch [string to lower [HTTP::host]] {
              "foo.company.com" { SSL::enable serverside }
          }
      }
      
    3. If you're switching between different pool members during a single client connection, then you absolutely should enable OneConnect. But if the client is only going to a single pool member, then you don't it.

  • We assumed (maybe incorrectly but this does work) that the SNI name in the serverssl profile would be used to match up to what the backend "served" up and so validate the backend certificate.

     

    It does not. The SNI is only used by the server, if at all needed.

     

    2, so we are doing this for a cluster where we programmatically add pools/serverssl profiles/certs etc and so we could need to keep a track of all hosts we added serverssl profiles for. So one suggestion we had was to create a datagroup that contains that set of host names and key enabling ssl serverside off of that

     

    The data group option is probably the best option. You simply need to know, based on the Host header, whether or not to use server side SSL, correct? You could also include the pool in that data group if you're also switching between pools.