Forum Discussion

Charles_Owen's avatar
Charles_Owen
Icon for Nimbostratus rankNimbostratus
Oct 22, 2019

Routing traffic by URI to a server pool with https front end using iRule

I am wanting to take any https request to commonserver.domain.name and routing traffic by URI to a specific port on an underlying pool member.

       

https is is handled by the f5 (in a SSL Profile) and the connections are persistent once established.

 

The port is based of the uri coming in.

  https://commonserver.domain.name/app1    ->     http://<serverpool>.domain.name:xxx2/app1 

  https://commonserver.domain.name/app2      ->         http://<serverpool>.domain.name:xxx4/app2 

  https://commonserver.domain.name/app3    ->         http://<serverpool2>.domain.name:xx82/app3 

 https://commonserver.domain.name/ ->         http://<serverpool3>.domain.name/defaultpage.htm

 

 

3 Replies

  • Hi

     

    To make things simpler, can't you create one one pool for port xxx2, another for port xxx4 another for port xx82, and a last one for port 80, and assign pool directly according the URI using LTM policy ?

     

    Yoann

  • You could try an iRule with a Datagroup to match on a " HTTP host Header + Path" and map it to select a pool.

    Note: I haven't tested this,

    when CLIENT_ACCEPTED {
        set DEFAULT_POOL [LB::server pool]
    }
     
    when HTTP_REQUEST {
        set HOST_PATH_2_POOL [string tolower [getfield [HTTP::host] ]][string tolower [URI::path [HTTP::uri] 1 1]]
        set POOL_SELECT_VALUE [class lookup $HOST_PATH_2_POOL HOST_and_PATH_2_POOL_DG]
        if {$POOL_SELECT_VALUE eq ""} {
           set POOL_SELECT_VALUE [class lookup [string tolower [getfield [HTTP::host] "." 1]] HOST_and_PATH_2_POOL_DG]
        }
        #log local0.notice "HOST_PATH_2_POOL = $HOST_PATH_2_POOL"
        #log local0.notice "POOL_SELECT_VALUE = $POOL_SELECT_VALUE"
        if {$POOL_SELECT_VALUE eq ""} {
            set USE_POOL $DEFAULT_POOL
        } else {
            set USE_POOL $POOL_SELECT_VALUE
        }
    }

    Your DG would look like:

    1. "commonserver.domain.name/app1" := "Poolname_1",
    2. "commonserver.domain.name/app2" := "Poolname_2",
    3. "commonserver.domain.name/app3" := "Poolname_3,
    4. "commonserver.domain.name/" := "Default_poolname",
    • Charles_Owen's avatar
      Charles_Owen
      Icon for Nimbostratus rankNimbostratus

      I will try your suggestion tomorrow...

      With limited success, I had started down a a path using a similar code with a DG using only "/appname" and used a "hammer" approach with a first irule before it like this:

       

      Irule #1

      when HTTP_REQUEST {

       if { [HTTP::uri] eq "" || [HTTP::uri] eq "/" } {

        HTTP::redirect "http://commonserver.domain.name/" "

        event disable all

       }

      }

       

      Irule#2

      when HTTP_REQUEST {

        #Check to see if the DataGroup matches a URI call

        set svr_port [class match -value -- [HTTP::uri] starts_with port_fwd_applications]

        #Check to see if a LB decision has already been made for this connection

        if { [LB::server addr] != "" }{

        #Check to see the LB port matches the DataGroup entry

          if {[LB::server port] != $svr_port } {

          #If the port and DataGroup dont match, remove the serverside connection and re-load-balance

      LB::detach

          } 

        }

        if {$svr_port eq ""}{

        #DataGroup doesn't match the URI, drop the connection

        #or do something else here

        drop

        }

      }

       

      when LB_SELECTED {

        #A new LB decision has been made, check to see if the DataGroup has fired

        if {$svr_port != ""}{

          #The DataGroup URI matches, check to see if the ports match

          if {[LB::server port] != $svr_port } {

            #Send the traffic to the DataGroup Port

            LB::reselect node [LB::server addr] $svr_port

            }

          }

      }