Wednesday, October 27, 2010

Mobile One-Time-Passwords with OpenVPN

This started off on my 'wish list' way back when as a fantasy. I was setting up an openVPN server and wrote down a list of how secure (read: paranoid) that i wanted my setup. Back when I worked at a large Techie company; we had securID keyfobs to log into our VPN and SSH servers remotely. The securID keyfobs worked on a basic principal. The user was given a 4-6 digit 'pin' number, and the fob was associated with a securID server. When the user wanted to log into either the VPN or SSH server, they would type in their PIN# followed by (I believe) the 8 digit LCD Display on their fob. The display changed codes every 10 seconds, so you had to be quick. Without the username, keyfob and PIN #, you were not getting into the server. So, that idea led to my 'wishlist' of what I wanted to see on a secure VPN server to the various servers at the house.

So at the time my requirements were simple. I still wanted certificate based authentication (easier to track, and revoke certs), username authentication AND a One-Time-Password. As keyfobs are still pretty expensive equipment, and that would end up being one more thing that I would have to carry around; I stumbled upon mOTP, or Mobile One Time Passwords. mOTP is pretty much limited (at least in my google searching experience) to proprietary systems, fancy keyfobs, or if your lucky; free opensource software Chaching!. In my ever increasing endeavours, I stumbled upon Oh, this was the pot of gold at the end of the rainbow for me! This had everything I needed to implement a secure openVPN server, except documentation on how the heck I was supposed to do it.

Now, before I begin; I just want to say that they do have setup guides for using radius servers, but I followed my philosophy of 'give it a day of your time, and go find another way'. For the life of me I couldn't get mOTP, FreeRadius and openVPN to play nice. Instead I found the next best thing, PAM modules for mOTP. In this blogpost I won't be telling you how to install openVPN, nor will I explain the best (or most secure) way to setup openvpn, as openVPN is still a learning process for me. I would hope if anyone finds some serious 'oh crap' security hole in how I do things, they would let me know and I can make the necessary changes to this document.

So let's get started shall we? First things first, you need an openVPN server (uh, no crap huh?) that you successfully tested with a client. If you have never set up an openVPN server, their website ( has EXCELLENT step-by-step guides on getting started. I have mOTP and openVPN installed on an Debian Server, so keep this in mind while your following this document, as some locations, and packages may shift during shipment so to speak.

Another thing that is a luxury, but not necessarily a necessity; is a development environment that mirrors that of your openVPN server. You will need utilities to compile various software from source, and if your using openVPN on a limited disk space server; you will quickly run out of space. The list of (and in no way complete, I might have had some of these installed at the time that I was writing this document) is as follows:

Development tools (Install these before beginning):
*gcc - needed to compile c/c++ from source
*dpkg-dev - needed by Debian for apt-get source
*libpam0g-dev - PAM Development libraries, needed for mOTP and Compiling openVPN plugins
*make - needed to make gcc files

Setting up PAM Modules for openVPN

*Note: as I stated earlier, I used debian for my openVPN/mOTP setup, so if you are using an RPM pkg mgr, or installing from source, these steps may be different.
1. Download the openVPN source code
a. cd to a temporary directory (/tmp)
b. apt-get source openvpn
2. Compile the auth-pam source
a. navigate to /src-dir/openvpn-dir/plugin/auth-pam (ex: /tmp/openvpn-2.1~rc11/plugin/auth-pam)
b. run: make, inside of the auth-pam directory. This generates the following file:
3. Create location and copy over the plugin
a. mkdir -p /usr/share/openvpn/plugin/lib
c. cp /usr/share/openvpn/plugin/lib
4. Edit your openVPN server.conf file (usually located in /etc/openvpn/server.conf), and add the following line:
a. plugin /usr/share/openvpn/plugin/lib/ openvpn

Setup and Configure mOTP files
Note: At this point, you need to download/install the compatible mOTP client for your mobile device, mOTP's website ( has the necessary java files to run on your phone.
I tested this out on both a blackberry 8330, and an Android 2.1 Mobile device, without any problems. Also, your mobile phone OS might also have other mOTP compatible software located in their 'online store' eg: Android Market, Blackberry App World, etc. I would try and use the mOTP client that is offered by mOTP's website before venturing into other mobile clients.

