Two Factor Authentication with LINOTP, Google Authenticator (TOTP), and a Juniper MAG

It seems everyone is jumping on the Two Factor authentication bandwagon and for good reason! It is certainly more secure but for non-enterprise customers commercial offerings can be VERY expensive. RSA – the most prominent 2FA provider can easily ring a bill beyond tens of thousands of dollars depending on your size.

In this guide I will show you how to roll your own 2FA using the widely supported Google Authenticator application and  the open-source LINOTP server.

For this guide we will be using Ubuntu Server 12.04, LinOTP, and the Commercial Juniper MAG SSLVPN Appliance as the authentication endpoint that will be requiring two factor authentication.


Before you begin there are a few things you need to prep.

  • An Ubuntu server configured with root access and a static IP address
  • A Juniper MAG Appliance with admin access (I will be using the MAG Virtual Appliance for this)
  • Access to a Device that can act as our authenticator token such as an android smartphone
  • IP connectivity between the Juniper MAG and the Ubuntu OTP Server
  • Accurate time on both the Ubuntu OTP server and the Client 2FA device

Step 1 : installation of LinOTP

This portion should be the simplest portion. Follow the guide from LinOTP here reiterated here for convenience purposes.

Login to your Ubuntu Server and execute the following commands one at a time:

apt-get update
apt-get install python-software-properties -y
add-apt-repository ppa:linotp/stable

apt-get update
apt-get install mysql-server -y    (Be sure to write down the root password!!)

apt-get install linotp -y    (Be sure to write down the OTP Management password!!)

When LinOTP is installed, I highly suggest using Apache for the SSL Support but you can adapt the guide using the linotp2-paster web service which runs on port 5001 by default.

If you accepted the defaults, used apache, and generated a self-signed certificate you can now access the LinOTP management interface with: https:\\[ip-addr-of-linotp]\manage

Step 2 : Initial LinOTP configuration

LinOTP can be configured many way but the most common in a 2FA setup is to have a user login to a device with a Username and Password, then be prompted for a second authentication token that is unique to that user. In order for that Token to be unique to that user, LinOTP needs a list of usernames so it can associate tokens. For this guide we will be manually populating a list of Usernames in a flat file but it is possible to leverage LDAP instead.

Lets start by creating a userlist for LinOTP. This userlist takes the exact form of the /etc/passwd file. For this example I will use the username of testuser. Create a new file:

touch /etc/local-db-passwd
nano /etc/local-db-passwd

Now populate the file with the following sample usernames:

testuser:x:1000::test user,,,::
anotherusername:x:1001::my name,,,::
admin:x:1002::admin name,,,::

Full documentation for the columns are on LinOTP’s website but the key columns are the; first columnthe username, and the third column – the unique userid number used internally by LinOTP.

Once you save the file and exit; in the LinOTP management interface go to users and refresh. You should see you users populate.

Now in the LinOTP interface create a new realm on the left called ‘mag‘,

When you create it, you will be forced to create and associate a new userid resolver. Create a userid resolver named ‘local-db‘ and point it to /etc/local-db-passwd

Finally, lets create a new token and associate it with our test user. Navigate to the users tab and highlight ‘testuser‘, then click the enroll button on the left.

This brings up the token enrollment wizard. Google Authenticator uses the HMAC Time Based tokens with a timestep of 30 seconds. Click the check box to have LinOTP generate an HMAC Key automatically. Once all the relevant options are selected, hit next.

A screen with the enrollment barcode is displayed. Keep this barcode safe! This barcode IS the two factor authentication and you must take measures protect it. The easiest way is to use the camera on your smartphone to scan the barcode from your Google Authenticator application. Once done your app now can function as the two factor authentication.

Step 3 : Radius Integration for LinOTP

We now need to install the FreeRadius components and plugins so it can talk to LinOTP and the MAG appliance.

I followed and adapted the excellent guide here:

Login to your OTP server as root and run the following:

