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!
You can examine https://www.kaplansoft.com/tekradius/Docs/Google-Authenticator.pdf for a Windows based implementation for Google Authenticator with RADIUS.
LikeLiked by 1 person