A few days ago I had the idea to set up two factor authentication on my OpenVPN remote user VPN implementation. I did some research and found that the code that Google used to build Google Authenticator (which provides two factor auth for Google accounts) is open source and available on a SVN repository.

Google provides a Google Authenticator app for many mobile platforms including:

Android, iOS and Blackberry

The application looks like this:

So are you interested so far? Good! Lets get started with setting up the application on our CentOS servers (I’m using 5.5 by the way).

Unfortunately we need to install a newer mercurial version than what is available by default on the CentOS yum repository. This means that we will need to download and compile it ourselves instead of using yum.

You can see the Mercurial Version requirements here:

http://code.google.com/p/google-authenticator/wiki/MercurialVersion

Before we compile mercurial we need to install several packages that we will need during this adventure. During this tutorial I assume that you are using centOS with a i386 architecture, if you aren’t make sure you edit the package names accordingly.

We will need the following packages for mercurial:

Docutils

Subversion

We will also need the following packages to compile google-authenticator:

Gcc

Python-devel

Pam.i386

Pam-devel.i386

So lets start having fun!

First we need to download and compile docutils ourselves because it’s not available on the default centOS yum repository: wget http://softlayer.dl.sourceforge.net/project/docutils/docutils/0.8.1/docutils-0.8.1.tar.gz tar -xvf docutils-0.8.1.tar.gz cd docutils-0.8.1 python setup.py install After we installed docutils lets go ahead and install all other dependencies before proceeding: yum install gcc python-devel subversion pam.i386 pam-devel.i386 So far so good! Now we need to download and compile mercurial: cd /tmp/ wget http://mercurial.selenic.com/release/mercurial-2.1.1.tar.gz tar xvzf mercurial-2.1.1.tar.gz cd mercurial-2.1.1 make install Now that we have successfully installed mercurial lets clone the google-authenticator SVN repository and compile the code: cd /tmp/ hg clone https://google-authenticator.googlecode.com/hg/ authenticator cd authenticator/libpam make && make install Now that we have google-authenticator installed we need modify our openvpn configuration to point to the new pam module we will use for two-factor authentication.

We do this by adding the following line to your OpenVPN server configuration: plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn Now we need to create the pam module that OpenVPN is expecting to use for authentication: touch /etc/pam.d/openvpn Use vi (or something similar) to edit the file and copy and paste the following configuration:

auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so auth required pam_google_authenticator.so forward_pass auth include system-auth account include system-auth password include system-auth After making the changes on the server edit your client configuration file to include the following directive:

auth-user-pass

Now lets restart openvpn so the changes take effect: service openvpn restart After restarting openvpn we must generate the tokens we need for google-authenticator. We do this by logging into whatever user will be using the VPN and issuing the following command: google-authenticator At this point you will be asked several questions, the first one is: Do you want authentication tokens to be time-based (y/n) Google will now generate a URL, your secret key, verification code and some emergency OTPs: https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/fran@localhost.localdomain%3Fsecret%3DUFMT4L562NPOXQY3

Your new secret key is: UFMT4L562NPOXQY3

Your verification code is 185633

Your emergency scratch codes are:

64291965

41844754

22921469

17413098

64795694

Make sure to answer yes to the following question: Do you want me to update your "/home/$USER/.google_authenticator" file (y/n) Below are three more questions you will be asked regarding how you want your tokens to function:

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)



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)



If the computer that you are logging into isn't hardened against brute-force

login attempts, you can enable rate-limiting for the authentication module.

By default, this limits attackers to no more than 3 login attempts every 30s.

Do you want to enable rate-limiting (y/n)



Now you are ready to use your new two-factor authentication for openvpn! When connecting use the following format in the password field:

password+[six digit google authenticator code]

This means if your password is skittles32! And your token is 135353 you would use the following password:

“skittles32!135353”

If you have any questions or feedback be sure to leave a comment!