×

Warning

JUser: :_load: Unable to load user with ID: 63
06 Dec 2013

Securing VMware View With Google Authenticator and Freeradius

I've always wanted to find a cost effective way to implement 2-factor authentication. Commercial solutions are expensive, and if you are a small business, you might not want to spend a small fortune on implementing an enterprise solution with hardware tokens. I stumbled across Google Authenticator a while back and started to wonder how it can be used to implement a free 2-factor authentication solution in my lab. I also found a few posts that suggested teaming it up with Freeradius and that's really where this post started.

 

After several attempts, I've managed to find a quick and easy way to get it working. Well, at first glance you'll probably disagree as this is quite a lengthy post, but the steps required to implement the solution are actually very simple. In this blog post, I've tried to explain each step in order. I do not expect everyone to be a Linux expert, and I kept that in mind whilst writing this post. To be honest, this is version 0.1 of this post and I'll probably expand this post over the next few weeks to include overall solution diagrams and extra information. For now, I've managed to at least write up the steps required to implement the solution.

Overview

This solution is based on CentOS 6.3. You can use any other Linux distribution, but the instructions in this post are CentOS/RHEL specific. We will be using Freeradius, an open source Radius server as the main component. Freeradius will make use of Pluggable Authentication Modules (PAM) and PAM will call upon Google Authenticator which is basically a module that is written for PAM. Google Authenticator will verify a user's password together with a token code that changes every 30 seconds. The user will make use of the Google Authenticator mobile APP to obtain a new token code every time a new login is required.

To finish, we will configure VMware Horizon View to make use of RADIUS authentication, and to contact the Freeradius server whenever a user requests a new connection using the View Client.

Checking DNS:

Before we do anything, we need to be sure tha the server is able to resolve it’s own hostname via DNS.

[root@radiussrv ~]# ping radiussrv
PING radiussrv.spiesr.com (192.168.1.19) 56(84) bytes of data.
64 bytes from radiussrv.spiesr.com (192.168.1.19): icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from radiussrv.spiesr.com (192.168.1.19): icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from radiussrv.spiesr.com (192.168.1.19): icmp_seq=3 ttl=64 time=0.044 ms
64 bytes from radiussrv.spiesr.com (192.168.1.19): icmp_seq=4 ttl=64 time=0.041 ms
^C
--- radiussrv.spiesr.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3199ms
rtt min/avg/max/mdev = 0.034/0.040/0.044/0.003 ms

 

Installing NTP to Ensure Accurate Server Time:

yum install ntp
/etc/init.d/ntpd start
chkconfig --level 345 ntpd on

 

Disabling SELinux:

Ah SELinux. SELinux is going to get in our way. We can configure SELinux to work with Freeradius, PAM and Google Authenticator, but for the sake of this document, I’ll just disable SELinux. If you need SELinux, please go and read the SELinux documentation in order to configure it properly. 

Also, as the configuration we are about to do, can be tricky, disabling SELinux now will ensure that it’s not the cause of any issues if we run into issues later on.

To disable SELinux in run-time, enter the following command:

setenforce 0

 To disable SELinux permanently (persist through reboots), edit the file /etc/selinux/config

Change the line that reads 

SELINUX=enforcing

 to read

SELINUX=disabled

 

Disabling the Linux Firewall

Another thing that could get in our way whilst troubleshooting, is the firewall. Let’s disable the Linux iptables firewall now, for both IPv4 and IPv6

service iptables stop
service ip6tables stop

 We can permanently turn off iptables and prevent it from starting up with the server with the chkconfig command:

chkconfig iptbales off
chkconfig iptables off

 Ensure that both versions of iptables have been turned off:

chkconfig --list | grep tables
ip6tables       0:off   1:off   2:off   3:off   4:off   5:off   6:off
iptables        0:off   1:off   2:off   3:off   4:off   5:off   6:off

 

Installing wget

