Forum Discussion

greenfroguk_338's avatar
greenfroguk_338
Icon for Nimbostratus rankNimbostratus
Nov 07, 2011

Basic iRule to redirect to pools

Hi,

 

 

We have a VIP created and against that VIP have a very basic iRule.

 

 

The idea is that depending on two matches on the URI it directs to a different pool. I know there will be a much better way of doing this.

 

 

The rule is as follows;

 

 

when HTTP_REQUEST { if {[HTTP::uri] contains "e02extport.com" and "var1" } { pool pool_ext_e02_var1 }

 

elseif

 

{[HTTP::uri] contains "e02extport.com" and "var2" } { pool pool_ext_e02_var2 }

 

elseif

 

{[HTTP::uri] contains "e02extport.com" and "var3" } { pool pool_ext_e02_var3 }

 

elseif

 

{[HTTP::uri] contains "e02extport.com" and "var4" } { pool pool_ext_e02_var4 }

 

else

 

{pool pool_ext_e02_default} }

 

 

the idea beinbg that if the uri contains e02extport and var1 then go here or continue to analyse the rule until you either hit a match and if not then use the default.

 

 

now I haven't been able to test it but I have had a report that if the uri is as follows

 

 

https://e02port.com/var1/app.html?r...o2port.com

 

 

then they tester gets a page can not be found.

 

 

if he messes about with the uri and puts in random characters in the ref section so as it breaks up the ref to something like ?ref=https://e02*port.com, or anything that breaks the string up it seems to work.

 

 

Two questions really why would the rule logic do that and what can I do to stop it, I am sure there is a better way, access is made via emebedded links in a browser.

 

 

Only ever done a single very simple iRule before.

 

 

Cheers,

 

 

G

 

8 Replies

  • this is mine.

    [root@ve1023:Active] config  b virtual bar list
    virtual bar {
       snat automap
       destination 172.28.65.152:http
       ip protocol tcp
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve1023:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
            if {[HTTP::uri] contains "e02extport.com" and [HTTP::uri] contains "var1" } {
                    log local0. "pool_ext_e02_var1"
                    pool pool_ext_e02_var1
            } elseif {[HTTP::uri] contains "e02extport.com" and [HTTP::uri] contains "var2" } {
                    log local0. "pool_ext_e02_var2"
                    pool pool_ext_e02_var2
            } elseif {[HTTP::uri] contains "e02extport.com" and [HTTP::uri] contains "var3" } {
                    log local0. "pool_ext_e02_var3"
                    pool pool_ext_e02_var3
            } elseif {[HTTP::uri] contains "e02extport.com" and [HTTP::uri] contains "var4" } {
                    log local0. "pool_ext_e02_var4"
                    pool pool_ext_e02_var4
            } else {
                    log local0. "pool_ext_e02_default"
                    pool pool_ext_e02_default
            }
    }
    }
    
    [root@ve1023:Active] config  curl -I http://172.28.65.152/var1/app.html?ref=https://eo2port.com
    
    [root@ve1023:Active] config  tail -f /var/log/ltm
    Nov  7 04:17:36 local/tmm info tmm[6742]: Rule myrule : pool_ext_e02_default
    
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus
    This is probably more efficient:

    if { [HTTP::host] equals "e02extport.com" } {
      switch -glob [HTTP::path] {
        "/var1/*" {
          pool pool_ext_e02_var1
        }
        "/var2/*" {      pool pool_ext_e02_var2    }    "/var3/*" {      pool pool_ext_e02_var3    }    default {      pool pool_ext_e02_default    }  }}

  • Hi greenfroguk,

    Anything after the "?" is part of the [HTTP::query], so you can use that as the qualifier for your logic first.

    Then you can analyze the [HTTP::uri] to see if it starts with your second condition.

    I agree with Arie, that a switch statement would be more efficient than nested if / elseif statements and would make it much easier to scale if you ever need to add sub-directories.

     
    when HTTP_REQUEST {
    if { [string tolower [HTTP::query]] contains "e02extport.com" } {
    switch -glob [string tolower [HTTP::uri]] {
    "/var1*" { pool pool_ext_e02_var1 }
    "/var2*" { pool pool_ext_e02_var2 }
    "/var3*" { pool pool_ext_e02_var3 } 
    "/var4*" { pool pool_ext_e02_var4 }
    }
    }
    else {
    pool pool_ext_e02_default
    }
    }
    

    Hope this helps.
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus
    From a performance perspective you should use "if/elseif" or "switch" (preferred) for up to about 100 items.

     

     

    However, it appears that changes to iRules often don't take effect for existing connections, thus requiring browser restarts.

     

     

     

    For this reason I often opt for classes (Data Lists) even if I have only a handful of items, since changes to classes take effect immediately.

     

  • Hi Arie,

     

     

    You can manually delete connections to a Virtual Server if you have updated an iRule and need it to be refreshed.

     

     

    Show connections to specific Virtual Server:

     

    b conn server show

     

     

    Delete connections to specific Virtual Server:

     

    b conn server delete

     

     

    Client Friendly way to do it: No.

     

    Effective in making sure that any Virtual Server or iRule Changes are applied to all connections: Yes.
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus
    That's good to know!

     

     

    Any adverse effects on the clients? I imagine it'll wreak havoc on persistence?

     

  • i totally agree with Michael and Arie. :-)

     

     

    anyway, what i wonder is, in my testing, the default else is triggered. why doesn't your irule work??
  • Blimey !,

     

     

    Thanks very much for all the replies. I will give that a go. I think there was an error on the intiail rules as in /var/log/less ltm I can see TCL errors. I will try this out and let you know the results. Thanks very much.

     

     

    G