Forum Discussion

Landono's avatar
Landono
Icon for Nimbostratus rankNimbostratus
Sep 04, 2014

SSL Serverside Not Being Disabled Correctly

Currently we have an iRule that selects the pool based on the URL path. Some pools accept SSL while others do not. In the IF statement (which is in the HTTP_REQUEST event block), if the traffic is forwarded to a pool that doesn't support SSL we have the command SSL:disable serverside. However, it seems that occasionally SSL is not being disabled correctly. Looking around it seems this may be because we should have SSL being disabled in the SERVER_CONNECTED block. I've modified our iRule to disable SSL by default, select the pool in the HTTP_REQUEST block and then re-enable SSL if needed in the SERVER_CONNECTED block. However, it seems that my string comparisons for the pool name in the SERVER_CONNECTED block are not working correctly. Any help on what I'm doing wrong in this iRule is appreciated.

Current iRule:

when CLIENT_ACCEPTED {
   SSL::disable serverside
   set default_pool [LB::server pool]
}

when HTTP_REQUEST {
    HTTP::header insert "X-Forwarded-Proto" "https"

    if { [HTTP::uri] starts_with "/foo" } {
      pool pool_foo_https
    }
    elseif { [HTTP::path] starts_with "/bar" } {
      pool pool_bar_http
    }
    else {
      pool $default_pool
    }
}

when SERVER_CONNECTED {
  if { ([string tolower [LB::server pool]] matches "pool_foo_https") } {
    SSL::enable serverside
  }
  else {
    SSL::enable serverside
  }
}

5 Replies

  • You should absolutely be able to use SSL::disable serverside in the HTTP_REQUEST event. You may alternatively want to adjust how you're filtering on the URIs, and/or investigate if these URIs are consistent.

    when CLIENT_ACCEPTED {
        set default_pool [LB::server pool]
    }
    when HTTP_REQUEST {
        HTTP::header insert "X-Forwarded-Proto" "https"
    
        if { [string tolower [HTTP::uri]] starts_with "/foo" } {
            pool pool_foo_https
        } elseif { [string tolower [HTTP::uri]] starts_with "/bar" } {
            pool pool_bar_http
            SSL::disable serverside
        } else {
            pool $default_pool
            SSL::disable serverside
        }
    }
    
  • Maybe some additional logging is in order:

    when CLIENT_ACCEPTED {
        set default_pool [LB::server pool]
        log local0. "default pool is $default_pool"
    }
    when HTTP_REQUEST {
        log local0. "incoming uri: [HTTP::uri]"
        HTTP::header insert "X-Forwarded-Proto" "https"
    
        if { [string tolower [HTTP::uri]] starts_with "/foo" } {
            log local0. "sending to foo pool"
            pool pool_foo_https
        } elseif { [string tolower [HTTP::uri]] starts_with "/bar" } {
            log local0. "sending to bar pool"
            pool pool_bar_http
            SSL::disable serverside
        } else {
            log local0. "sending to default pool"
            pool $default_pool
            SSL::disable serverside
        }
    }
    

    In this case you may also want to enable OneConnect.

  • My main question is why my if statement on the pool is not working correctly.

    can you try to add partition name (i.e. /common)?

     config
    
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            serverssl {
                context serverside
            }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 7
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:80 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool pool_foo_https
    ltm pool pool_foo_https {
        members {
            200.200.200.101:443 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool pool_bar_http
    ltm pool pool_bar_http {
        members {
            200.200.200.111:80 {
                address 200.200.200.111
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when CLIENT_ACCEPTED {
      SSL::disable serverside
      set default_pool [LB::server pool]
    }
    
    when HTTP_REQUEST {
      set host [HTTP::host]
      set uri [HTTP::uri]
      HTTP::header insert "X-Forwarded-Proto" "https"
    
      if { [HTTP::uri] starts_with "/foo" } {
        pool pool_foo_https
      }
      elseif { [HTTP::path] starts_with "/bar" } {
        pool pool_bar_http
      }
      else {
        pool $default_pool
      }
    }
    
    when SERVER_CONNECTED {
      if { [LB::server pool] matches "/Common/pool_foo_https" } {
        SSL::enable serverside
      }
      else {
        SSL::disable serverside
      }
    }
    when HTTP_RESPONSE {
      log local0. "client=[IP::client_addr]:[TCP::client_port] host=$host uri=$uri server=[LB::server]"
    }
    }
    
     /var/log/ltm
    
    [root@ve11a:Active:In Sync] config  tail -f /var/log/ltm
    Sep  4 17:50:40 ve11a info tmm[15094]: Rule /Common/qux HTTP_RESPONSE: client=172.28.24.1:38994 host=172.28.24.10 uri=/ server=/Common/foo 200.200.200.101 80
    Sep  4 17:50:52 ve11a info tmm1[15094]: Rule /Common/qux HTTP_RESPONSE: client=172.28.24.1:38995 host=172.28.24.10 uri=/foo server=/Common/pool_foo_https 200.200.200.101 443
    Sep  4 17:50:58 ve11a info tmm[15094]: Rule /Common/qux HTTP_RESPONSE: client=172.28.24.1:38996 host=172.28.24.10 uri=/bar server=/Common/pool_bar_http 200.200.200.111 80
    
  • The X-Forwarded-For header can be added with a tick box in a http profile.

    If this is 11.4+ then you should use policies. No iRule needed.

    If pre 11.4 then use HTTP classes for pool selection and add the following iRule. Ensure you have a catchall class at the end for the default pool.

    when HTTP_CLASS_SELECTED {
      switch [HTTP::class] {
        "class_pool_bar" -
        "class_pool_default" { SSL::disable serverside }
      }
    }
    
  • This thread is 3 years old but the original question had "SSL::enable serverside" in BOTH if and else conditions and that's why the if statement on the pool is not working correctly.

    when SERVER_CONNECTED {
      if { ([string tolower [LB::server pool]] matches "pool_foo_https") } {
        SSL::enable serverside
      }
      else {
        SSL::enable serverside
      }
    

    Should have been

    when SERVER_CONNECTED {
      if { ([string tolower [LB::server pool]] matches "pool_foo_https") } {
        SSL::enable serverside
      }
      else {
        SSL::disable serverside
      }