Forum Discussion
Trying to add more restrictions to exiting iRule with flags
Hi, we are trying to additional restrictions based on new IP and URL to existing rule... Below is an example of our current and also NEW iRule. does this look right? is there a better way to do this?
requirement: only source IP can access current allowed URI's and this new URI. We are adding new IP to both "allow_IP" list
current iRulewhen HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } {
set show_flag 0
set allow_flag 0
Set the allow flag as required for each URI below
if { [HTTP::uri] starts_with "/gel/" } {
set allow_flag 1
} elseif { [HTTP::uri] equals "/water/" } {
set allow_flag 1
}
the below filters the URI by IP
if { [class match [IP::client_addr] equals allow_address_data_group ] } {
set show_flag 1
} else {
if { $allow_flag } {
set show_flag 1
}
}
if { $show_flag } {
if { [HTTP::uri] starts_with "/gel/" }{
pool secure_80_pool
} elseif { [HTTP::uri] starts_with "/water/" }{
pool secure_80_pool
} else {
HTTP::redirect "http://deafult-internal.net"
}
} else {
HTTP::redirect "http://default_external.com"
}
}
iRule with new restrictionswhen HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } {
set show_flag 0
set allow_flag 0
new flags for URI and IP respectively
set r1_flag 0
set r2_flag 0
Set the allow flag as required for each URI below
if { [HTTP::uri] starts_with "/gel/" } {
set allow_flag 1
} elseif { [HTTP::uri] equals "/water/" } {
set allow_flag 1
}
Set the allow flag for new URI
if { [HTTP::uri] starts_with "/new-URI/" } {
set r1_flag 1
}
the below filters the URI by IP
if { [class match [IP::client_addr] equals allow_address_data_group ] } {
set show_flag 1
} else {
if { $allow_flag } {
set show_flag 1
} else { [class match [IP::client_addr] equals new_allow_address_data_group ] } {
set r2_flag 1
} else {
if { $r1_flag } {
set r2_flag 1
}
if { $show_flag } {
if { [HTTP::uri] starts_with "/gel/" }{
pool secure_80_pool
} elseif { [HTTP::uri] starts_with "/water/" }{
pool secure_80_pool
} else {
if { $r2_flag } {
if { HTTP::uri] starts_with "/new-URI/" }{
pool secure_80_pool
} else {
HTTP::redirect "http://deafult-internal.net"
}
} else {
HTTP::redirect "http://www.default-external"
}
}
13 Replies
- Brad_Parker
Cirrus
Try something like below. It should be less complicated and more efficient.
when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI start with /gel/ or /water/ validate allowed IP and send it to the pool or redirect if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } If URI start with /new-URIr/ validate allowed IP and send it to the pool or redirect elseif { [HTTP::uri] starts_with "/new-URI/" } { if { [class match [IP::client_addr] equals new_allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } Redirect all other URI else { HTTP::redirect "http://www.default-external" } }- Brad_Parker
Cirrus
Missed a bracket when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI start with /gel/ or /water/ validate allowed IP and send it to the pool or redirect if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } If URI start with /new-URIr/ validate allowed IP and send it to the pool or redirect elseif { [HTTP::uri] starts_with "/new-URI/" } { if { [class match [IP::client_addr] equals new_allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } Redirect all other URI else { HTTP::redirect "http://www.default-external" } } } - JP_42120
Nimbostratus
Hi Brad, thank you. I will try this format. We actually have 10+ URIs in the first filter. I guess it would look like below if we needed to add more. (I'm still new with iRules) :D adding additional URI's in the filter if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" || [HTTP::uri] equals "/dirt/" || [HTTP::uri] equals "/sky/ || [HTTP::uri] equals "/etc/"................}
- Brad_Parker_139
Nacreous
Try something like below. It should be less complicated and more efficient.
when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI start with /gel/ or /water/ validate allowed IP and send it to the pool or redirect if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } If URI start with /new-URIr/ validate allowed IP and send it to the pool or redirect elseif { [HTTP::uri] starts_with "/new-URI/" } { if { [class match [IP::client_addr] equals new_allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } Redirect all other URI else { HTTP::redirect "http://www.default-external" } }- Brad_Parker_139
Nacreous
Missed a bracket when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI start with /gel/ or /water/ validate allowed IP and send it to the pool or redirect if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } If URI start with /new-URIr/ validate allowed IP and send it to the pool or redirect elseif { [HTTP::uri] starts_with "/new-URI/" } { if { [class match [IP::client_addr] equals new_allow_address_data_group ] } { pool secure_80_pool } else { HTTP::redirect "http://deafult-internal.net" } } Redirect all other URI else { HTTP::redirect "http://www.default-external" } } } - JP_42120
Nimbostratus
Hi Brad, thank you. I will try this format. We actually have 10+ URIs in the first filter. I guess it would look like below if we needed to add more. (I'm still new with iRules) :D adding additional URI's in the filter if { [HTTP::uri] starts_with "/gel/" || [HTTP::uri] equals "/water/" || [HTTP::uri] equals "/dirt/" || [HTTP::uri] equals "/sky/ || [HTTP::uri] equals "/etc/"................}
- shaggy_121467
Cumulonimbus
does the irule work as intended in its current state? unless i'm misreading, it looks like $show_flag is always set if $allow_flag was set earlier in the rule, regardless of whether the client-IP is in allow_address_data_group:
if { [class match [IP::client_addr] equals allow_address_data_group ] } { set show_flag 1 } else { if { $allow_flag } { set show_flag 1 } }it seems overly complicated and not very flexible. Why not store your allowed-URIs in a data-group?
when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { if { [ class match [IP::client_addr] equals allow_address_dg ] } { if { [ class match [HTTP::uri] starts_with allow_uri_dg ] } { pool secure_80_pool } else { client-IP matched allow_address_dg but uri didn't match allow_uri_dg HTTP::redirect "http://default.internal.com" } } else { client-IP did not match allow_address_data_group HTTP::redirect "http://default.external.com" } } else { host did not match foo.com } }- JP_42120
Nimbostratus
Hi Shaggy, I was thinking that too when I first saw it, but the app team says it's been working as expected for them. Storing URI's in a datagroup is a great idea. (me newbie :D) it would simplify the irule. thanks!
- shaggy
Nimbostratus
does the irule work as intended in its current state? unless i'm misreading, it looks like $show_flag is always set if $allow_flag was set earlier in the rule, regardless of whether the client-IP is in allow_address_data_group:
if { [class match [IP::client_addr] equals allow_address_data_group ] } { set show_flag 1 } else { if { $allow_flag } { set show_flag 1 } }it seems overly complicated and not very flexible. Why not store your allowed-URIs in a data-group?
when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { if { [ class match [IP::client_addr] equals allow_address_dg ] } { if { [ class match [HTTP::uri] starts_with allow_uri_dg ] } { pool secure_80_pool } else { client-IP matched allow_address_dg but uri didn't match allow_uri_dg HTTP::redirect "http://default.internal.com" } } else { client-IP did not match allow_address_data_group HTTP::redirect "http://default.external.com" } } else { host did not match foo.com } }- JP_42120
Nimbostratus
Hi Shaggy, I was thinking that too when I first saw it, but the app team says it's been working as expected for them. Storing URI's in a datagroup is a great idea. (me newbie :D) it would simplify the irule. thanks!
- JP_42120
Nimbostratus
Combining both methods....
new iRulewhen HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI match allowed URI's if { [class match [HTTP::uri] starts_with allow_URI_data_group ] } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool 80_pool } else { HTTP::redirect "http://deafult-internal.net" } } If URI start with new URI validate allowed IP and send it to the pool or redirect elseif { [class match [HTTP::uri] starts_with new_allow_URI_data_group ] } { if { [class match [IP::client_addr] equals new_allow_address_data_group ] } { pool 80_pool } else { HTTP::redirect "http://deafult-internal.net" } } Redirect all other URI else { HTTP::redirect "http://www.default-external" } } }
- Brad_Parker
Cirrus
Once you start needing that many uri options the data group is the way to go. - JP_42120
Nimbostratus
HI Brad, Actually, the second condition "/water/more.." is a subset of the first URI "/water/...". Would it be possible to negate "/water/more..." in first condition? Is there a better way? new first condition.. when HTTP_REQUEST { if { [HTTP::host] starts_with "foo.com" } { If URI match allowed URI's if { [class match [HTTP::uri] starts_with allow_URI_data_group ] } { Negate if { [class match [HTTP::uri] not_starts_with "/water/more..."] } { if { [class match [IP::client_addr] equals allow_address_data_group ] } { pool 80_pool } else { HTTP::redirect "http://deafult-internal.net" } }......
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