Tutorial: Google Authenticator as 2-factor authenticator for NetScaler

13 Apr

So this is kind of nerdy but it’s also very cool. And poorly documented, so it’s nice figuring it out. Keeps me off the street 🙂 It is possible to use Google Authenticator as a second factor to authenticate to your NetScaler. And it’s not really hard to implement as well. So if you read Citrix’s blog about it you will see they’re using OpenOTP. The rest of the document is incomplete and give you very little instructions how to install. I will try to write a complete tutorial on how you can acchieve it. Let’s go!

Shopping list:
• A fully configured NetScaler. Not going to cover that. You just need to add the RADIUS authentication policies in the end. I’ll show you how.
• An installed CentOS/RedHat VM (or any other distro you feel comfortable with). This tut is written for CentOS/RedHat though. You must be able to find your way in Linux (using vi etc). Not going to cover that either.
• WebADM with WebApps & Services AND the OpenOTP Radius Bridge for the correct platform (x86/x64) which both can be downloaded here
• A mobile device with Google Authenticator installed
• A working Active Directory domain controller that allows LDAPS. Note: You need the Schema Master to extend the Schema.
• And ofcourse a domain admin account with Schema Admin permissions as well; cause we’re going to extend the schema.
• A service account that is allowed sufficient permissions to the Active Directory. The admin manual isn’t really clear about this. For sure read is needed. Furthermore write permissions are needed to the OU you’re going to create later on.
• A nice tool to edit AD. Like AD Explorer

I think that’s about it. Let’s proceed.

Installing and enabling services

Login to your Linux host and use the following commands to install the required packages:

yum install glibc.i686 libgcc.i686 ntp mysql-server mysql compat-libstdc++-33 compat-libstdc++-33.i686

Next start and enable your MySQL and NTPD services (note. configure your host as ntp client to prevent time sync issues (which in return can cause authentication failures)).

service mysqld start
service ntpd start
chkconfig mysqld on
chkconfig ntpd on

Configuring the WebADM database

First secure mysql with the following command. The default root password is empty. Set a new one. Remove anonymous users and test databases. Disable remote root logins etc.


Next create the database. Login to MySQL with the following command. Enter the newly created MySQL root password.

mysql –uroot –p

And create the database (replace the user and password part)

create database webadm;
GRANT ALL PRIVILEGES ON webadm.* TO 'webadm_user'@'localhost' IDENTIFIED BY 'password';

Unzipping WebADM

If you followed my shopping list you’re now in the proud possession of two .gz files. One contains the WebADM with WebApps & Services and the other one the OpenOTP Radius Bridge. Use a tool like WinSCP to copy both files to your Linux host. Eg the /tmp directory. Now use the following command to gunzip both archives:

cd /tmp
gunzip webadm_file.gz
chmod +x webadm_file.sh

Installing WebADM

The installation of WebADM couldn’t have been made much easier. Just fire up the setup script with:


You will see the WebADM installation script. You need to enter some simple data like the hostname and your company. In my case I have chosen to integrate with Schema Extension. If you really don’t want this read the manual how you need to configure without Schema Extension.

WebADM v1.3.3-2 Self Installer
Copyright (c) 2010-2015 RCDevs SA, All rights reserved.
Please report software installation issues to bugs@rcdevs.com.

Install WebADM in '/opt/webadm' (y/n)? y
Extracting files, please wait... Ok
Removing temporary files... Ok
Run WebADM setup script now? (y/n)? y
Checking system architecture...Ok
WebADM proposes 3 default configuration templates:
1) Default configuration (Novell, eDirectory, Oracle, OpenLDAP)
2) Active Directory with schema extention (preferred with AD)
3) Active Directory without schema extention
Choose a template number or press enter for default: 2
Enter the server fully qualified host name (FQDN): lx2.darpa.local
Enter your organization name: markbrilman.nl

