Apr 29

Optimising your NetScaler SSL configuration

I’ve seen a lot of excellent guides around on optimising SSL parameters on NetScaler which is awesome. A lot of them are geared towards obtaining the coveted A+ rating from Qualsys’ excellent SSLLabs test which I think is important as it gives people an easy way to ensure they are compliant to certain level in a world where the goalposts are frequently rapidly moving even if only their SSL settings.

Because there are so many guides out there I was reluctant to write one myself but as you can tell I have.

I also wanted to provide some background as to why we are making these decisions as I have experienced a lot of people blinding following guides but not really having any idea why it is they’re doing what they’re doing which is, I think, quite dangerous. So here we are, if you find it useful, cool, if not, contact me for a full refund.

It’s important to say that I am not some kind of SSL wizard, I’m just someone who’s spent a lot of time working with and thinking about SSL for lots of different customers with sometimes vastly different requirements.

Continue reading

Jun 02

NetScaler 11.0 Swivel integration using NetScaler Rewrite

Update to my previous blog post NetScaler 11.0 Swivel integration here’s anupdate of how to do exactly the same thing only using NetScaler rewrites rather then editing any code on the NetScaler itself.

The reason this is useful is that any updates we make to javascript that comes within the NetScaler firmware may (will probably) need to be redone every time you upgrade your firmware as Citrix may (always) tweak the code between builds. Using rewrite means we only have a very small dependency on certain bits of code remaining the same.

If you’ve already made the changes from my previous blog post I would recommend reverting these before making this change using the following steps:

  1. Remove ‘cp -r /var/vpn/vpn/ /netscaler/ns_gui/vpn/’ command from /nsconfig/rc.netscaler
  2. Delete the following files
    1.  /vpn/vpn/js/gateway_login_form_view_pinsafe.js
    2. /netscaler/ns_gui/vpn/js/gateway_login_form_view_pinsafe.js
  3. Unbind and delete RePol_custom_form_view and It’s associated action

If not you can crack on and create some rewrite policies!

Create the following Rewrite actions: 

add rewrite action ReAct_Pinsafe_AppendEULA replace_all “HTTP.RES.BODY(1000000)” “\”form.append(eula_section,field_login,pinsafe_button,pinsafe_image)\”” -search “text(\”form.append(eula_section,field_login)\”)”

add rewrite action ReAct_Pinsafe_Append replace_all “HTTP.RES.BODY(1000000)” “\”form.append(field_login,pinsafe_button,pinsafe_image)\”” -search “text(\”form.append(field_login)\”)”

add rewrite action ReAct_pinsafe.js insert_after_all “HTTP.RES.BODY(12000)” q{“<script type=\”text/javascript\” src=\”/vpn/pinsafe.js\”></script>”} -search q{text(“<script type=\”text/javascript\” src=\”/vpn/login.js\”></script>”)}

add rewrite action ReAct_Pinsafe_LeftRightVar replace_all “HTTP.RES.BODY(1000000)” q{“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login); \r\n//pinsafe: create pinsafe div  \r\n var left_pinsafebutton =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_button);  \r\n “+ ” var right_pinsafebutton=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_button);  \r\n var left_pinsafeimage =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_image);   \r\n”+” var right_pinsafeimage=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_image); \r\n”} -search q{text(“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login);”)}

add rewrite action ReAct_Pinsafe_ButtonInput replace_all “HTTP.RES.BODY(1000000)” q|”var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton); \r\n”+” //pinsafe: create button input \r\n var Pinsafe = $(\”<input type=’button’ onclick=’showTuring()’ value=’Get Code’></input>\”).attr({‘id’:’Get_Code’,’value’:’Get Code’,’class’:’custombutton login_page’}).appendTo(right_pinsafebutton); \r\n “+” //pinsafe: create turing image /r/n var PinsafeImg = $(\”<br><img id=imgTuring name=imgTuring style=’padding-right:10px; padding-top:10px’ height=’97’ width=’360px’ align=’right’ />\”).appendTo(right_pinsafeimage);\r\n “| -search q|text(“var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton);”)|

add rewrite action ReAct_Pinsafe_ButtonVar replace_all “HTTP.RES.BODY(1000000)” q{“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);\r\n”+”var pinsafe_button=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);var pinsafe_image=$(\”<div></div>\”);\r\n”} -search q{text(“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);”)}

add rewrite action ReAct_Insert_Pinsafe_ButtonVar insert_after_all “HTTP.RES.BODY(1000000)” q{“\r\n var pinsafe_button=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);\r\nvar pinsafe_image=$(\”<div></div>\”);\r\n”} -search q{text(“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);”)}

