May 13, 2014

Using Netscaler Responder Policies to Redirect Protocol and Path via Hostname

Reblogged from blog.codestructure.com

I needed to ensure that when either of two different hostnames hit a HTTP vserver that they were redirected from HTTP to HTTPS. Additionally they wanted to add a path to the URL based on the hostname in the request.  Then if either of the same requests came to the SSL vserver it would append the path.


An HTTP vserver on 10.10.10.101 - An SSL vserver on 10.10.10.101

If http://serverportal.domain.com move to https, and append /portal.

If http://servermobile.domain.com move to https, and append /mobile.

i.e.
http://serverportal.domain.com -> https://serverportal.domain.com/portal/
https://serverportal.domain.com -> https://serverportal.domain.com/portal/
http://servermobile.domain.com -> https://servermobile.domain.com/portal/
https://servermobile.domain.com -> https://servermobile.domain.com/portal/

Adding the traditional responder redirection (http://support.citrix.com/article/CTX121490) worked when going http to https, but would cause "Too many redirects" when attached to both http and https.  This was because I began using the policy expressions:

Policy 1 - HTTP.REQ.HOSTNAME.CONTAINS("serverportal.domain.com")
Policy 2 - HTTP.REQ.HOSTNAME.CONTAINS("servermobile.domain.com")

And policy action for protocol redirect- "https://"+HTTP.REQ.HOSTNAME+HTTP.REQ.URL"
and policy action for adding the path - "https://"+HTTP.REQ.HOSTNAME+"/portal/" etc.

It kept evaluating the same expression which was to check for the hostname and ended up in a infinite loop.

What I had to do was add additional logic to each expression, for each http to https redirection policy I had it check hostname and protocol.  For https to https I had to check for hostname and additionally evaluate for the missing path:



Policy 1- CLIENT.TCP.DSTPORT.EQ(80) && HTTP.REQ.HOSTNAME.CONTAINS("serverportal.domain.com")
Policy 2 - CLIENT.TCP.DSTPORT.EQ(80) && HTTP.REQ.HOSTNAME.CONTAINS("servermobile.domain.com")


At that point I could to the standard responder action with appended path:

Action 1 - redirect "https://"+HTTP.REQ.HOSTNAME+"/portal/"
Action 2 - redirect "https://"+HTTP.REQ.HOSTNAME+"/mobile/"

And then also do checks for incoming https requests to add the path:



Policy 1 - HTTP.REQ.URL.EQ("/") && HTTP.REQ.HOSTNAME.CONTAINS("\serverportal.domain.com\")
Policy 2 - HTTP.REQ.URL.EQ("/") && HTTP.REQ.HOSTNAME.CONTAINS("\servermobile.domain.com\")

and just redirect to the final destination:



Action 1 - redirect "https://"+HTTP.REQ.HOSTNAME+"/portal/"
Action 2 - redirect "https://"+HTTP.REQ.HOSTNAME+"/mobile/"

I bound the policies for each function by vserver:

HTTP to SSL with path:


SSL to SSL with path:


So http redirects to https+hostname+path, and https redirects to https+hostname+path based on either name and protocol, or name and default path.

Here is what the CLI looks like:

add responder action PORTAL_REDIR_ACT redirect "\"https://\"+HTTP.REQ.HOSTNAME+\"/portal/\"" -bypassSafetyCheck YES
add responder action MOBILE_REDIR_ACT redirect "\"https://\"+HTTP.REQ.HOSTNAME+\"/mobile/\"" -bypassSafetyCheck YES
add responder action PORTAL_PATH_REDIR_ACT redirect "\"https://\"+HTTP.REQ.HOSTNAME+\"/portal/\"" -bypassSafetyCheck YES
add responder action MOBILE_PATH_REDIR_ACT redirect "\"https://\"+HTTP.REQ.HOSTNAME+\"/mobile/\"" -bypassSafetyCheck YES
add responder policy PORTAL_REDIR_POL "CLIENT.TCP.DSTPORT.EQ(80) && HTTP.REQ.HOSTNAME.CONTAINS(\"serverportal.domain.com\")" PORTAL_REDIR_ACT
add responder policy MOBILE_REDIR_POL "CLIENT.TCP.DSTPORT.EQ(80) && HTTP.REQ.HOSTNAME.CONTAINS(\"servermobile.domain.com\")" MOBILE_REDIR_ACT
add responder policy PORTAL_PATH_POL "HTTP.REQ.URL.EQ(\"/\") && HTTP.REQ.HOSTNAME.CONTAINS(\"serverportal.domain.com\")" PORTAL_PATH_REDIR_ACT
add responder policy MOBILE_PATH_POL "HTTP.REQ.URL.EQ(\"/\") && HTTP.REQ.HOSTNAME.CONTAINS(\"servermobile.domain.com\")" MOBILE_PATH_REDIR_ACT


No comments:

Post a Comment