Generating WebADM CA private key... Ok
Creating WebADM CA certificate... Ok
Generating Rsign server private key... Ok
Creating Rsign server certificate request... Ok
Siging Rsign server certificate with WebADM CA... Ok
Generating HTTP server private key... Ok
Creating HTTP server certificate request... Ok
Signing HTTP server certificate with WebADM CA... Ok
Creating webadm system user... Ok
Adding WebADM CA certificate to the local trust list... Ok
Setting file permissions... Ok
Adding WebADM user to dialout group... Ok
Do you want WebADM to be automatically started at boot (y/n)? y
Adding startup scripts... Ok
Do you want to register WebADM logrotate script (y/n)? y
Adding logrotate scripts... Ok
Do you want to generate a WebADM secret key in webadm.conf (y/n)? y
Generating secret key string... Ok
WebADM has successfully been setup.
Please read the INSTALL and README files in /opt/webadm/ to configure WebADM.

Repeat steps for the Radius Bridge, which is a simple setup.

WebADM configuration files

The first config file we’re editing is the servers.xml (/opt/webadm/conf/servers.xml). This file contains the connection data for your domain controller(s) and your SQL Server. Note that the first (primary) domain controller must be the Schema Master (else your Schema Extension will not work).

The second config file is the webadm.conf (/opt/webadm/conf/webadm.conf) file. This file contains some important WebADM configuration.

The proxy user is the service account to be used for WebADM. It needs to be entered as distinguished name (DN).

proxy_user "CN=WebAdm Service Account,OU=Service Accounts,OU=DARPA,DC=darpa,DC=local"
proxy_password "password"

The super_admins value contains the DN’s of the superadmins of WebADM. You can ofcourse add multiple accounts or groups.

super_admins "cn=Administrator,cn=Users,dc=darpa,dc=local", \
"cn=Domain Admins,cn=Users,dc=darpa,dc=local", \

I disabled other_admins. I don’t need them but later on your setup will get stuck if you leave them enabled

#other_admins "cn=Other Admins,cn=Users,dc=mydomain,dc=com"

So this is the OU structureI mentioned in my shopping list. You need to create the OU and the containers in the OU with a tool like AD Explorer by hand.

# Find below the LDAP containers required by WebADM.
# Change the container's DN to fit your ldap tree base.
# WebADM Optionsets container
optionsets_container "cn=OptionSets,ou=WebADM,dc=darpa,dc=local"
# WebApp configurations container
webapps_container "cn=WebApps,ou=WebADM,dc=darpa,dc=local"
# WebSrv configurations container
websrvs_container "cn=WebSrvs,ou=WebADM,dc=darpa,dc=local"
# Mount points container
mountpoints_container "cn=Mountpoints,ou=WebADM,dc=darpa,dc=local"
# Domain and Trusts container
domains_container "cn=Domains,ou=WebADM,dc=darpa,dc=local"
# Clients container
clients_container "cn=Clients,ou=WebADM,dc=darpa,dc=local"


Ready to start!

Now let’s start WebADM using the following command:

/opt/webadm/bin start

Starting up WebADM should look like this:

Checking system architecture... Ok
Checking SELinux status... Warning (SELinux enabled)
WebADM may not work properly with SELinux enforcement enabled.
Checking libudev dependency... Ok
Checking server configurations... Ok

No Enterprise license found (using bundled Freeware license)
Contact sales@rcdevs.com for commercial information

Starting WebADM PKI server... Ok
Starting WebADM Session server... Ok
Starting WebADM HTTP server... Ok

Connected LDAP server: LDAP Server (dc3.darpa.local)
Connected SQL server: SQL Server (localhost)
Connected PKI server: PKI Server (localhost)
Connected Session server: Session Server (localhost)

Checking LDAP proxy user access... Ok
Checking SQL database access... Ok
Checking PKI service access... Ok

If you receive errors you have some troubleshooting to do. All should work well if you followed this guide. If you have Schema errors check that the superadmin account is schema admin and your first LDAP server holds the Schema Master FSMO role. If you have database errors… well.. the error says it all… 🙂

Assuming you did not receive errors your ready to connect. Connect to the webinterface https://centos_host_fqdn . Don’t mind the cert error, you can download the Root CA cert later on. The first time you need to login with the DN of the superadmin account.

Eg: cn=Administrator,cn=Users,dc=darpa,dc=local + password.

In the next screen you have some buttons to extend the schema and setup the database. I would love to show them to you but I already performed all the Schema Extensions. But they cannot be missed, you have big red letters telling you your setup is not complete until the button is clicked. After performing your Schema Extensions and your database setup you’re ready to create your WebADM domain.

Creating the WebADM LDAP Domain

Navigate to Create > WebADM LDAP Domain