add rewrite action ReAct_Insert_Pinsafe_ButtonInput insert_after_all “HTTP.RES.BODY(1000000)” q|”//pinsafe: create button input\r\nvar Pinsafe = $(\”<input type=’button’ onclick=’showTuring()’ value=’Get Code’></input>\”).attr({‘id’:’Get_Code’,’value’:’Get Code’,’class’:’custombutton login_page’}).appendTo(right_pinsafebutton); \r\n”+”//pinsafe: create turing image \r\nvar PinsafeImg = $(\”<br><img id=imgTuring name=imgTuring style=’padding-right:10px; padding-top:10px’ height=’97’ width=’360px’ align=’right’ />\”).appendTo(right_pinsafeimage);\r\n”| -search q|text(“var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton);”)|

add rewrite action ReAct_Insert_Pinsafe_LeftRightVar insert_after_all “HTTP.RES.BODY(1000000)” q{“\r\n//pinsafe: create pinsafe div\r\nvar left_pinsafebutton =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_button);\r\n”+”var right_pinsafebutton=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_button);\r\nvar left_pinsafeimage =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_image);\r\n”+”var right_pinsafeimage=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_image);\r\n”} -search q{text(“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login);”)}

Create the following Rewrite policies:

add rewrite policy RePol_Pinsafe_ButtonVar “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_ButtonVar

add rewrite policy RePol_Pinsafe_LeftRightVar “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_LeftRightVar

add rewrite policy RePol_Pinsafe_ButtonInput “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_ButtonInput

add rewrite policy RePol_Pinsafe_AppendEULA “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Pinsafe_AppendEULA

add rewrite policy RePol_Pinsafe_Append “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Pinsafe_Append

add rewrite policy RePol_pinsafe.js “HTTP.REQ.URL.EQ(\”/vpn/index.html\”)” ReAct_pinsafe.js

Create the following Responder Action (this hasn’t changes since the last blog) remembering to insert your Swivel Pinsafe external FQDN where it says <insert swivel SQDN>

add responder action ResAct_pinsafe.js respondwith “\”var pinsafeUrl = \\\”https://<insert swivel FQDN>:8443/proxy/\\\”;\n\”+\”\nfunction showImage(sUrl) {\n\tsUser = document.getElementsByName(\\\”login\\\”)[0].value;\n\tif (sUser==\\\”\\\”) {\n\t\tdocument.getElementsByName(\\\”login\\\”)[0].focus();\n\t} else {\n \”+\”\n\t\t// Find the image using Mozilla compatible approach…\n\t\tvarImg = document.getElementById(\\\”imgTuring\\\”);\n \”+\”\n\t\t//Set the image SRC and make it visible\n\t\tvarImg.src = sUrl + \\\”username=\\\” + sUser + \\\”&random=\\\” + Math.round(Math.random()*100000);\n \”+\”\n\t\tvar imgDiv = document.getElementById(\\\”turingDiv\\\”);\n\t\timgDiv.style.display = \\\”\\\”;\n\t}\n}\n\”+\”\nfunction showTuring() {\n\tshowImage(pinsafeUrl + \\\”SCImage?\\\”);\n}\n\”+\”\nfunction sendMessage() {\n\tshowImage(pinsafeUrl + \\\”DCMessage\\\”);\n}\”\n”

Create the following Responder policy

add responder policy ResPol_pinsafe.js “HTTP.REQ.URL.EQ(\”/vpn/pinsafe.js\”)” ResAct_pinsafe.js

Now you will need to bind these policies to NetScaler Gateway virtual server (or you can bind globally if all NetScaler Gateway virtual servers require Swivel Pinsafe however I would recommend that you bind per virtual server)

My example uses the NetScaler Gateway virtual server name of ‘Vsrv_Gateway’ so you can find and rep;ace with your own NetScaler Gateway virtual server name

bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_ButtonVar -priority 10 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_LeftRightVar -priority 15 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_ButtonInput -priority 20 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_AppendEULA -priority 25 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy RePol_pinsafe.js -priority 30 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_Append -priority 35 -gotoPriorityExpression NEXT -type RESPONSE

bind vpn vserver Vsrv_Gateway -policy ResPol_pinsafe.js -priority 100 -gotoPriorityExpression END -type REQUEST


Sep 28

NetScaler Gateway 11.0 – Multi Domain dropdown

This method is not compatible with NetScaler version 11.0 after build 64.34 since Citrix deprecated the -userdomains vpn vserver parameter. Please see http://support.citrix.com/article/CTX203873 for alternate instructions.

Thanks to Scott Osborne (@VirtualOzzy) for pointing this out to the CUG Networking SIG

When NetScaler 11.0 was released I noticed a couple of interesting things

1. There was a new ‘userdomains’ parameter for VPN virtual servers.

2. ‘gateway_login_form_view.js’, used to write the NetScaler Gateway login form as of version 11.0, contained the following:



I had hoped that this meant that Citrix had built in support for creating multi domain drop downs for NetScaler Gateway virtual servers out of the box with version 11.0. unfortunately this isn’t the case with NetScaler Gateway but it is with AAA virtual servers which now support NFactor authentication (Thanks @NSTipster for the clue!)

Anyway, as much as I appreciate NFactor for AAA virtual servers that was not my goal so I went implementing for NetScaler Gateway.

When’ playing with the userdomains parameter I noticed that setting this adds the domains to a cookie called ‘userDomains’

setting userdomains per vserver:


Cookie created as a result of setting userdomains parameter:


although out of the box this changes nothing for the end user when browsing the NetScaler gateway login page it does give us an interesting opportunity. We can use this cookie to populate our custom drop down menu rather then hard coding into the customized pages. Much nicer.

we only need to make a couple of changes to gateway_login_form_view.js  to bring the preexisting create_drop_down function to life:

Firstly I’ve copied the default gateway_login_form_view.js so we can modify a new file

From shell:

cp /netscaler/ns_gui/vpn/js/gateway_login_form_view.js /netscaler/ns_gui/vpn/js/gateway_login_form_view_domains.js

create a rewrite policy to load this new ‘gateway_login_form_view_domains.js’ rather then the default ‘gateway_login_form_view.js’ when /vpn/index.html is loaded.

From NS CLI:
add rewrite action ReAct_domains_form_view replace_all “HTTP.RES.BODY(120000)” q{“<script type=\”text/javascript\” src=\”/vpn/js/gateway_login_form_view_domains.js\”></script>”} -search q{text(“<script type=\”text/javascript\” src=\”/vpn/js/gateway_login_form_view.js\”></script>”)}

add rewrite policy RePol_domains_form_view “HTTP.REQ.URL.EQ(\”/vpn/index.html\”)” ReAct_domains_form_view

find the following line:

var domain = ns_getcookie(“domain”);

change it to:

var domain = ns_getcookie(“userDomains”);

This will present you with a drop down, albeit ugly and unpopulated with end user readable text



if you inspect the newly generated element you’ll see the userdomains you set previously are present in the code however the option text parameter has not been set.


Find the following line:

var select = $(‘<select name=”domainvalue”></select>’).attr({“size”:”1″,”class”:”domain_select”});

Change it to:

var select = $(‘<select name=”domainvalue”></select>’).attr({“size”:”1″,”class”:”domain_select”,”style”:”width: 360px; height: 40px”});

Find the following line:

var option = $(“<option></option>”).attr({“value”:domains[j],”id”:domains[j]});

change it to:

var option = $(“<option></option>”).attr({“value”:domains[j],”id”:domains[j],”text”:domains[j],”style”:”width: 360px; height: 40px”});



















Much better.. but at the moment still useless until we can use this selection in an expression that can be attached to an authentication policy. In order to see what this could be we check what happens when we submit a login request with a domain selected from the drop down menu



Now if advance HTTP expressions should be used on NetScaler Gateway authentication policies we would have a winner here as we could apply a policy based on the domainvalue value in the HTTP request body but unfortunately we cannot with NetScaler Gateway

back to the old school method of setting a cookie using the drop down menu then.

Find the following line:

//domain drop down markup

Insert the following before it (line 41):

function getCookie(name) { // use: getCookie(“name”);
var re = new RegExp(name + “=([^;]+)”);
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
var today = new Date();
var expiry = new Date(today.getTime() + 28 * 24 * 3600 * 1000); // plus 28 days
var expired = new Date(today.getTime() – 24 * 3600 * 1000); // less 24 hours
function setCookie(name, value) { // use: setCookie(“name”, value);
document.cookie=name + “=” + escape(value) + “; path=/; expires=” + expiry.toGMTString();
function storeValues(form) {
setCookie(“domainvalue”, form.domainvalue.value);
return true;

Find the following line:

var form = $(“<form></form>”).attr({method:’post’,action: action_url ,name:’vpnForm’,autocomplete:’off’, style : ‘magin:0’}).submit(function(event){clean_name_cookie();ns_check(event);});

Insert the following before it (line 41):

var form = $(“<form></form>”).attr({method:’post’,action: action_url ,name:’vpnForm’,autocomplete:’off’, style : ‘magin:0’}).submit(function(event){return storeValues(this);clean_name_cookie();ns_check(event);});

From the NS CLI create an LDAP authentication policy for each domain you wish to authenticate against – in my case lab, stuartc and stuc:
add authentication ldapPolicy AuthPol_LDAP_lab_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=lab” AuthSrv_LDAP_lab_Users

add authentication ldapPolicy AuthPol_LDAP_stuartc_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=stuartc” AuthSrv_LDAP_stuartc_Users
add authentication ldapPolicy AuthPol_LDAP_stuc_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=stuc” AuthSrv_LDAP_stuc_Users

Bind the above policies to your NetScaler gateway virtual server and there you go, authentication to multiple domains from a single NetScaler Gateway using a drop down menu.

Hopefully it wont be long till NFactor is supported on NetScaler Gateway, until then hope this helps someone.
The modified gateway_login_form_view.js can be downloaded here

Sep 25

Swivel Integration – NetScaler 11.0

This post has been updated HERE to achieve the same goal only using NetScaler Rewrite and Responder so we no longer need to modify any files on the NetScaler.

Use the below method if you do not have NetScaler Standard, Enterprise or Platinum edition licensing


For those who may have read my guide to customizing NetScaler Gateway 10.1 UI for Swivel integration (https://www.stuartc.net/blog/tech/swivel-integration-netscaler-10-1/), here’s an update for version 11.0 build 62.10!

For the moment I’ve settled for modifying a copy of the default files rather then doing it all in rewrite and responder because there isn’t enough time in the day 🙂 I may update later without if I get a chance.

Not much has changed really from a Pinsafe point of view, we still want to load js function, add a ‘get code’ button and view a turing image. Easy.

Due to Portal themes being introduced in NetScaler 11.0 the NetScaler UI files have been rewritten to make the application of themes parameters possible, which is good!

tumblr_mruku4p0GM1szisbjo2_250[1]The only problem is none of these changes are documented by Citrix, which is bad..

tumblr_mruku4p0GM1szisbjo3_250[1]Anyway… Here’s how you do it.

We start off by copying the default /vpn/js/gateway_login_form_view.js and and call it /vpn/js/gateway_login_form_view_pinsafe.js

2015-09-25_173405[1]The modify the folowing areas of this new file:






You can download the full file from here: http://i.stuc.uk/gatewayloginformviewpinsafejs

Remmeber to copy the modified /vpn/js/gateway_login_form_view_pinsafe.js file to the /var/vpn/vpn/js/ directory so it’s automatically copied into memory at startup.

Once this is complete you will need 2 rewrite policies inject your custom pinsafe .js files into the /vpn/index.html  and a responder to present the pinsafe function .js file.

These can be created with the following commands (you may need to highlight the below lines of text as my wordpress theme cuts off the end – will fix one day)

Create a rewrite action and policy to use our customized /vpn/js/gateway_login_form_view_pinsafe.js file rather then the default

add rewrite action ReAct_pinsafe_form_view replace_all "HTTP.RES.BODY(120000)" q{"<script type=\"text/javascript\" src=\"/vpn/js/gateway_login_form_view_pinsafe.js\"></script>"} -search q{text("<script type=\"text/javascript\" src=\"/vpn/js/gateway_login_form_view.js\"></script>")}
add rewrite policy RePol_pinsafe_form_view "HTTP.REQ.URL.EQ(\"/vpn/index.html\")" ReAct_pinsafe_form_view

Create a responder action and policy to return the pinsafe js funciton. Replace <PINSAFEFQDN> with the extenral FQDN for your pinsafe turing image.

add responder action ResAct_pinsafe.js respondwith "\"var pinsafeUrl = \\\"https://<PINSAFEFQDN>:8443/proxy/\\\";\n\"+\"\nfunction showImage(sUrl) {\n\tsUser = document.getElementsByName(\\\"login\\\")[0].value;\n\tif (sUser==\\\"\\\") {\n\t\tdocument.getElementsByName(\\\"login\\\")[0].focus();\n\t} else {\n \"+\"\n\t\t// Find the image using Mozilla compatible approach...\n\t\tvarImg = document.getElementById(\\\"imgTuring\\\");\n \"+\"\n\t\t//Set the image SRC and make it visible\n\t\tvarImg.src = sUrl + \\\"?username=\\\" + sUser + \\\"&random=\\\" + Math.round(Math.random()*100000);\n \"+\"\n\t\tvar imgDiv = document.getElementById(\\\"turingDiv\\\");\n\t\timgDiv.style.display = \\\"\\\";\n\t}\n}\n\"+\"\nfunction showTuring() {\n\tshowImage(pinsafeUrl + \\\"SCImage\\\");\n}\n\"+\"\nfunction sendMessage() {\n\tshowImage(pinsafeUrl + \\\"DCMessage\\\");\n}\"\n"
add responder policy ResPol_pinsafe.js "HTTP.REQ.URL.EQ(\"/vpn/pinsafe.js\")" ResAct_pinsafe.js

Create a rewrite action and policy to include our pinsafe.js file when /vpn/index.html loads
add rewrite action ReAct_pinsafe.js insert_after_all "HTTP.RES.BODY(12000)" q{"<script type=\"text/javascript\" src=\"/vpn/pinsafe.js\"></script>"} -search q{text("<script type=\"text/javascript\" src=\"/vpn/login.js\"></script>")}
add rewrite policy RePol_pinsafe.js "HTTP.REQ.URL.EQ(\"/vpn/index.html\")" ReAct_pinsafe.js

Bind to the NetScaler Gateway virutal server that requires Swivel integration

bind vpn vserver VSrv_Gateway -policy RePol_pinsafe.js -priority 90 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver VSrv_Gateway -policy RePol_pinsafe_form_view -priority 100 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver VSrv_Gateway -policy ResPol_pinsafe.js -priority 200 -gotoPriorityExpression END -type REQUEST

That should be it! 

Enter your username and click 'Get Code'

2015-09-25_175644[1]I will change my password 2 prompt later as it’s friday and beer i calling my name 🙂 Hope this helps – any questions let me know in the comments or by email (stuart@stuartc.net)


Dec 21

Swivel integration – NetScaler 10.1

Quick one from a recent deployment. This customer had chosen Swivel (http://www.swivelsecure.com) as their secondary authentication. Swivel requires a Turing image to be displayed on the VPN logon page to provide the user with one time password they need to provide for RADIUS authentication.

Swivel have helpfully provided very detailed guides on how to do this by replacing the index.html and login.js various NetScaler versions which helped a great deal. (https://kb.swivelsecure.com/wiki/index.php/Citrix_Netscaler_Gateway_10.x)

I Wanted to achieve this without changing any files on the NetScaler filesystem because..

1. The customer only wished to use Swivel on a single NetScaler Gateway VServer so we only wanted the turing image to display when users hit that Vserver meaning that simply swapping out the index.html with the customised version Swivel provide was not an option. We could have used responder or javascript to switch between index.html files based on the HTTP.REQ.HOSTNAME but.. well I didn’t want to.
2. I didn’t want to modify any of the files located on the NetScaler. There are a number of reasons for this but mainly to prevent issues with older versions of the index.html and login.js being preserved in a customers customisations after new versions of the appliance is upgraded to a newer version of the firmware.
3. I like the idea of using NetScaler Rewrite and Responder where ever possible. The customer paid for the feature so why not use it?

Anyway.. Here are the policies I used in the end. hope there save someone some time.

Continue reading

Jun 03

OWA 2010 Form Based SSO

  1. I’ve been asked about this a few times recently so thought it worth a post.

As of version 10.69.4.nc NetScaler Gateway and AAA features support OWA 2010

In order to provide SSO when authentication on OWA is form based additional configuration is required.

Create a formSSOAction, this provide the NetScaler with the following information:
  • The page in which to complete the Form based SSO (/owa/auth.owa)
  • The field names to pass the username and password values to (username and password)
  • The cookie that deals with authentication for OWA (cadata)
  • The method in which to submit form data (post)


Continue reading

Feb 20

Windows RT browser based access to Access Gateway Enterprise with WIoNS

During a recent project Citrix Receiver for Windows RT version 1.2 was released to the public and by lucky coincidence a majoy stakeholder in the project happened to be the proud owner of a Windows Surface RT which seemed like an ideal opportunity to try out the new Web Interface support for Windows RT.

Now being honest I have not got this working when users are logging in via the Metro Citrix Receiver app but in my defence I was quite busy. I did however manage to provide access for Windows RT web browsers via Web Interface. Now I know that doesn’t sound ground breaking, and thats because it isn’t really, but it is blog worthy simply because it does not work as I’d expected out of the box.

The reason for this is that we weren’t using Web Interface 5.4 hosted on a Windows Server, we had deployed our NetScalers with Web Interface on NetScaler (WIoNS). An unexpected side effect being I’d not taken into consideration that the default rewrite policies, created when selecting the ‘Enable Access through Citrix Receiver’ tick box in the WIoNS wizard, would not apply to this new mysterious Windows RT browser. 

Essentially the issue is although applications are enumerated on the Web Interface page when you attempt to launch an application all you’re met with a short period of Internet Explorer loading ‘launcher.jsp’ and nothing more. 

Once the following rewrite policies are applied ICA access via Windows RT web browsers shoudl work as expected  (i.e. browse to the Access Gateway Vserver FQDN from the Windows RT web browser, log into the Access Gateway logon page and launch applications from the Web Interface) 

Continue reading

Jan 31

NetScaler Access Gateway 10: Modify secondary authentication prompt with rewrite action

As alot of you will have seen in the article CTX123121 the NetScaler Rewrite feature can be used to modify the look and feel of the Access Gateway logon page, commonly this involves changing the default password prompts created in the login.js file.

As the article states these rules may vary from version to version – and they do so I thought I’d add the correct policy for NetScaler version 10 as it differs slightly form that given for version 9.2 due to a slight change in the version 10 login.js file

Continue reading

Mar 08

Updating Provisioning Server target agent in VMWare

A quick post – nothing ground breaking really but I encountered a customer at the start of this year who encountered this problem but couldn’t seem to find any information online to help so I thought I’d put some info up here. There are a number of other articles on the net that cover the same subject, I’ve included a few within this post.

Provisioning server is a great product for reducing administrative overheads when managing a XenApp or XenDesktop environment – saying that there are still a couple of tasks that require a little extra effort when updating a provisioned image. These tasks are updating the provisioning serve agent itself and either XenServer or VMWare tools..

The problem being you cannot boot your provisioned image into private mode and update these components mainly because if you update these components you generally will interfere with the targets ability to either use the PVS agent (because you’re upgrading it) or contact the PVS server (because you’re in the middle of upgrading the servers virtual NIC drivers).

Because of this you must update these components within an image that is not provisioned which means booting a VM directly to VHD/VMDK.

A number of methods exist to do this (the following links document a few)








This process, although a little long winded in some cases, it’s actually really easy when using Hyper-V or XenServer as they allow direct VHD booting. VMWare however do not utilize the VHD format for their virtual disks sticking with their traditional VMDK format which means we cannot currently direct boot from VHD (too my knowledge – if this has been added in more recent versions please let me know!)

Essentially performing this task in VMWare shouldn’t really prove much more difficult. The method I favour here for updating a provisioned image is to use VMWare Converter to P2V (V2V in this case) your current provisioned image into a non provisioned Virtual machine. This process will treat the provisioned target device as if it were a physical server and copies the contents of the provisioned disk to a new virtual disk located in the VMWare hosts storage and attaches it to a new Virtual Machine – creating a new non provisioned virtual machine using your provisioned image.

From this point you can update your PVS Agent or VM Tools component then use XenConvert/PVS Imaging Wizard to stream the image back from the new Virtual machine back to a Provisioning Server VHD.

As always please feel free to comment if you have any additional methods you’d like to share

Feb 15

Access Gateway Enterprise – Disabling cookies prevents the secondary authentication field displaying

As expected this blog has gone a significant amount of time without update. This is mostly because I’ve not had anything particularly interesting to say.

So yesterday an Access Gateway Enterprise question was posed to me so I thought I would run through it in case anyone else encounters the same problem. It may not be that interesting


A user reported that the secondary authentication field was not displaying when they browsed the Citrix Access Gateway Enterprise logon page. This particular user was using an IPhone but this is incidental and the issue would have occurred for any user with the same browser settings.


While only the first authentication field displayed due to the Access Gateway Enterprise VServer configuration users could not log on using just this password and an access denied error would be displayed if they attempted to logon.


In this example I’ve used Firefox, I’ve done this because it’s got some useful add ons to further illustrate the issue.

When Accessing an Access Gateway Enterprise Vserver with two factor authentication configured (one of more authentication policies bound to the primary and secondary authentication parameters of the VServer.) a user should see the following:

If cookies are disabled within Firefox they will see the following – This shows only a single password field.

Uncheck ‘Accept cookies from sites’ and refresh the page

Click more for an explaination..

Continue reading