Forum Discussion

Frank_30530's avatar
Frank_30530
Icon for Altocumulus rankAltocumulus
Feb 05, 2019

SSL::enable/SSL::disable unexpected behaviour

I have a question about the specific bahaviour of LTM with regard to SSL::enable/SSL::disable.

I have a virtual server with two pools:

  • One pool has a member that needs TLS communication;
  • The other pool has a member that doesn't use TLS (i.e., it uses plain text HTTP).

The pool selection is based on the request URI (e.g., the first URI-path selects the pool).

I have a serverside SSL profile configured to my virtual server.

When I use the iRule below, the behaviour is not quite what I expected:

when HTTP_REQUEST {

  if {  } {
     select the tls-pool: enable server side SSL
    SSL::enable serverside
    pool 
  }
  else {
     select the http-pool: disable server side SSL
    SSL::disable serverside
    pool 
  }

}
`


The observed behaviour is as follows:
  1. Client connects to virtual server (new TCP connection).
  2. Client issues a request that selects the http-pool. The http-pool member responds (confirmed: the 'SSL::disable' works).
  3. Over the same client TCP connection, the client issues a request that selects the tls-pool. The tls-pool member responds (confirmed: server side TLS is working).
  4. Over the same client TCP connection, the client issues a request that selects the http-pool again. This fails!

    A tcpdump reveals that LTM is sending a TLS Client Hello to the http pool member. The pool member responds with a '400 Bad Request', I get errors in /var/log/ltm:

    `warning tmm2[1688]: 01260009:4: Connection error: ssl_null_parse:3177: record length too large (22)
    warning tmm2[1688]: 01260013:4: SSL Handshake failed for TCP 192.168.10.10:80 -> 192.168.10.1:50214
    `

    and the client side TCP connection is aborted (TCP RST).

    When I rewrite my iRule to perform the 'SSL::enable' and 'SSL::disable' in a SERVER_CONNECTED event, all seems to work fine:

    `when HTTP_REQUEST {
    if {  } {
        set tls 1
        pool 
      }
      else {
        set tls 0
        pool 
      }
    }
    when SERVER_CONNECTED {
    if { $tls == 1 } {
        SSL::enable serverside
      }
      else {
        SSL::disable serverside
      }
    }
    

What is the difference? My guess is it has to do with attach/detach. But I seem to miss the subtle difference...

2 Replies

  • Check out this article:

     

    https://support.f5.com/csp/article/K9800

     

    However, in order to support proper pool reselection mid-connection, such as supporting multiple HTTP requests arriving on the same Keep-Alive connection, the existing server-side connection must first be detached. If no conditions resulting in pool selection match the request, failure to detach from the existing server-side connection may result in an unexpected choice for the default pool.

     

  • Just a thought, I see in your 1st irule you are making SSL disable in the clientside of the connection, Http request. Because when you do not sepcify context side, it will apply to the default connection side. So here it's SSL DISABLE for client SSL alone. But your serverssl is still enabled. Thereby when sent to serverside, serverssl still applies.

    when HTTP_REQUEST {
    
      if {  } {
         select the tls-pool: enable server side SSL
        SSL::enable
        pool 
      }
      else {
         select the http-pool: disable server side SSL
        SSL::disable
        pool 
      }
    
    }
    

    If you try the below, it should work too.

    when HTTP_REQUEST {
    
      if {  } {
         select the tls-pool: enable server side SSL
        SSL::enable
        pool 
      }
      else {
         select the http-pool: disable server side SSL
        SSL::disable
         Not really sure if both context sides can be mentioned in one command :very) SSL::disable clientside serverside
        SSL::disable serverside
        pool 
      }
    
    }