Forum Discussion
Chris_Schaerli_
Nimbostratus
May 12, 2008Redirect or rewrite?
Hi,
I am trying to setup something to direct traffic based on source IP. We are rolling out an application and we want to do it in phased approach.
This is what I had to start.
when HTTP_REQUEST {
if { [IP::addr [IP::remote_addr] equals 10.32.186.0/255.255.252.0] } {
HTTP::redirect “https://site.com/portal/site/NEW"
} elseif {[IP::addr [IP::remote_addr] equals 10.20.20.0/255.255.252.0] } {
HTTP::redirect http://site.com/portal/site/OLD
} elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } {
HTTP::redirect "https://site.com/portal/site/OLD"
}
}
I applied this Irule to both VIPS for http://site.com and https://site.com , but I found when I my traffic was looping. I guess I can’t redirect on the same VIP that I want to direct traffic to? Do I have to use a URL instead of a redirect?
when HTTP_REQUEST {
if { [IP::addr [IP::remote_addr] equals 10.32.186.0/255.255.252.0] } {
HTTP:uri "https://site.com/portal/site/NEW"
}elseif {[IP::addr [IP::remote_addr] equals 10.32.186.0/255.255.252.0] } {
HTTP:uri "http://site.com/portal/site/OLD"
} elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } {
HTTP::uri "https://site.com/portal/site/OLD"
}
}
Thanks,
Chris
13 Replies
- hoolio
Cirrostratus
Hi Chris,
I think you need two different iRules for this. It looks like on the HTTP VIP, you want to redirect specific clients to HTTPS and send the rest to the pool. On the HTTSP VIP, you want to redirect some clients and send the rest to the pool. The syntax you're using for the IP address comparisons and redirects is fine. To send the request to the pool, you can either specify it using the 'pool' command, or just configure a default pool on the VIP and don't specify any action in the iRule. Here's an example for the HTTP VIP:when HTTP_REQUEST { if { [IP::addr [IP::remote_addr] equals 10.32.186.0/255.255.252.0] } { Redirect from the HTTP VIP to the HTTPS VIP HTTP::redirect “https://site.com/portal/site/NEW" } elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } { Redirect from the HTTP VIP to the HTTPS VIP HTTP::redirect "https://site.com/portal/site/OLD" } elseif {[IP::addr [IP::remote_addr] equals 10.20.20.0/255.255.252.0] } { Use the HTTP pool for this request. Or remove this line and the request will go to the default pool on the VIP pool http_pool } }
Aaron - Chris_Schaerli_
Nimbostratus
Aaron,
That logic worked great. I setup two rules, one for HTTP traffic and the other for HTTPS. One new wrinkle. I have now been told this is going to be on a shared VIP. So I can't use the IP based rule alone. I need to look at the URI and if traffic matches a pattern then the IP based rules would pick up the traffic.
This is what my url looks like is this https://foo.com/portal/site/../..
There was a section of code posted earlier this week for matching the URI.
when HTTP_REQUEST {
if {[HTTP::uri] eq "/portl/site/"}
What is the best way to put together the URI and the IP match?
Chris - hoolio
Cirrostratus
Hi Chris,
You can wrap all the logic in the HTTP_REQUEST event in an 'if' statement which checks the path. You basically have it listed in your post above. I'm not sure whether you want to match on the full URI matching /portal/site exactly, the path matching /portal/site exactly or the path starting with /portal/site. Here's an example which checks if the path is exactly /portal/site/.when HTTP_REQUEST { if {[HTTP::path] eq "/portl/site/"} if { [IP::addr [IP::remote_addr] equals 10.32.186.0/255.255.252.0] } { Redirect from the HTTP VIP to the HTTPS VIP HTTP::redirect “https://site.com/portal/site/NEW" } elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } { Redirect from the HTTP VIP to the HTTPS VIP HTTP::redirect "https://site.com/portal/site/OLD" } elseif {[IP::addr [IP::remote_addr] equals 10.20.20.0/255.255.252.0] } { Use the HTTP pool for this request. Or remove this line and the request will go to the default pool on the VIP pool http_pool } } }
Aaron - Chris_Schaerli_
Nimbostratus
Aaron,
I have put something like this out, but all the traffic is falling though to the "else" condition. If I had to guess It is bombing because I need both the path and source IP to true for it to go to the pool. Is this correct?
when HTTP_REQUEST {
if { [HTTP::path] eq "/FOO/"} {
if { [IP::addr [IP::remote_addr] equals 10.12.126.248/255.255.255.255] } {
pool FOO.COM-80 }
if { [IP::addr [IP::remote_addr] equals 10.12.126.249/255.255.255.255] } {
pool FOO.COM-80 }
if { [IP::addr [IP::remote_addr] equals 10.12.126.250/255.255.255.255] } {
pool FOO.COM-80}
if { [IP::addr [IP::remote_addr] equals 10.24.69.2/255.255.255.255] } {
pool FOO.com-80}
} elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } {
HTTP::redirect "http://www.NEW.com"}
} - Colin_Walker_12Historic F5 AccountHere's a slightly cleaned up version. The logic looks correct. I'm not sure why requests would be falling through assuming you have the path and IP correct in the request. Have you tried adding some logging statements to see what values are coming through in your request packets?
when HTTP_REQUEST { if { [string tolower [HTTP::path]] eq "/foo/"} { switch [IP::addr [IP::remote_addr]] { 10.12.126.248/255.255.255.255 - 10.12.126.249/255.255.255.255 - 10.12.126.250/255.255.255.255 - 10.24.69.2/255.255.255.255 - default { pool FOO.com-80 } } } elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } { HTTP::redirect "http://www.NEW.com"} } }
Colin - Chris_Schaerli_
Nimbostratus
Colin,
I am having a problem getting the rule to build. I get an error in the I-rule editor on the first line. Am I missing a bracket? - Colin_Walker_12Historic F5 AccountThe first line looks fine, but I did make the mistake of assuming that you could use the IP::addr command in this way. Since the IP::addr command takes two arguments, you won't be able to use it in a switch statement. That means you'll have to use a series of if/else comparisons if you want to compare network ranges with multiple destinations. Since your example only uses a single pool as a destination, you could use the or command instead of multiple ifs.
So, if you're just comparing single IP addresses, you could do so like:when HTTP_REQUEST { if { [string tolower [HTTP::path]] eq "/foo/"} { switch [IP::remote_addr] { 10.12.126.248 - 10.12.126.249 - 10.12.126.250 - 10.24.69.2 - default { pool FOO.com-80 } } } elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } { HTTP::redirect "http://www.NEW.com" } }
If you need to compare network ranges, and therefore need the IP::addr command, you would want something more like:when HTTP_REQUEST { if { [string tolower [HTTP::path]] eq "/foo/"} { if {([IP::addr [IP::remote_addr] equals 10.12.126.248/255.255.255.255]) or ([IP::addr [IP::remote_addr] equals 10.12.126.249/255.255.255.255]) or ([IP::addr [IP::remote_addr] equals 10.12.126.250/255.255.255.255]) or ([IP::addr [IP::remote_addr] equals 10.24.69.2/255.255.255.255]) } { pool FOO.com-80 } } elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } { HTTP::redirect "http://www.NEW.com" } }
Hopefully this helps,
Colin - Chris_Schaerli_
Nimbostratus
Ok Colin,
Made a couple changes and it is sort of working now. I think I need a condition for "and" so that I catch both the URI and the IP. It looks like right now once it hits the matches_regex it does not evaluate the rest of the expression. So it is not evaluating the IP.
when HTTP_REQUEST {
if { [HTTP::uri] matches_regex {\/FOO\/}} {
if {([IP::addr [IP::remote_addr] equals 10.12.126.248/255.255.255.255]) or
([IP::addr [IP::remote_addr] equals 10.12.126.249/255.255.255.255]) or
([IP::addr [IP::remote_addr] equals 10.12.126.250/255.255.255.255])
} {
pool FOO.com-80
}
} elseif {[IP::addr [IP::remote_addr] equals 10.0.0.0/255.0.0.0] } {
HTTP::redirect "http://www.NEW.com"
}
} - Colin_Walker_12Historic F5 Account1.) I don't think you need a regular expression for this kind of match. You can probably achieve this with string commands just as easily. This wouldn't stop the solution from working, just add un-needed overhead.
2.) The reason you don't need an "and' statement is because you're using a pair of nested "if" statements. The second if statement only gets evaluated if the first if statement returns true. As such, there is an implied "and" between the two, since the second only happens if the first is true.
Does that help? Is this working now, or are you still having issues?
Colin - Chris_Schaerli_
Nimbostratus
I switched to the matches_regex because the eq never seemed to hit.
I did a TCPdump on the bigip and I could see traffic that matched both conditions come in, but I was always sent to the redirect condition.
Once I switched to the regex it looked like things were working, but when I took my IP out of the rule for the second part of the test I was still able to get in, so I was questioning if the rule was evaluating the IP and the URI.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects