For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

forsan's avatar
forsan
Icon for Altostratus rankAltostratus
Apr 29, 2014

node select iRule

Hi,

 

I have created an iRule that that is supposed to send traffic to a specific node depending on input from the URI. The iRule looks like this:

 

when HTTP_REQUEST { set node_ip [getfield [HTTP::uri] "/" 4] if { $node_ip >= 160 and $node_ip <= 253 } { HTTP::uri [string map [list $node_ip ""] [HTTP::uri]] node "10.1.1.$node_ip" 80 } else { pool mediaroot-pool } }

 

The idé is that if I use the url http://example.com/foo/bar/mediaroot/image1.jpg I will be sent to the "default" pool mediaroot-pool. But if I go to the url http://example.com/foo/bar/170/mediaroot/image1.jpg I will be sent to the node 10.1.1.170 and the URI will be changed to /foo/bar/mediaroot/image1.jpg with a rewrite.

 

I have created nodes between .160 and .253.

 

The part of the iRule that is not working is this: if { $node_ip >= 160 and $node_ip <= 253 }

 

If I go to the URL http://example.com/foo/bar/170/mediaroot/image1.jpg its sent to the correct node but with the URL http://example.com/foo/bar/mediaroot/image1.jpg the if statement thinks that mediaroot (getfield value 4) is correct.

 

Is the if statement that checks if the $node_ip is between 160-253 wrong?

 

Regards Andréas

 

3 Replies

  • with the URL http://example.com/foo/bar/mediaroot/image1.jpg the if statement thinks that mediaroot (getfield value 4) is correct.

     

    it went to mediaroot-pool pool here. how did you know it went to the wrong node?

     

  • e.g.

     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 { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 9
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set node_ip [getfield [HTTP::uri] "/" 4]
      log local0. "node_ip $node_ip"
      if { $node_ip >= 160 and $node_ip <= 253 } {
        HTTP::uri [string map [list $node_ip ""] [HTTP::uri]]
        log local0. "HTTP::uri [string map [list $node_ip ""] [HTTP::uri]] "
        log local0. "node 10.1.1.$node_ip 80"
      } else {
        log local0. "pool mediaroot-pool"
      }
    }
    }
    
     test
    
    [root@ve11a:Active:In Sync] config  curl -I http://example.com/foo/bar/mediaroot/image1.jpg
    HTTP/1.1 404 Not Found
    Date: Tue, 29 Apr 2014 12:37:51 GMT
    Server: Apache/2.2.3 (CentOS)
    Content-Type: text/html; charset=iso-8859-1
    
    [root@ve11a:Active:In Sync] config  tail /var/log/ltm
    Apr 29 05:47:42 ve11a info tmm1[13022]: Rule /Common/qux : node_ip mediaroot
    Apr 29 05:47:42 ve11a info tmm1[13022]: Rule /Common/qux : pool mediaroot-pool
    
  • Hi,

    I got the following error in the log: May 12 09:07:04 bigip err tmm[9415]: 01220001:3: TCL error: /Common/mediaroot - bad IP address format (line 😎 invoked from within "node "10.1.1.$node_ip" 80"

    I have now found that if I use I URL other than a number or /mediaroot/ as the 4:th argument in the URI the iRule do not match any of the if statements. What I have done is that I modified the first elseif statement to elseif { $node_ip starts_with "1" || $node_ip starts_with "2" && $node_ip >= 160 } to check that its a number and then added an else statement that drops the connection if its not matching the other statements.

    when HTTP_REQUEST {
        set node_ip [getfield [HTTP::uri] "/" 4]
        if { [HTTP::uri] starts_with “/foo/bar/mediaroot/“ } {
            log local0. "starts with /foo/bar/mediaroot/"
            pool mediaroot-pool
        } elseif { $node_ip starts_with "1" || $node_ip starts_with "2" && $node_ip >= 160 } {
            HTTP::uri [string map [list $node_ip ""] [HTTP::uri]]
            node "10.1.1.$node_ip" 80
        } else {
            drop
        }
    }