Forum Discussion

Karthik_Krishn1's avatar
Karthik_Krishn1
Icon for Cirrostratus rankCirrostratus
Oct 03, 2016

IRule to select Virtual server based on Incoming URI

Hello,

 

I am trying to setup an irule such that traffic based on certain URL's is directed towards the appropriate virtual servers. Essentialy we have mutliple URL's " siteA.domain.com" , "siteB.domain.com", "siteC.domain.com" and so on. What i want to do when the traffic comes in is that based on the incoming URL, i want the traffic to be sent to the VS defined for that site. I have a conceptual idea but when i put the rule in i get the error " command not valid in current scope"

 

The rule i tried is as below

 

when HTTP_REQUEST { if {[HTTP::uri] contains "siteA.domain.com" } { log local0. "SiteA Access" virtual vs_SiteA_prod } elseif {[HTTP::uri] contains "SiteB.domain.com" } { log local0. "SiteB Access" virtual vs_SiteB_prod } elseif {[HTTP::uri] contains "SiteC.domain.com" } { log local0. "SiteC Access" virtual vs_kronos_prod } elseif {[HTTP::uri] contains "SiteD.domain.com" } { log local0. "SiteD Access" virtual vs_SiteD_prod } else { log local0. "SiteA" virtual vs_SiteA_prod } } }

 

Any help would be appreciated.

 

Thanks,

 

karthik

 

8 Replies

  • I'm not sure if you can redirect to multiple virtual servers because the irule you are using it in one virtual server.

     

    You can configure multiple pools and redirect to those pools based on the URL. Does that serves your purpose? I can help you creating an irule for that.

     

    Otherwise you might need to create a wildcard wideip in GTM and create a DNS irule.

     

    -Jinshu

     

  • karthik,

    If I understand you correctly, I think you are trying to route by HTTP host. If so, you'll have to use [HTTP::host] instead of [HTTP:uri].

    when HTTP_REQUEST { 
        if {[HTTP::host] contains "siteA.domain.com"} { 
            log local0. "SiteA Access" virtual vs_SiteA_prod 
        }  
    }
    

    See the following: https://devcentral.f5.com/wiki/iRules.HTTP__host.ashx

  • That will help. but here's the thing. On the virtual servers for each of those SIte's i also have a redirect to a specific login URI. Can you redirect to a pool and issue the appropriate redirect as part of the same iRUle ?

     

    for eg when a user types in https://siteA.domain.com , pool SiteA needs to be selected and the user needs to be redirected to "https://siteA.domain.com/TC/welcome.msv" and when a user ttypes in https://siteB.domain.com, pool SiteB needs o be selected and user needs to be redirected to http://siteB.domain.com/Login/login.apsx

     

    I started out along the path of redirecting to pools based on the URL , but did not know how to issue the redirects

     

    • strain17's avatar
      strain17
      Icon for Nimbostratus rankNimbostratus

      For redirects, you can either use "HTTP::redirect" or "HTTP::respond".

       

      https://clouddocs.f5.com/api/irules/HTTP__redirect.html https://clouddocs.f5.com/api/irules/HTTP__respond.html

       

      For the trigger, something that checks for either the HTTP::path or HTTP::uri would work. Example"

       

      switch -glob [string tolower [HTTP::uri]] {
          "" -
          "/"  {
              HTTP::redirect "https://[HTTP::host]/TC/welcome.msv"
          }
      }
      

      From your initial description, it doesn't seem like you are sharing a single virtual server with multiple pools. It looked like a virtual server which redirects to other virtual servers. So, if that is the cause, the default pool (if one is set) for each of the virtual servers should serve the request to appropriate pools.

       

    • Karthik_Krishn1's avatar
      Karthik_Krishn1
      Icon for Cirrostratus rankCirrostratus

      Actually i do want to use a single virtual server to redirect to other pools and at the same time perform the redirect to the appropriate URL once the pool is selected. Currently the way these are setup is a single VS for each site.

       

      The rule i was going to use for pool selection is as below. Is it possible to do the redirect within this rule.

       

      when HTTP_REQUEST { if {[HTTP::uri] contains "siteA.domain.com" } { log local0. "SiteA Access" pool vs_SiteA_prod_pool_pool } elseif {[HTTP::uri] contains "SiteB.domain.com" } { log local0. "SiteB Access" pool vs_SiteB_prod_pool } elseif {[HTTP::uri] contains "SiteC.domain.com" } { log local0. "SiteC Access" pool vs_kronos_prod_pool } elseif {[HTTP::uri] contains "SiteD.domain.com" } { log local0. "SiteD Access" pool vs_SiteD_prod_pool } else { log local0. "SiteA" pool vs_SiteA_prod_pool } } }

       

    • strain17's avatar
      strain17
      Icon for Nimbostratus rankNimbostratus

      Without fully understanding 100% what it is you are trying to do still (because URL redirection is independent of the actual pool selection). Here is a modified (very crude) example of what you can do with your iRule above:

      when HTTP_REQUEST {
              if {[HTTP::uri] contains "siteA.domain.com" } {
                      log local0. "SiteA Access"
                      pool vs_SiteA_prod_pool_pool
                      if {[HTTP::uri] == "" || [HTTP::uri] == "/"} {HTTP::redirect "https://[HTTP::host]/TC/welcomeA.msv"}
              } elseif {[HTTP::uri] contains "SiteB.domain.com" } {
                      log local0. "SiteB Access"
                      pool vs_SiteB_prod_pool
                      if {[HTTP::uri] == "" || [HTTP::uri] == "/"} {HTTP::redirect "https://[HTTP::host]/TC/welcomeB.msv"}
              } elseif {[HTTP::uri] contains "SiteC.domain.com" } {
                      log local0. "SiteC Access"
                      pool vs_kronos_prod_pool
                      if {[HTTP::uri] == "" || [HTTP::uri] == "/"} {HTTP::redirect "https://[HTTP::host]/TC/welcomeC.msv"}
              } elseif {[HTTP::uri] contains "SiteD.domain.com" } {
                      log local0. "SiteD Access"
                      pool vs_SiteD_prod_pool
                      if {[HTTP::uri] == "" || [HTTP::uri] == "/"} {HTTP::redirect "https://[HTTP::host]/TC/welcomeD.msv"}
              } else {
                      log local0. "SiteA"
                      pool vs_SiteA_prod_pool
              }
      }
      

      I personally would use the switch statement for this.

  • It looks from your original post that you are simply trying to make a pool selection based on the incoming Host header. For more details on the Host header, I encourage you to read the "Elaboration" section of this iRule recipe:

    The

    virtual
    command selects a BIG-IP Virtual Server by name. That's almost certainly not what you want (though it could be, if you had differing profiles attached to various Virtual Servers; but in that case, it usually makes more sense to map the DNS hostnames to differing IPs, one per Virtual Server). Again, assuming that you wish to select a BIG-IP Pool based on the incoming Host header value:

    when HTTP_REQUEST {
        switch [string tolower [HTTP::host]] {
            "www.abc.com" {
                pool abc_com
            }
            
            "www.def.com" {
                pool def_com
            }
            
            "www.alpha.com" -
            "www.beta.com" {
                pool alphabet
            }
        }
    }
    

    To understand the dash case, see the Elaboration section of "Analysis" section of this recipe:

    People often put in a "default" case, but you generally do not need to do so. If no

    switch
    case matches, the default configuration of the Virtual Server will be used, including whatever Pool is attached to the Virtual Server.

    If you have a large number of cases, then you should consider using a Data-Group:

    Data-Groups are more efficient than

    switch
    es for larger data sets.