Securing VMware applications with Google Authenticator

Earlier this week I created a tenant in HobbitCloud for a friend with his own development company. He needs to leverage the power of Infrastructure-as-a-Service, but is unwilling to move to the public cloud for all his workloads just yet. However, now that HobbitCloud is accessible externally, it was clear I had to increase security.

Note: the following is based on Jon Schulman‘s awesome work which can be found at https://blogs.vmware.com/management/2016/02/configuring-vra-7-for-2-factor-authentication.html. However I’ve been working with RHEL/CentOS for years and do things a little differently – namely use SSSD for domain authentication.

With an extensive background in managed services, I’m used to implementing solutions based on RSA SecurID. However, my platform licence has expired, and a replacement is quite frankly prohibitive. It was clear an alternative solution was needed.

Enter Google Authenticator.

Background

I won’t wax on/wax off about the product as I’m sure you’re capable of Googling it for yourself. However I need to explain what I required from it.

Quite possibly the nastiest AD diagram ever

The platform consists of two sites – the primary based in Utrecht, Netherlands; the secondary in Southport, United Kingdom. There is an Active Directory root domain (mdb-lab.com), and each physical location has their own Active Directory child domain and site.

For redundancy I’ll be deploying two Google Authenticator boxes in Utrecht and one in Southport. All three boxes will be in the mdb-lab.com domain.

Getting started – SSSD

There are numerous way to get Linux (in this case CentOS) to interact with Active Directory, some more “pure” than others. In the olden days (RHEL4/5) it used to be Winbind, but even back then I preferred to use native methods like LDAP and Kerberos. Unfortunately these are quite complex to setup… that is until the System Security Services Daemon came along.

For the following to work I assume the following:

  • Each box has the NTP client installed and is pointing to an authoritative time source
  • DNS (both forward and reverse) is working to perfection
  • Hostname is set correctly (on CentOS 7 nmtiu is your friend)
  • You’ve disabled selinux
  • All the necessary firewall rules are in place to allow Active Directory and Radius authentication

If they’re not, don’t bother proceeding until they are.

I’m waiting for you to cock up NTP and DNS

To get SSSD working correctly, install the following packages:

yum install -y realmd sssd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools

Once installed, use the following to add to the domain (substitute accordingly):

realm join --user=Administrator@mdb-lab.com mdb-lab.com

The above configuration is stored in /etc/sssd/sssd.conf. To make home directories look neater, edit the file and change the line:

fallback_homedir = /home/%u@%d

to:

fallback_homedir = /home/%u

Google Authenticator

There’s no need to compile Google Authenticator from scratch, just download the RPM from RepoForge and install it:

wget ftp://195.220.108.108/linux/epel/7/x86_64/g/google-authenticator-1.03-1.el7.x86_64.rpm

Now install:

rpm -Uvh google-authenticator-1.03-1.el7.x86_64.rpm

Freeradius

Install Freeradius using:

yum install -y freeradius

Straight away, the Pluggable Authentication Module with Freeradius won’t be enabled. Let’s change that by creating a symlink:

ln -s /etc/raddb/mods-available /etc/raddb/mods-enabled/pam
chown -h root:radiusd /etc/raddb/mods-enabled/pam

To get radiusd working, we need to edit the following files:

  • /etc/pam.d/radiusd
  • /etc/raddb/clients.conf
  • /etc/raddb/radiusd.conf
  • /etc/raddb/sites-enabled/default
  • /etc/raddb/users

Edit /etc/pam.d/radiusd and add the following lines:

auth requisite pam_google_authenticator.so forward_pass
account required pam_sss.so use_first_pass

Edit /etc/raddb/clients.conf and add your VMware applications. I will be authenticating logons from vRealize Automation and View, so will add two clients (substitute accordingly):

client vra.nl.mdb-lab.com {
        ipaddr                          = 172.17.60.253
        secret                          = VMware1!
        require_message_authenticator   = no
}

Remember to use the IP address that Freeradius will actually see – in my case that’s a NAT’d address as both View and vRA live on subnets behind a pair of F5 load-balancers.

Edit /etc/raddb/radiusd.conf and change:

user = radiusd
group = radius

To:

user = root
group = root