Add the LDAP Domain in the WebADM domain container


Registering OTP & QR Server

This can easily be done on the main page. Just click register and register the required services.


Registering a token

Now the really fun part. Connecting your Google Authenticator to the domain user. On the left side browse for the user. Click the user and choose OTP & U2F Authentication Server (x actions).


Next click Register/Unregister OTP tokens. You will be presented with the option to configure the token.


Choose the QR (Time Based) token and fire up your Google Authenticator. Scan the code…. The magic is done. Time for testing. Return to the OTP & U2F Authentication Server (x actions) menu and this time choose Test User Login.


Type the LDAP Password and the Google Authenticator code. And……:



Configuring the users WebADM settings

Again browse for the user on the left side. This time select the WebADM settings for the user.


Select the OTP option and configure OTP and TOKEN for the user.


All done and almost there.

Configuring Radius

The NetScaler needs to use OpenOTP as a RADIUS server. You already downloaded and installed the Radius server. Now it’s time to configure. We need to configure two files of the Radius component. First the /opt/radiusd/conf/clients.conf . This file contains the allowed clients for the Radius server plus the shared secret. I just added the vlan my NetScalers are connected to.

client {
secret = your_shared_secret
shortname = NetScaler-VLAN-10

I also disabled the default allow rule from RCDevs

# By default, OpenOTP Radius Bridge allows any client to connect
#client {
# secret = testing123
# shortname = any

Changing listening ports

In my case something’s already running on port 8080 which conflicts with the SOAP HTTP Port. I decided to change this port which can easily be done in the /opt/webadm/bin/webadm file

export HTTP_PORT_STD=8180
export HTTP_PORT_SSL=443
export SOAP_PORT_STD=8181
export SOAP_PORT_SSL=8443

However if you decide to do so you also need to edit the /opt/radiusd/conf/openotp.conf file

# Server URL(s):
# OpenOTP SOAP service URL(s). This is the only mandatory setting.
# Two server URLs can be configured and separated by a comma.
# When two servers are configured, you may choose a request routing policy below.
server_url = ""

Don’t make the mistake like I did to enter the HTTP_PORT_STD in your server_url. It needs to be the SOAP_PORT_STD. If you make the same mistake you will get authentication failures that are poorly logged. It took me some time to figure out what was wrong. So that’s about it. The final step is to configure a basic RADIUS Authentication Server and Policy on your NetScaler. I’m not going to take a deep dive into this cause it’s quite easy. Fire up your NetScaler Management Console and browse to the Authentication > Radius > Server tab.


Add the IP of your Linux host. Port is (1812 (which is UDP, so check your firewall config)). Configure the shared secret you configured in your /opt/radiusd/conf/clients.conf file.


Add the Authentication policy which just says ns_true (true).


Open up the NSGW or AAA vServer and click the + sign to add a secondary authentication method.


And bind the Radius Policy to the vServer.

Wow documenting this took me way longer then expected. But it is kinda cool. Have fun configuring and please let me know if you have updates on this document.


  • Stephan Fuchs, is saying:

    Thx a lot for this good tutorial, now my NetScaler is capable of using Google Authenticator 🙂

    Reply this message
  • Robert Carrico, is saying:

    So it is not possible to use two-factor without AD? I just want two-factor for a single VPN user account that I was hoping could be a local user account on the Netscaler.

    Reply this message
    • mark, is saying:

      In this setup you need AD. I never played around with local netscaler accounts. Not sure it’s possible.

      Reply this message
  • Urs, is saying:

    Looks great for just enabling one user.
    But do I really need to alter the AD-Schema? Usually, that is not so wanted because of support issues.
    And how could I enroll such a thing for > 10K Users with self registering for them on the first attempt of login at the netscaler? Can it be done?

    Reply this message
    • mark, is saying:

      Hi Urs,

      I think I read somewhere Schema extension is not necessary. It is however the easiest way to implement. Self Registration is on my list to test with NetScaler but I did not manage to find the time yet to test.
      If I have some hours left in the near future I’ll look into it and keep you posted.

      Kind regards,


      Reply this message
  • Arjan Beijer, is saying:

    Looks really cool to setup but i miss enrolling users.

    Can users enroll via a portal or something like that ?
    Really do not want to do this manually with every user standing next to me.

    Reply this message

Leave a Reply