Forum Discussion
Class match does not appear to work how I expected with contains
All,
I am trying to write an irule that essentially matches a http header value and checks the allowed IPs which can send it. I have created a datagroup called headers (string type as address type does not allow multiple rows with the same IP address), where I hoped to be able to put mutliple header values with a separator as the string and the ip address/range as the value (e.g. header values are dave and matt) - below is an example record in the headers datagroup:
SSSdaveSSSmattSSS:= 10.10.10.5
I was expecting I could do a " class match -value SSSdaveSSS contains headers" however this fails to find a match, however if I change the string in the datagroup to be just "SSSdaveSSS" it matches, and appears to act the same as equals.
Can anyone advise how "contains" works when checking a string in datagroup and/or if there is a way to do a partial match on the string value in the datagroup?
Hi
Then you can :
- Create a data group "string" with header name as key, and IP / IP RANGE as values
header1 := 10.10.10.0/24|10.10.20.0/24|10.50.1.1
Get the header
Check if header in datagroup, and if not, allow (header not filtered)
If header in datagroup, get allowed IPs and range in list
Loop through each IP /range and check if source is included there.
And make a decision.
set allowedips [split [class match -value $hdrtocheck equals ttt] "|"] log local0. "$allowedips" set allowed 0 if { ! ($allowedips equals "") } { foreach ip $allowedips { if {[IP::addr $srcip equals $ip ]}{ incr allowed } } if { $allowed > 0 } { log local0. "$srcip allowed" } else { log local0. "$srcip denied" } } else { log local0. "not checked" }
- Yoann_Le_Corvi1Cumulonimbus
Hi
Then you can :
- Create a data group "string" with header name as key, and IP / IP RANGE as values
header1 := 10.10.10.0/24|10.10.20.0/24|10.50.1.1
Get the header
Check if header in datagroup, and if not, allow (header not filtered)
If header in datagroup, get allowed IPs and range in list
Loop through each IP /range and check if source is included there.
And make a decision.
set allowedips [split [class match -value $hdrtocheck equals ttt] "|"] log local0. "$allowedips" set allowed 0 if { ! ($allowedips equals "") } { foreach ip $allowedips { if {[IP::addr $srcip equals $ip ]}{ incr allowed } } if { $allowed > 0 } { log local0. "$srcip allowed" } else { log local0. "$srcip denied" } } else { log local0. "not checked" }
- Yoann_Le_Corvi1Cumulonimbus
Hi
class match -value SSSdaveSSS will return "10.10.10.5" that is, the value of the name/value pair.
Depending on what you are trying to create a datagroug of type address, then insert name value pair, like this :
10.10.10.0/24 := header1|header2|header3|header4
then use
if { [class match -value $srcIP equals DGallowedheader] contains $headertocheck } { log local0. "allowed" } else { log local0. "denied }
This approach also allows you to use netork range in your datagroup.
Yoann
- MW1Cirrus
apologies meant to hit reply rather than submit as a different answer
- MW1Cirrus
Thanks for the above. I have to admit I hadnt thought of nesting the class match and then contains in one.
On my original code with the string type it doesnt return a match on the contains SSSdaveSSS (running 12.1.3 I had logging in the irule and verified it did not match but if I put a record with a plain SSSdaveSSS underneath a record for SSSdaveSSSmattSSS, or removed the original record it did match ). I'll look to see if I can use the address type.
Unfortunately though I need to check the header value first as this is the element that decides if it should be restricted. I can create a 2nd datagroup with just the list of header values to check first (so it knows it should existing the other datagroup as a value), but was trying to reduce any duplication.
Logic trying to implement
1) request comes in check header value to see if it is a restricted header that can only be sent from specified IPs -- otherwise let request route on.
2) If header matches check if client IP is on the "allowed list", if not return block msg, if matches lsit let request route on.
The issue is there could be multiple IP addresses allowed to send multiple headers.
thanks
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