Note: changing Freeradius to run as root instead of chrooting it under its own account will most likely make your security team freak. I will come back to this at a later date.

Edit /etc/raddb/sites-enabled/default, search for “pam” (use ? in vi) and uncomment the line to enable PAM.

Create a security group in Active Directory called RADIUS_disabled. Edit /etc/raddb/users and replace:

DEFAULT Group == "disabled", Auth-Type := Reject
                Reply-Message = "Your account has been disabled."

With:

DEFAULT Group == "RADIUS_disabled@mdb-lab.com", Auth-Type := Reject
                Reply-Message = "Your account has been disabled."

Immediately below that insert the following:

DEFAULT Auth-Type := PAM

Firewall and service

Allow incoming connections on the firewall for radius. On CentOS 7 use the following:

firewall-cmd --zone=public --add-port=1812/udp --permanent
firewall-cmd --reload

Enable the Freeradius service using:

systemctl enable radiusd

Don’t start the service just yet.

Primary & Secondary

For redundancy we will be using two radius servers. However both boxes must be able to read the home directories on each server.

There are a number of ways to achieve this (eg. NFS home directories using Autofs), but the simplest way is just to replicate the home directories from the primary to the secondary using rsync.

Install SSSD and Freeradius on the secondary server. Also, install rsync using:

yum install -y rsync

Once installed, edit /etc/rsyncd.conf and add the following lines:

[home]
        path = /home
        comment = Home
        hosts allow = 
        read only = no
        secrets file = /etc/rsyncd.secrets

Create a file called /etc/rsyncd.secrets and add the following (substitute accordingly):

sa_rsyncd:VMware1!

Allow incoming connections to the firewall for rsync using the following:

firewall-cmd --zone=public --add-port=873/tcp --permanent
firewall-cmd --reload

Enable and start the rsync service using:

systemctl enable rsyncd
systemctl start rsycd

On the primary server, logon as root and edit the crontab using:

crontab -e

Add the following line (substitute accordingly):

*/10 * * * * rsync /home/ sa_rsyncd@<insert secondary server here>::home --password-file=/root/pwfile -ogpru

The above instructs rsync to copy the home directories from the primary to the secondary server every ten minutes and to preserve file ownership and permissions.

Finally, create the file /root/pwfile and add the password you specified in /etc/rsycnd.secrets on the secondary.

Applications

Configure your VMware sites for radius authentication. Refer to the official documentation on how to do this.

Create tokens

Next we need to create the Google Authenticator tokens on the primary. To make the token look professional in the app and to avoid giving away too much information (such as server names), we need to add a couple of switches.

Logon to the primary server as root, then su to become the user requiring a token using (substitute accordingly):

su - mark@uk.mdb-lab.com

Create the token using (again, substitute accordingly):

 google-authenticator -tdf -r 3 -R 30 -w 17 -Q UTF8 -i HobbitCloud -l $USER

This creates the token and will appear in the app using a generic name (in this case HobbitCloud) instead of the actual server name (which you will not want to expose).

The process for importing the token is pretty simple, but if you aren’t sure then Jon’s article (link above) details the requisite steps.

Once the token has been created, this will be replicated to the secondary using rsync within the next ten minutes.

Testing

To begin testing, SSH to both the primary and secondary servers using the domain account you created the token for above. This will validate domain authentication is working as expected. If logon fails, check for errors in /var/log/secure.

Run the following command on both the primary and secondary to run Freeradius in debug mode:

 radiusd -X

Logon to your chosen VMware application using the domain account, password and Google Auth code. Any errors on should be displayed immediately on the primary.

If successful, and you have configured the secondary in your VMware applications, stop Freeradius on the primary and try authenticating again. You should see output on the secondary only this time.

When you are happy authentication works as planned, stop Freeradius on both nodes and start the service using:

systemctl start radiusd

Finishing off

As mentioned at the beginning, this article expands on the work done by Jon. The notable differences being:

  • Using SSSD instead of Likewise
  • Active Directory Parent/Child domain authentication
  • Using a pre-compiled version of Google Authenticator
  • Replication between the primary and secondary
  • Minor changes to Google Authenticator token generation

Happy authenticating!

One thought on “Securing VMware applications with Google Authenticator

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.