We will be using wget to download the RepoForge (RPMForge) RPM file in order to install it. Using yum, let’s install wget now:

 yum install wget

 

Installing the RepoForge (RPMForge) Repository

Google Authenticator can generate QR codes that contain the keys used to configure your mobile Google Authenticator app. This is not required, but it does help to quickly and accurately configure your mobile app simply by scanning the generated QR code. QR codes can be generated in Linux using the qrencode library. When generated, the QR code will be displayed on screen or in the SSH session.

Unfortunately, the qrencode library is not included in the standard CentOS/RHEL repositories. It is however located in the RPMForge (now known as RepoForge) repositories. We will now add the RPMForge repository to the server in order to use yum to download and install the library, along with everything else that we’ll need.

Using wget, download the RPMForge Repository RPM file to /var/tmp:

cd /var/tmp
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm

With the RPM downloaded, install it with the following command:

rpm --ivh rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm

 Ensure the RPMForge Repository is available

yum list --enablerepo=rpmforge-extras

 Check to see if the qrencode library is available to be installed

yum list qrencode
Loaded plugins: fastestmirror, presto
Loading mirror speeds from cached hostfile
 * base: mirrors.vooservers.com
 * extras: centos.mirroring.pulsant.co.uk
 * rpmforge: ftp.nluug.nl
 * updates: mirrors.vooservers.com
Available Packages
qrencode.x86_64                             3.2.0-1.el6.rf                             rpmforge

 

Ensuring Linux Build Tools are Installed

When we download the Google Authenticator PAM module later, it will be cloned from a git repository to the local server. This means that we will be downloading source code that we will have to compile and install as binaries. To enable us to compile source code, we need a C compiler and a utility called make. Install all build tools using yum in a single line:

yum install gcc cpp make

 

Installing Screen

This is not a required component, but I find it very useful. Install screen using yum:

yum install screen

 

Installing the Required Packages 

With the pre-requisites in place, let’s install the software we need to proceed:

yum install pam-devel freeradius freeradius-utils git qrencode

 

Download Google Authenticator PAM Module Source

We need to download the Google Authenticator source code, compile it and install it. I always use /var/tmp to download files to and to compile from source before installing the compiled software.

Change directory to /var/tmp

cd /var/tmp

 Using git, download the entire Google Authenticator project source code by cloning the repository. No need to download and extract tar archives!

git clone https://code.google.com/p/google-authenticator/

 Compile and install the Google Authenticator PAM module

cd /var/tmp/google-authenticator/libpam/
make && make install

 

Configuring Freeradius

Now that Freeradius has been installed, it needs to be configured. Generally the only configuration that’s normally required for Freeraduis is to leave it alone. However, we are not that fortunate. In a nutshell, what we need to do is:

1. Change the user under which radiusd runs

2. Add a user group called disabled. Linux user accounts who are members of this group won’t be able to authenticate with Radius

3. Configure Freeradius to deny access to members of “disabled”

4. Configure Freeradius to use PAM as the default authentication type

5. Enable PAM in the Freeradius configuration

6. Configure a “client” entry for the VMware View Connection Server

The above 6 easy steps will configure Freeradius to make use of PAM, and allow the View Connection Server to send requests to the radius server.

On CentOS/RHEL, the configuration files for Freeraduis is located at /etc/raddb

 

1. Configuring radiusd To Run As root

Note:

I am always uncomfortable when having to run services as the root user. I always recommend running services/daemons with the lowest possible privileges that it can get away with. However, due to the design of the Google Authenticator PAM module, and the fact that we are trying to authenticate with PAM and Freeradius against Google Authenticator, we have to run the Freeradius daemon (radiusd) as root, and here’s why:

When a user is set up to use Google Authenticator, the user’s private key will be stored in /home/<username>/.google_authenticator. The Freeradius daemon (radiusd) needs to have access to that file in order to read the key and pass authentication. The only user that has such access to all user’s home directories is root. Therefore, in order for radiusd to gain access to the file, it has to run as root.

