Forum Discussion

bbensten_8485's avatar
bbensten_8485
Icon for Nimbostratus rankNimbostratus
Jul 07, 2014

Following order in Irule processing.

Hi, we have the following irule that thanks to a Dev Central user is working well but I have an additional question. Can someone help me add logic that allows the rule to process in order of granularity? For example, if a user connects with the path of /blah/*/blah2 do not care about the ip block but if only /blah then I do care... I need 3 different possibilities that all include /blah somewhere in the path but 2 specifics that should not have the IP block applied.

 

when HTTP_REQUEST { if { [string tolower [HTTP::path]] contains "/blah" } { if { ! [class match [IP::client_addr] equals allowed_IPs]} { log local0. "[IP::client_addr]:[TCP::client_port] does not match the allowed IP list" discard } } }

 

6 Replies

  • 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 55
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm data-group internal allowed_IPs
    ltm data-group internal allowed_IPs {
        records {
            172.28.24.15/32 { }
        }
        type ip
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set path [string tolower [HTTP::path]]
      log local0. "*********************"
      log local0. "client=[IP::client_addr] host=[HTTP::host] path=$path"
    
      if { $path starts_with "/blah" } {
        if { [string match "/blah/*/blah2*" $path] } {
          log local0. "$path matches /blah/*/blah2*"
        } else {
          log local0. "$path starts with /blah but not /blah/*/blah2*"
          if { ! [class match [IP::client_addr] equals allowed_IPs]} {
            log local0. "[IP::client_addr] does not match allowed IP list"
          } else {
            log local0. "[IP::client_addr] matches allowed IP list"
          }
        }
      }
    }
    }
    
     /var/log/ltm
    
    [root@ve11a:Active:In Sync] config  tail -f /var/log/ltm
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/blah/something
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : /blah/something starts with /blah but not /blah/*/blah2*
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : 172.28.24.1 does not match allowed IP list
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.15 host=172.28.24.10 path=/blah/something
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : /blah/something starts with /blah but not /blah/*/blah2*
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : 172.28.24.15 matches allowed IP list
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/blah/1/2/blah2/something
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : /blah/1/2/blah2/something matches /blah/*/blah2*
    Jul  8 00:39:57 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:57 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/somethingelse
    
    • bbensten_8485's avatar
      bbensten_8485
      Icon for Nimbostratus rankNimbostratus
      Nitass, This is very helpful. I have a few follow up questions. 1- As you clearly did above, I want to be able to evaluate multiple URI strings and if not one of those strings, require the client IP to be allowed. Right now, there are 7 evaluations that need to be done and if not one of those, it needs to match the ip list. List is as follows: /blah/blah1 /blah/blah2 /blah/blah3 /blah/blah3/* /blah/blah4/* /blah/blah4/*/foo1/foo2 /blah/blah5/blah6-* 2- Would it make sense to do the list of URI options as a Datagroup list? If so, how would we do that? I really appreciate your help.
  • 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 55
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm data-group internal allowed_IPs
    ltm data-group internal allowed_IPs {
        records {
            172.28.24.15/32 { }
        }
        type ip
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set path [string tolower [HTTP::path]]
      log local0. "*********************"
      log local0. "client=[IP::client_addr] host=[HTTP::host] path=$path"
    
      if { $path starts_with "/blah" } {
        if { [string match "/blah/*/blah2*" $path] } {
          log local0. "$path matches /blah/*/blah2*"
        } else {
          log local0. "$path starts with /blah but not /blah/*/blah2*"
          if { ! [class match [IP::client_addr] equals allowed_IPs]} {
            log local0. "[IP::client_addr] does not match allowed IP list"
          } else {
            log local0. "[IP::client_addr] matches allowed IP list"
          }
        }
      }
    }
    }
    
     /var/log/ltm
    
    [root@ve11a:Active:In Sync] config  tail -f /var/log/ltm
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/blah/something
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : /blah/something starts with /blah but not /blah/*/blah2*
    Jul  8 00:38:53 ve11a info tmm[29362]: Rule /Common/qux : 172.28.24.1 does not match allowed IP list
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.15 host=172.28.24.10 path=/blah/something
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : /blah/something starts with /blah but not /blah/*/blah2*
    Jul  8 00:39:23 ve11a info tmm[29362]: Rule /Common/qux : 172.28.24.15 matches allowed IP list
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/blah/1/2/blah2/something
    Jul  8 00:39:36 ve11a info tmm1[29362]: Rule /Common/qux : /blah/1/2/blah2/something matches /blah/*/blah2*
    Jul  8 00:39:57 ve11a info tmm[29362]: Rule /Common/qux : *********************
    Jul  8 00:39:57 ve11a info tmm[29362]: Rule /Common/qux : client=172.28.24.1 host=172.28.24.10 path=/somethingelse
    
    • bbensten_8485's avatar
      bbensten_8485
      Icon for Nimbostratus rankNimbostratus
      Nitass, This is very helpful. I have a few follow up questions. 1- As you clearly did above, I want to be able to evaluate multiple URI strings and if not one of those strings, require the client IP to be allowed. Right now, there are 7 evaluations that need to be done and if not one of those, it needs to match the ip list. List is as follows: /blah/blah1 /blah/blah2 /blah/blah3 /blah/blah3/* /blah/blah4/* /blah/blah4/*/foo1/foo2 /blah/blah5/blah6-* 2- Would it make sense to do the list of URI options as a Datagroup list? If so, how would we do that? I really appreciate your help.
  • Data groups don't really support wildcard matching, so you'd necessarily need an if/switch tree for the URI patterns, but then you can absolutely use a data group for the IP list. Try this:

    when HTTP_REQUEST {
        if { [string tolower [HTTP::uri]] starts_with "/blah" } {
            switch -glob [string tolower [HTTP::uri]] {
                "/blah/blah1*" {
                    log local0. "blah1"
                     do something
                }
                "/blah/blah2*" {
                    log local0. "blah2"
                     do something
                }
                "/blah/blah3/*" {
                    log local0. "blah3/"
                     do something
                }
                "/blah/blah3*" {
                    log local0. "blah3"
                     do something
                }
                "/blah/blah4/*/foo1/foo2*" {
                    log local0. "blah4/foo"
                     do something
                }
                "/blah/blah4/*" {
                    log local0. "blah4/"
                     do something
                }
                "/blah/blah5/blah6-*" {
                    log local0. "blah5/6"
                     do something
                }
                default {
                    log local0. [IP::client_addr]
                    if { [class match [IP::client_addr] equals my_ip_list] } {
                         do something
                    }
                }
            }
        } else {
            if { [class match [IP::client_addr] equals my_ip_list] } {
                 do something
            }
        }
    }
    
  • I would add here that it's VERY important to specify the more specific URI patterns before the less specific patterns.