Forum Discussion
Miron_du_Plessi
Nimbostratus
Nov 03, 2007HTTP Redirect based on URI
Hi,
I have a webserver behind our LTM. Access to the webserver is working correctly when users use the full url of
https://remedy.xxx.net/arsys/home
however we are trying to ensure that they reach the correct webpage even if they type.
https://remedy or
https://remedy.xxx.net
However when they type this they are directed to the default apache page.
To do this on the load balancer instead of the webserver I thought that the following irules should solve the problem.
However it appears to have no effect, and im thinking that the problem may lie with the if statements. I did try and test if the redirect will work without the if statements which appeared to work obviously with errors as expected.
****************************************************
when HTTP_REQUEST {
set uri [HTTP::uri]
if { $uri ends_with "/remedy" } {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
} elseif { $uri ends_with "/remedy.xxx.net" } {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
}
}
****************************************************
when HTTP_REQUEST {
if { [HTTP::uri] ends_with "/remedy"} {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
} elseif { [HTTP::uri] ends_with "/remedy.xxx.net"} {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
}
}
I know there are a few topics already on this subject, which seem to suggest that it is quite easy.
Any ideas.
Regards
Miron
10 Replies
- hoolio
Cirrostratus
Hi Miron,
You can add log statements to your rule and then tail the /var/log/ltm log file (tail -f /var/log/ltm) to see what values you're getting:when HTTP_REQUEST { log local0. "URI: [HTTP::uri]" if { $uri ends_with "/remedy" } { log local0. "URI: [HTTP::uri] matched /remedy check" HTTP::redirect "https://remedy.xxx.net/arsys/home" } elseif { $uri ends_with "/remedy.xxx.net" } { log local0. "URI: [HTTP::uri] matched /remedy.xxx.net check" HTTP::redirect "https://remedy.xxx.net/arsys/home" } }
I think you're mixing up the Host header value and the URI that HTTP::uri returns. If a client requests https://test.example.com/path/to/file.ext, [HTTP::host] will return "test.example.com". [HTTP::uri] will return "/path/to/file.ext".
You probably want to try something like this:when HTTP_REQUEST { log local0. "Host: [HTTP::host], URI: [HTTP::uri]" if { [string tolower [HTTP::host]] eq "remedy"} { log local0. "Host: [HTTP::host] matched remedy check" HTTP::redirect "https://remedy.xxx.net/arsys/home" } elseif { [string tolower [HTTP::host]] eq "remedy.xxx.net" } { log local0. "Host: [HTTP::host] matched remedy.xxx.net check" HTTP::redirect "https://remedy.xxx.net/arsys/home" } }
Alternately, if you want to redirect any request to the VIP that's not made to remedy.xxx.net, you could just do a single test:when HTTP_REQUEST { log local0. "Host: [HTTP::host], URI: [HTTP::uri]" if { not ([string tolower [HTTP::host]] eq "remedy.xxx.net")} { log local0. "Host: [HTTP::host] didn't match remedy.xxx.net; redirecting." HTTP::redirect "https://remedy.xxx.net/arsys/home" } }
Aaron - Miron_du_Plessi
Nimbostratus
Aaron ,
Thanks for the device ill try it out. Looks like ill have to include some statement that checks if the uri is null otherwise it would loop.
Would this be a simple
if { [string tolower [HTTP::host]] eq "remedy" AND [string tolower [HTTP::uri]] eq null} {
Regards
Miron - Miron_du_Plessi
Nimbostratus
Aaron,
Thanks I got it working,what looks like correctly.
I couldnt use null so just Anded with "/" which seems to work.
I will play with the logging which looks usefull.
when HTTP_REQUEST {
if { [string tolower [HTTP::host]] eq "remedy" and [string tolower [HTTP::uri]] eq "/" } {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
} elseif { [string tolower [HTTP::host]] eq "remedy.xxx.net" and [string tolower [HTTP::uri]] eq "/"} {
HTTP::redirect "https://remedy.xxx.net/arsys/home"
}
} - Regarding the null...
Per the HTTP Spec, the URI must always at least be a slash "/". HTTP::uri can never be an empty string.
-Joe - Miron_du_Plessi
Nimbostratus
Joe/Aaron,
Thanks for the help.
I have one small issue now. if a user just types in the following:
http://10.100.100.100
https://10.100.100.100
http://remedy
https://remedy
They are presented with a certificate error(btw the 10.100.100.100 is the remedy server)
but can click okay to accept cert and proceed.
I presume this is because the client is expecting a different certificate. We currently use a wildcard cert
for the *.xxx.net domain
Do you have any advice on how to resolve this.
Miron - hoolio
Cirrostratus
If the client makes a request to the VIP address over HTTPS with a host header value that doesn't match the cert's CN, they'll get the browser prompt to accept the mismatched cert. There isn't anything you can do to eliminate that.
You can try to eliminate the scnearios whereby a user would make a request to the VIP via HTTPS with the wrong Host header value though.
If the client is first making a request via HTTP to the VIP address, you could redirect them to the correct host via HTTPS (https://remedy.xxx.net). They wouldn't get the cert warning then.
Aaron - Miron_du_Plessi
Nimbostratus
Aaron,
So if I can eliminate the the cert warning coming up for:
http://remedy
http://10.100.100.100
That would be usefull
On my standard VIP for port 80 I have the following I rule.
you will notice that I tried to include the third statement instead of the secondhowever this did not work. In fact you couldnt access the webpage at all if you included the third statement instead of the second one
when HTTP_Request{
HTTP::redirect https://[getfield [HTTP::host] "." 1][HTTP::uri]
HTTP::redirect "https://remedy.xxx.net/arsys/home"
Miron - hoolio
Cirrostratus
The second redirect should work:when HTTP_Request{ HTTP::redirect "https://remedy.xxx.net/arsys/home" }
Do you have the rule assigned to an HTTP virtual server on the same IP as the https virtual server? Do you see any errors in /var/log/ltm?
Can you use a browser plugin to LiveHttpHeaders for Firefox or HTTPwatch for IE to see what response is coming back from the VIP? Else, you can use this Codeshare example to log the headers to /var/log/ltm. (Click here)
Aaron - Miron_du_Plessi
Nimbostratus
Aaron,
I found the problem in the rule I submitted. As I had the following when i was
when HTTP_Request{
HTTP::redirect https://[getfield [HTTP::host] "." 1][HTTP::uri]
HTTP::redirect "https://remedy.xxx.net/arsys/home"
}
This was not running the 3rd statement possibly because it reads it similar to java (ie only the first statement)
Anyways that worked well to redirect , however after that the login did not work and the website seemed to be looping the client.
I have added the Firefox live headers output from the two tests
Test 1 - Redirect.txt (Login Fails)
when HTTP_Request{
HTTP::redirect "https://remedy.xxx.net/arsys/home"
HTTP::redirect https://[getfield [HTTP::host] "." 1][HTTP::uri]
}
Test 2 - NoRedirect.txt (Login Works)
when HTTP_Request{
HTTP::redirect https://[getfield [HTTP::host] "." 1][HTTP::uri]
HTTP::redirect "https://remedy.xxx.net/arsys/home"
}
Besides for this problem it looks like it may be beneficial to capture the 302 from the server and replace the http with https. Might just clean up the communication.
After that I can look at protecting the webserver identity.
Miron - Jo_Anglin_5148Historic F5 AccountMiron,
Thanks for sharing your corrected Irule. It worked wonderful for me too.
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