1. Create necessary directories for mOTP and PAM
a. mkdir /var/cache/motp
2. Copy sample configuration file and change permissions on the file
a. cp motp.conf /etc/security
b. chmod 600 /etc/security/motp
3. Create an openvpn file, and set permissions in /etc/pam.d
a. touch /etc/pam.d/openvpn && chmod 644 /etc/pam.d/openvpn
4. Copy to /lib/security
a. cp /lib/security
5. Modify /etc/pam.d/openvpn with your favorite editor, and add the following information:
auth sufficient /lib/security/ not_set_pass
password required /lib/security/ debug
account required /lib/security/

Configuring mOTP on your device
1. Start up the mOTP client on your mobile device, enter: #**# when asked to enter your PIN.
This will generate a secret hash that is needed only by the motp.conf file, write down
the hash, because you will need it. Then eat the paper, leave no evidence.
a. Enter #**# on your mobile device.
b. Enter a bunch of random characters to generate your hash
c. Write down the hash results.
d. Also, at least on the android will see an 'epoch' time, this will
be needed to compute the time offset between the server and your phone.
ex: 128797806

Figure out your time offset between the server and your mobile device.
* The offset is in hours. For instance if your phone is set to a different timezone
than that of the server, finding the epoch time is necessary to sync the pin to the hash
generated. Some newer versions of mOTP mobile, allow you to set the timezone manually
in the software, so that you will always have a 0 in the offset on the server. As of this writing
there are two other mOTP clients on the android marketplace, that let you set the UTC where you are currently at.

* Also note, from my experience. If the difference between the two times are less than 360, than you won't need to add anything but a 0 when it comes
to setting your offset. 360=1, 720=2, etc.

1. Write down your epoch time from the mobile device
2. type: "date +%s" on the openVPN server, and write down the first 9 digits of
the server's epoch time.
3. Subtract the two numbers for a positive integer. Ex: 1289798394 (server time)
- 128797806 = 33. This number is the output in 10s of seconds (360=1 hour, etc), write it down, you will need it for this next step.

Configure motp.conf file with the necessary information
motp.conf is located in /etc/security, where you moved it over in a previous step. Use your favourite editor (it is VI, isn't it?) to edit the motp.conf file.
There are comments in the file that tell you what to put where. This might just be a coincidence, or might not...But I found that the username that I selected
for motp.conf had to be different than the username that I had on my server. I think it has something to do with the pam login modules and having the same username.
I didn't look further into this, but just in case, try a different username than a local user on the server.

1. username, secret (the hash generated above), a pin # of your choosing, and your offset
2. Comment out the default (korff) for security purposes. It's in there just as example on how you configure motp.

Configure openvpn
1. Add the following line to your openVPN server.conf file with your favourite editor.
a. plugin /usr/share/openvpn/plugin/lib/ openvpn
b. Note: if you want to just use mOTP as authentication, and not certificates (not recommended) than add 2 more lines to the config:
1. client-cert-not-required
2. username-as-common-name
2. Add the following line to your openVPN client.conf file (on the client machine of couse)
a. auth-user-pass

Test your configuration
1. Restart your openvpn server (/etc/init.d/openvpn restart or if you want to see debug messages on console: openvpn /etc/openvpn/server.conf from the command line)
2. Now test your client, best to test this first from the commandline: openvpn /etc/openvpn/client.conf so that you can see exactally what is going on. For my testing purposes
I had the server running from the commandline, viewing debug messages; and the client from the commandline, watchin them both connect, and checking for any errors.
3. You should now be requested to enter a username, use the name that you created in your motp.conf file earlier.
4. On your Mobile device (remember you have 10 seconds from connection to generate and enter your password) enter the PIN # you created, and use the results (default mobile
app has the result printed below where you enter your pin number, in red)as your one time password.
5. If it all works out, you should now be connected to your VPN. Tada!

So there you have it. Mobile One-Time-Passwords using openVPN. If this doesn't work, my first bet would be to check to see if openvpn worked prior to you venturing into the mobile otp arena. That
was my problem when I first started working with this. Drop me a comment if you use this, curious if anyone else will have a use for this.


  1. Wow! So this is what genius looks like. You should present this at defcon. Good stuff Jason.

  2. Thanks for posting this. It was the only MOTP PAM module tutorial I could find. I modified what you did to set up iOTP(US available version of mOTP) with SSH. I'm trying to get it working with a PPTP VPN to my IPOD (but no luck so far). Thanks again for posting this.

  3. On my Squeeze system is already there in /lib/openvpn. It was there in Lenny too.

    I have already got the MOTP PAM working with ssh generating OTPs on my iPhone using iOTP (free iPhone app) so I'm hoping that getting openvpn working as well shouldn't be too hard. Your tutorial is a very useful starting point.