Forum Discussion
Ip filter iRule with multiple data groups
I currently have an iRule in place to do ip filtering in multiple places in a website. I had an oversight when this was first written and failed to put a rule in for the entire website.
when HTTP_REQUEST {
if { [string tolower [HTTP::uri]] eq "/t/lccc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_lccc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/wwcc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_wwcc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/nwccd/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_nwccd] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/nwc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_nwc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/ewc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_ewc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/cwc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_cwc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} elseif { [string tolower [HTTP::uri]] eq "/t/cc/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_cc] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
} else {
Let the request pass...
}
}
From this point I would like to add something to filter the top level of the site, using each of the above data groups. Would this go after the final "else"? Also, is this the proper way to refer to multiple data groups?
} elseif { { [string tolower [HTTP::uri]] eq "/" } then {
if { [class match [IP::client_addr] equals /Education/tableau_cc, /Education/tableau_cwc,/Education/tableau_ewc, etc, etc, etc ] } then {
Let the request pass...
} else {
HTTP::respond 403 content "Access Denied"
}
}
Thanks
- JG
Cumulonimbus
Would the following do (untested)?
} elseif { { [string tolower [HTTP::uri]] eq "/" } then { set dg_list {dgrp1 dgrp2 dgrp3} set allowed 0 foreach dg $dg_list { if { [class match [IP::client_addr] equals dg] }{ set allowed 1 break } } if { $allowed < 1} { HTTP::respond 403 content "Access Denied" } }
(Replace dgrp* with real data group names.) .
- Stanislas_Piro2
Cumulonimbus
The code is too complicated.
I recommend to create only 2 Datagroups
- /Education/DG_URI containing URI as key and the list of allowed roups as value
- /Education/tableau_global containing IP addresses as key and the group membership as value
Then use following irule.
when HTTP_REQUEST { Search if the URI have an IP address restriction, store the allowed groups in a variable if { [set AllowedGroups [class match -value [string tolower [HTTP::uri]] equals /Education/DG_URI]] ne "" } then { Search if the IP address is known in a the IP addresses Datagroup and filter based on previous search if { [set IPGroups [class match -value [IP::client_addr] equals /Education/tableau_global]] ne "" && ($AllowedGroups contains $IPGroups)} then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } }
Hi shipszky,
If you want to stick to your existing iRule structure then take a look below to see how multiple data-groups can be queried in a serial manner for
.[HTTP::uri] eq /
Note: But I second Stanislas opinion, that an approach with just two data-groups (one to identify the IPs and a second one to identify the URI) makes way more sense (e.g. easier to maintain, better flexibility).
when HTTP_REQUEST { set low_uri [string tolower [HTTP::uri]] if { $low_uri eq "/t/lccc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_lccc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/wwcc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_wwcc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/nwccd/" } then { if { [class match [IP::client_addr] equals /Education/tableau_nwccd] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/nwc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_nwc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/ewc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_ewc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/cwc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_cwc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/t/cc/" } then { if { [class match [IP::client_addr] equals /Education/tableau_cc] } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } elseif { $low_uri eq "/" } then { if { ( [class match [IP::client_addr] equals /Education/tableau_lccc] ) or ( [class match [IP::client_addr] equals /Education/tableau_wwcc] ) or ( [class match [IP::client_addr] equals /Education/tableau_nwccd] ) or ( [class match [IP::client_addr] equals /Education/tableau_nwc] ) or ( [class match [IP::client_addr] equals /Education/tableau_ewc] ) or ( [class match [IP::client_addr] equals /Education/tableau_cwc] ) or ( [class match [IP::client_addr] equals /Education/tableau_cc] ) } then { Let the request pass... } else { HTTP::respond 403 content "Access Denied" } } else { Let the request pass... } }
Note: I've changed your existing syntax slightly so that LTM computes the lower URI just a single time (aka.
at the beginning) and then reuses the computedset low_uri [string tolower [HTTP::uri]]
result for the individual$low_uri
statements.[if]
Cheers, Kai
- shipszky
Altocumulus
Thank you for all these answers everyone. I'm going to go with Kai's as a quick fix, but implement Stanislas's answer once I can get the data groups merged.
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