apt-get install freeradius-utils freeradius -y
apt-get install linotp-freeradius-perl -y

rm /etc/freeradius/{clients.conf,users}

mv /etc/freeradius/modules/perl /etc/freeradius/modules/perl.old

Create /etc/freeradius/clients.conf with

nano /etc/freeradius/clients.conf

Paste the following text into /etc/freeradius/clients.conf replacing the Juniper MAG IP address and your chosen Radius NAS password. Note that in the config, we are defining the NAS identifier as ‘vpn’.

client vpn {
ipaddr = [IP-ADDR-of-MAG]
netmask = 32
secret = ‘mypass

client localhost {
# used for testing Radius
ipaddr =
netmask = 32
secret = ‘mypass

Save and quit

Create /etc/freeradius/users.conf with

nano /etc/freeradius/users.conf

Paste the following text into /etc/freeradius/users.conf

DEFAULT Auth-type := perl

Create /etc/freeradius/modules/perl with

nano /etc/freeradius/modules/perl

Paste the following text into /etc/freeradius/modules/perl

perl {
module = /usr/lib/linotp/

Create /etc/linotp2/rlm_perl.ini with

nano /etc/linotp2/rlm_perl.ini

Paste the following text into /etc/linotp2/rlm_perl.ini


Create /etc/freeradius/sites-available/linotp with

nano /etc/freeradius/sites-available/linotp

Paste the following text into /etc/freeradius/sites-available/linotp

authorize {

authenticate {

Activate the linotp rules with

ln -s /etc/freeradius/sites-available/linotp /etc/freeradius/sites-enabled

Start/restart the Radius service with

service freeradius stop
service freeradius start

Now test your 2FA token with Radius and LinOTP with this command:

radtest testuser {YOUR-OTP-NUMBER} 0 mypass

If everything worked you should get an authentication success. If you need to troubleshoot, stop the radius service and run it in debug mode with “freeradius -Xxx” in a separate console window, then try the radtest command again and watch the debug messages.


If you get an Symbol error in FreeRadius like:

freeradius: symbol lookup error: /usr/lib/perl/5.14/auto/IO/ undefined symbol: Perl_xs_apiversion_bootcheck

Follow these instructions to resolve:

  • Get the perl version with: ls -l /usr/lib/perl (mine was 5.14.2)
  • Run the command: export LD_PRELOAD=”/usr/lib/{perl_version}
  • Test

If this works, modify /etc/init.d/freeradius and add this line towards the top after “export $PATH …”

export LD_PRELOAD=”/usr/lib/{perl_version}”

Step 4 : Configuring the Juniper MAG

There are many ways to configure a MAG appliance but I will assume that you have already got one up and running. For this I will assume usage of the Local Auth profile called “System Local” and a user realm called “Users“.

Start by logging into the HTTPS Admin interface for your MAG.

To create a new Auth Server, navigate to ‘Authentication’ -> ‘Auth Servers’. Create a new RADIUS Auth Server called ‘linotp’. Use the following values:

  • The NAS Identifier is ‘vpn’ or what ever NAS ID you used in the FreeRadius Clients.conf
  • Use the OTP server IP address for Radius Server
  • the Shared Secret is ‘mypass’ or what ever password you used in the FreeRadius Clients.conf

All other settings can be left at default.

Now lets modify our user realm (Alternatively you can create your own).

Navigate to ‘Users’ -> ‘User Realms’ -> ‘User Realms’ and click on the ‘Users’ realm

Toward the bottom there is a check box labeled “Use Additional Authentication server“, enable this.

For Authentication #2, select LinOTP.

Since we do not want to require users to have to re-enter their Username, under “Username is…” select “Predefined As” with a value of “<USER>

Leave password set to “specified by user on sign-in page“.

Save you changes and test!

If everything worked well, you should logon with the regular username and password, if successful a secondary prompt is displayed in which you should put in the numeric code given by your Google Authenticator token!