cancel
Showing results for 
Search instead for 
Did you mean: 

Class match does not appear to work how I expected with contains

MW1
Cirrus
Cirrus

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?

1 ACCEPTED SOLUTION

Yoann_Le_Corvi1
Cumulonimbus
Cumulonimbus

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"   }  

 

View solution in original post

4 REPLIES 4

Yoann_Le_Corvi1
Cumulonimbus
Cumulonimbus

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

apologies meant to hit reply rather than submit as a different answer

MW1
Cirrus
Cirrus

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

Yoann_Le_Corvi1
Cumulonimbus
Cumulonimbus

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"   }