When I get some time, I will see if I can find a way around this. But for now, this is how it works.

Edit the file /etc/raddb/radius.conf

Find the two lines that read:

user = radiusd
group = radiusd

 And change them to read:

user = root
group = root

 Save the radius.conf file and exit the editor.

 

2. Adding the disabled Group

Back at the bash prompt, create a new user group called "disabled":

groupadd disabled

 

3. Configuring Freeradius to Deny Access To “disabled”

We now need to configure Freeradius to deny access to members of the disabled group. Edit the /etc/raddb/users file and find the section that reads:

#
# Deny access for a group of users.
#
# Note that there is NO 'Fall-Through' attribute, so the user will not
# be given any additional resources.
#
#DEFAULT        Group == "disabled", Auth-Type := Reject
#               Reply-Message = "Your account has been disabled."
#

 Uncomment the section to read:

#
# Deny access for a group of users.
#
# Note that there is NO 'Fall-Through' attribute, so the user will not
# be given any additional resources.
#
DEFAULT        Group == "disabled", Auth-Type := Reject
               Reply-Message = "Your account has been disabled."
#

Do not yet save and exit the editor. Step 4 will introduce an additional change to the users file

 

4. Setting PAM as the Default Authentication Type

Now, change the default authentication type to PAM by adding the following line directly underneath the above section (below the uncommented section in the /etc/raddb/users file as described in step 3): 

#
# Deny access for a group of users.
#
# Note that there is NO 'Fall-Through' attribute, so the user will not
# be given any additional resources.
#
DEFAULT        Group == "disabled", Auth-Type := Reject
               Reply-Message = "Your account has been disabled."
#
DEFAULT        Auth-Type := PAM

  Save the file and exit the editor

 

5. Enabling PAM Support in FreeRadius

Ok, so we’ve told Freeradius that the default authentication type should be PAM, however PAM is disabled by default in this release of Freeradius, so we will have to enable it.

 To enable PAM, edit the /etc/raddb/sites-enabled/default file

Under the Authentication section, locate the following lines:

        #
        #  Pluggable Authentication Modules.
#       pam

Uncomment the line that reads pam:

        #
        #  Pluggable Authentication Modules.
 pam

Save the file and exit the editor.

 

6. Creating a Client Configuration for the View Connection Server

In order to accept requests from the VMware View Connection server, we need to set up a client for the View Connection server in /etc/raddb/clients.conf

 Edit /etc/raddb/clients.conf and locate the following section:

#
#  You can now specify one secret for a network of clients.
#  When a client request comes in, the BEST match is chosen.
#  i.e. The entry from the smallest possible network.
#
#client 192.168.0.0/24 {
#       secret          = testing123-1
#       shortname       = private-network-1
#}
#
#client 192.168.0.0/16 {
#       secret          = testing123-2
#       shortname       = private-network-2
#}

 Add the following lines after the above section. The IP address just after “client” should match the IP address of the VMware View Connection Server. Make a note of the “secret” you specify here, as it will later be needed to configure the View Connection Server to use this Radius server for two-factor authentication. The “shortname” should match that of the View Connection server name

 client 192.168.1.24{

        secret          = testing123-2
        shortname       = viewconnect
}

Save the file and exit the editor.

Configure the Freeradius daemon to start with the server:

chkconfig --level 345 radiusd on

This is all the configuration changes that we need to make to Freeradius. The next step is to configure PAM.

 

Configuring PAM

We now need to tell PAM to make use the Google Authenticator module. Configuring PAM to use the Google Authenticator module is as simple as editing a single file.

Edit the /etc/pam.d/radiusd file and change the file to look as below:

#%PAM-1.0
#auth       include     password-auth
#account    required    pam_nologin.so
#account    include     password-auth
#password   include     password-auth
#session    include     password-auth
auth requisite pam_google_authenticator.so forward_pass
account required pam_unix.so use_first_pass

 

