I’m just setting up a Web Application Firewall on a Citrix NetScaler 11.1 for a costumer’s shop. My costumer mandated: most of the website has to be available via HTTP. However we don’t want to expose sensitive information to the internet, so we had to create a policy redirecting users to SSL whenever needed.
So how can we do this? First of all, I had to find out: which information is sensitive? It takes some time, you have to explore the application (basically a webshop).
Next: how to redirect to SSL, and thereby preserve the URL?
The policy expression
The policy has to be flexible. I want to be able to redirect users from where ever to the same URL via https. So my policy has to be a responder policy. Subtype: redirect.
add responder action res_act_send2ssl redirect
"\"https://\"+HTTP.REQ.HOSTNAME + HTTP.REQ.URL.HTTP_URL_SAFE"
-responseStatusCode 302
Rather trivial.
What does it do? It redirects to "https://"
, appends the server name specified (HTTP.REQ.HOSTNAME
). If there is just one host name you could rather do something like "https://hostname.exampe.com"
. Next it appends the URL (HTTP.REQ.URL
). The parameter HTTP_URL_SAFE
is not needed. It converts all URLs into save URLs, so for examlpe /logon Page
is converted into /logon%20Page
. It’s good practice to do so.
Last, not least: the HTML status code: I’m usually very exact about HTML status codes: 302 is a temporary redirect, while 301 is a permanent redirect. There is no difference from the perspective of a browser: the browser will redirect. However crawlers, like Google™, will make a big difference: it will follow a 301 (and delete the previous content from its an index), it might not follow a 302 (as it is only a temporary redirect and will be gone soon). In this case, we didn’t want crawlers to follow, so we stayed with 302, the Citrix NetScaler default.
The policy
My policy had to be flexible. One of the requirements: We need to add URLs to it, when we come across a new URL. So I came up with the idea to use a Pattern Set.
Pattern Set
I prefer string maps over expression1 || expression2 || ... || expressionn
constructions for several reasons: It’s more effective from the perspective of NetScaler RAM and CPU (so it causes less load to NetScalers), and even more important, it’s easier to understand, and it’s easier to maintain. Just add another URL to the Pattern Set.
add policy patset WebApp_secureURLs bind policy patset WebApp_secureURLs "/login" -index 1 ...
so this will create a Patern Set, containing URLs. This URLs will be used in the policy expression. You’ll simply have to add URLs if you need SSL for additional URLs
The Policy expression, using a pattern set
add responder policy res_pol_send2ssl "HTTP.REQ.URL.CONTAINS_ANY(\"WebApp_secureURLs\")" res_act_send2SSL
This will create a policy expression using a pattern set. HTTP.REQ.URL
us the URL (not containing the hostname), CONTAINS_ANY
means, the URL has to contain any of the objects inside my pattern set. We could also use EQUALS_ANY
or ENDSWITH_ANY
. It depends on, whether you are able to specify the URL exact enough or not (we can’t). (\"WebApp_secureURLs\")
specifies the pattern set to be used. The double quotes "
have to be masked with \"
in command line as policy expressions have to be set in double quotes (" ... "
).
Hallo Johannes, danke für den interessanten Blogpost. Du sprichst anfangs vom Thema Web Application Firewall. Mich (und ich denke viele andere Leser) interessiert, wie ich via NetScaler diese Web Application Firewall gezielt für das Reverse Proxying von diversen Websiten abbilden kann. Bei einer Sophos als Reverse Proxy kann ich leicht Funktionen wie SQL Injection, Web Application, AV usw anhaken. Mir fällt es schwer bei Kunden verargumentieren zu können, dass der NetScaler dies auch kann, da ich nicht weiß, wo und wie das einzurichten ist. Hättest du Lust darüber einen Blogpost zu verfassen, oder hast du schon Referenzen, welche du evtl. teilen möchtest?
Vielen Dank und viele Grüße aus Freiburg
Julian Jakob
Im Prinzip gerne. Im Moment bin ich aber sehr beschäftigt, es kann dauern 🙂