Forum Discussion
Help with pattern match irule required
Need help with an irule to drop the request if pattern is not matched. The link and pattern is always as below whereby only the values will change....such as vid, height, quality values etc
http://myserver.com/getimage.aspx?vid=84687usehttp=0&cat=default&class=books&size=custom&resize=1&dpi=300&quality=90&type=jpg&width=&height=&id=470746
http://myserver.com/getimage.aspx?vid=8461&usehttp=0&cat=default&class=books&size=custom&resize=1&dpi=300&quality=100&type=jpg&width=&height=&id=470784
12 Replies
- Michael_Jenkins
Cirrostratus
Tested this with
through the CLI with success. You could use the tcl string match command to build your filtertclshGood A: Proper pattern set goodA "/getimage.aspx?vid=84687usehttp=0&cat=default&class=books&size=custom&resize=1&dpi=300&quality=90&type=jpg&width=&height=&id=470746" Bad A: Removed vid parameter set badA "/getimage.aspx?usehttp=0&cat=default&class=books&size=custom&resize=1&dpi=300&quality=90&type=jpg&width=&height=&id=470746" Good B: Proper pattern set goodB "/getimage.aspx?vid=8461&usehttp=0&cat=default&class=books&size=custom&resize=1&dpi=300&quality=100&type=jpg&width=&height=&id=470784" Bad B: Swapped parameter location (usehttp & vid) set badB "/getimage.aspx?usehttp=0&vid=8461&cat=default&class=books&size=custom&resize=1&dpi=300&quality=100&type=jpg&width=&height=&id=470784" Match pattern set pattern "/getimage.aspx\?vid=*usehttp=?&cat=*&class=*&size=*&resize=?&dpi=*&quality=*&type=*&width=*&height=*&id=*" echo "A (Good): [string match $pattern $goodA]" echo "A (Bad) : [string match $pattern $badA]" echo "B (Good): [string match $pattern $goodB]" echo "B (Bad) : [string match $pattern $badB]"so an iRule might look like this
when HTTP_REQUEST { You don't have to set the pattern to a variable. you could just as easily paste it in the string match command, but this is a little clean (though not as performant) set pattern "/getimage.aspx\?vid=*usehttp=?&cat=*&class=*&size=*&resize=?&dpi=*&quality=*&type=*&width=*&height=*&id=*" if { not ([string match $pattern [string tolower [HTTP::uri]]]) } { Drop the request drop } } - mikey_webb
Cirrus
Thanks Michael - initial testing here looks good
- mikey_webb
Cirrus
Michael
Can you help again, I now need to have 2 different patterns and if not match on any of them then drop.
I set pattern1 and pattern2 but Seem to be getting the if statement wrong as get a syntax error, or do I now need to use -glob
- Michael_Jenkins
Cirrostratus
You may be better off using a
statement for multiple patterns. something like thisswitchwhen HTTP_REQUEST { switch -glob -- [string tolower [HTTP::uri]] { "/getimage.aspx\?vid=*usehttp=?&cat=*&class=*&size=*&resize=?&dpi=*&quality=*&type=*&width=*&height=*&id=*" - "Insert another pattern here" { Looks good. Do nothing } default { Drop the request drop } } - mikey_webb
Cirrus
when HTTP_REQUEST { set pattern1 "/getimage.aspx?vid=&usehttp=&cat=&class=&size=&resize=&dpi=&quality=&type=&width=&height=&id=" set pattern2 "/getimage.aspx?vid=&usehttp=&cat=&shade=&background=&colour="
if { not ([string match "$pattern1" or "$pattern2" [string tolower [HTTP::uri]]]) } { HTTP::respond 400 }}
it does not like the OR
- Michael_Jenkins
Cirrostratus
I'd do something like this. (Random note: The switch command is more efficient and easier to read in this case, so I'd use that. You can check out irule optimizations for more on optimizing if you want.)
when HTTP_REQUEST { switch -glob -- [string tolower [HTTP::uri]] { "/getimage.aspx?vid=*&usehttp=*&cat=*&class=*&size=*&resize=*&dpi=*&quality=*&type=*&width=*&height*&id=*" - "/getimage.aspx?vid=*&usehttp=*&cat=*&shade=*&background=*&colour=*" { Looks good. Do nothing } default { HTTP::respond 400 } } - mikey_webb
Cirrus
Michael J - yes this worked perfectly, only issue now thrown a curveball. Now need no pattern matching to take place at all from private ips. I know private ips are a datagroup called private_net but not sure how to add to the what is working, failing that i know i could have an entry on gtm that would go to different ltm virtual servers but wondering if can do in existing rule.
when HTTP_REQUEST { switch -glob -- [string tolower [HTTP::uri]] { "/getimage.aspx?vid=&usehttp=&cat=&class=&size=&resize=&dpi=&quality=&type=&width=&height&id=" - "/getimage.aspx?vid=&usehttp=&cat=&shade=&background=&colour=" { Looks good. Do nothing } default { HTTP::respond 400 } }
- Michael_Jenkins
Cirrostratus
You can check out these links to get an idea on how to do this and how it works
- IP::client_addr: gets the client ip
- IP::addr: used to compare ip addresses
- DevCentral Question: the first answere from Kevin may help
- Article: half way down there's a snippet for comparing
Basically, you'll need to use the
command for checking, with a datagroup trye for addresses.[class match [IP::client_addr] equals "DATA_GROUP_NAME" ] - mikey_webb
Cirrus
Yes read some of them but still cant get to work fully work, the bad request bit usually. I want to not pattern match anything internal just forward, for external I want to pattern match but if external client match is wrong then a bad request
when HTTP_REQUEST { if { [class match [IP::client_addr] equals private_net] } { Internal IP match - do nothing } else { switch -glob -- [string tolower [HTTP::uri]] { "/getimage.aspx?vid=&usehttp=&cat=&class=&size=&resize=&dpi=&quality=&type=&width=&height&id=" - "/getimage.aspx?vid=&usehttp=&cat=&shade=&background=&colour=" { Looks good. Do nothing } default { HTTP::respond 400 } }
- Michael_Jenkins
Cirrostratus
Try adding some logging like below and see what you're getting. (I did see a little typo in one of the patterns and fixed it)
when HTTP_REQUEST { if { [class match [IP::client_addr] equals private_net] } { log local0. "IP is private" Internal IP match - do nothing } else { log local0. "IP is not private" switch -glob -- [string tolower [HTTP::uri]] { "/getimage.aspx?vid=*&usehttp=*&cat=*&class=*&size=*&resize=*&dpi=*&quality=*&type=*&width=*&height=*&id=*" - "/getimage.aspx?vid=*&usehttp=*&cat=*&shade=*&background=*&colour=*" { Looks good. Do nothing log local0. " Pattern match found" } default { log local0. " Pattern didn't match. Respond 400" HTTP::respond 400 } } } }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com