Starting the Freeradius Daemon In Debug Mode

Start the radiusd daemon in debug mode to see if it starts up without any issues:

radiusd -X

Verify the following:

... adding new socket proxy address * port 35031
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on command file /var/run/radiusd/radiusd.sock
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.

If all look well, press Ctrl+C to exit out of debug mode

If the radius server started up and is ready to process requests, we can stop the server and restart it in another screen to complete our initial testing and possible troubleshooting:

service radiusd stop
screen –dmS radiusserver radiusd -X

Attach to the radiusserver screen

screen –r radiusserver

Verify the following again to be sure the server has started in a screen without any issues:

... adding new socket proxy address * port 45692
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on command file /var/run/radiusd/radiusd.sock
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.

Detatch from the screen:

Press Ctrl+a d (Press Ctrl+A. Release all keys and then press D)

NOTE: The server should now have detached from the screen running the Freeradius debug session and should be back at a prompt. Whilst detached from the screen, the daemon is still running in debug mode and we can reattach to its screen at any time by typing:

screen –r freeradiusserver

 

Testing the Freeradius + PAM + Google Authenticator implementation

We can test the radius server using radtest, a utility that was installed as part of the freeradius-utils package earlier. In order to do any kind of testing, we need a user to test against.

Add a user in order to test out 2-factor authentication. The users will be Linux users and authentication will require the Linux user password combined with the One Time Password generated by the user’s APP on his mobile phone.

Create a test user with the username “testuser” and assign password123 as the users’ password:

useradd testuser
passwd testuser
password123
password123

Let’s configure the new user to make use of Google Authenticator:

Log in as the user

su testuser

Ensure that we are in the testuser home directory and start the Google Authenticator configuration for the user by entering:

cd ~ google-authenticator

The google-authenticator command will launch a wizard that will generate a key for the user as well as a QR code. As the code is too large to display in the post, I took a screen grab and resized it between line1 and line 2 in the code blocks below:

Do you want authentication tokens to be time-based (y/n) y

 

 

 

 

 

 

 

 

 

Your new secret key is: GGQS2OFTRGK5B4VE
Your verification code is 935687
Your emergency scratch codes are:
  48439961
  69903227
  75907760
  40390365
  23419041

Do you want me to update your "/home/testuser/.google_authenticator" file (y/n)y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) n

 

Setting up Google Authenticator on a Mobile Device

At the time of writing, Google Authenticator supports Android, iOS and Blackberry devices. Download the mobile all “Google Authenticator” from the relevant marketplace on your mobile device. Once installed, scan the provided QR code generated by your server. This will add an account to your mobile app that corresponds with the user account on the server:

The APP will generate a new six-digit code around every 30 seconds.

Now that we have created a new user, created a Google Authenticator token for the user and have our APP generating a new code every 30 seconds, we can test the configuration using radtest

Exit the user account and revert to root by typing ‘exit’

[testuser@radiussrv ~]$ exit
exit
[root@radiussrv pam.d]#

Test the configuration with the following command syntax:

radtest <username> <password>+<Google OTP> <radiusservername>:<port> <nas-port> <clientsecret>

The nas-port parameter value is not important. Enter 10 here. It do just fine.

[root@radiussrv pam.d]# radtest testuser password123430876 localhost:1812 10 testing123

Sending Access-Request of id 4 to 127.0.0.1 port 1812
        User-Name = "testuser"
        User-Password = "password123430876"
        NAS-IP-Address = 192.168.1.19
        NAS-Port = 10

        Message-Authenticator = 0x00000000000000000000000000000000

rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=4, length=20

 If you have followed the steps properly, you should see an “Access-Accept” packet. If so, the configuration is working fine.

 

Troubleshooting

If the configuration doesn’t work, it could be one of many things. I would check the following:

  • Ensure that the time on the mobile device running the Google Authenticator APP is within 30 seconds of that of the server.
  • Check the /var/log/radius/radius.log file for any errors.
  • Check the radius debug screen for any errors.

 

Configuring VMware View to authenticate using the new Freeradius server:

  1. Open a web browser to and navigate to the View Admin portal (https://<view-connection-server>/admin)
  2. Log in as an administrator.
  3. On the left hand side, expand the “View Configuration” section and click “Servers”
  4. Click on the “Connection Servers” tab and select the Connection Server to be configured
  5. Click the edit button
  6. The Edit View Connection Server Settings dialog appears. Click the “Authentication” tab
  7. Under “Advanced Configuration”, select “RADIUS” from the drop down list next to “2-factor authentication”
  8. Next to “Authenticator”, select “Create New Authenticator” from the drop down list

Now, let's set up the new authenticator:

  1. Enter the label for the connection. This will be displayed in the View Client Connection Dialog.
  2. Enter a description
  3. Enter the IP address of the Freeradius server
  4. Enter the secret as specified in the clients.conf file. If they don’t match, authentication won’t work.

 

Testing VMware View Radius Authentication

  1. Open the View Client and attempt to connect.
  2. Enter the Linux username 
  3. Enter the Linux User password followed by the OTP displayed on the Google Authenticator mobile app.

 

Written by  6 comments
Last modified on Tuesday, 09 December 2014 15:16
Rate this item
(2 votes)

Comments (6)

  1. Gary

#6 point is informative for me, I am working on a client project as Creating a Client Configuration for the View Connection Server from last 4 hours, your article help to understand all about my requirements.

  Attachments
 
  1. Daniel

I am having issues with the pam configuration. I have looked at many sites and the issue I have is on Centos 6+ and RHEL 7 if you use the configuration as listed above you can type whatever you want for the password part and as long as the...

I am having issues with the pam configuration. I have looked at many sites and the issue I have is on Centos 6+ and RHEL 7 if you use the configuration as listed above you can type whatever you want for the password part and as long as the token is correct it lets you in effectively breaking the password portion of the security mechanism. Changing this to a auth required (as opposed to acccoutn requried) never seems to work and I suspect it has to do with either the way the google auth code passes the token stripped string back to PAM or pam_unix.so itself failing.
Has anyone else seen this behavior?

Read More
  Attachments
  Comment was last edited about 4 years ago by
  1. Rynardt Spies

Hi Daniel,

Thanks for the comment. My current implementation works correctly, however the configuration could be different from what's specified in the blog post. I'll go and do some research and post my findings here.

Regards,

  Attachments
  Comment was last edited about 4 years ago by
  1. Johny

Hello.

This works well, thanks!

However, my question is , how we could use Google Auth alone, without Unix password?
How should I change PAM or Freeradius configuration?
(now it works with <password>+<Google OTP> , I want to use <Google OTP>...

Hello.

This works well, thanks!

However, my question is , how we could use Google Auth alone, without Unix password?
How should I change PAM or Freeradius configuration?
(now it works with <password>+<Google OTP> , I want to use <Google OTP> alone)

Read More
  Attachments
 
  1. Leon

Hi
Thanks for this article, it is very helpful!
We want to enroll this in our Company. our big Problem with this is the user creation.
We have about 500 users and we don't know their Password. how can we enroll this, so that not every user has to...

Hi
Thanks for this article, it is very helpful!
We want to enroll this in our Company. our big Problem with this is the user creation.
We have about 500 users and we don't know their Password. how can we enroll this, so that not every user has to come to us and type in their Password in the ubuntu System?
Thx for help!

Read More
  Attachments
 
There are no comments posted here yet

Leave your comments

Posting comment as a guest. Sign up or login to your account.
0 Characters
Attachments (0 / 3)
Share Your Location

@martinclarkson I know. That kinda sucks though. All good things must eventually come to an end.
Follow Rynardt Spies on Twitter