How To Set Up OpenVPN To Authenticate With LinOTP

Want to support HowtoForge? Become a subscriber!
 
Submitted by cornelinux (Contact Author) (Forums) on Mon, 2012-10-22 18:51. :: Security

How To Set Up OpenVPN To Authenticate With LinOTP

Introduction

This howto will show you the way to set up OpenVPN to authenticate users against the LinOTP authentication backend. Thus you can bring up your VPN using two factor authentication with different kind of OTP tokens.

If you only have a few users or a few machines and using your smartphone as your token suites you, you should probably take a look at this howto on this site.

But on the other hand if you need to manage several users with different kind of tokens, you should go on reading this howto.

 

Setting up LinOTP

First you need to set up LinOTP. There are several ways to do this. You can download Debian and Ubuntu packages or you can install the system using the Python Package Index. It provides a good quick start to get the service up and running for demo purposes (check for the latest version).

You might install the LinOTP backend together with the OpenVPN daemon on the same machine to keep things straight and simple.

 

Configuring PAM for LinOTP

There are different ways to authenticate against LinOTP. You can use the Web API or a RADIUS server, but you can also use a PAM module to authenticate with your OTP tokens.

LinOTP provides a pam_linotp written in C, which is contained in the authentication modules. But we do not want to go through the hassle of compiling the C stuff today and install all the necessary devel packages.

So we turn to another PAM module: pam_py_linotp.

We now are going to install this pam module on the OpenVPN server.

You can download it, unpack it, install it:

tar -ztf pam_py_linotp-0.1.tar.gz

cd pam_py_linotp-0.1/

sudo python setup.py install

Alternatively you can use the pip tool to do it much quicker:

sudo pip install pam_py_linotp

or you can just copy the single python module to a given location:

cd pam_py_linotp-0.1/

cp src/ pam_linotp.py /lib/security

To use this module you need to install libpam-python.

libpam-python allows you to use the pam_py_linotp.py python module in your PAM stack.

Install libpam-python according to your distribution like:

sudo apt-get install libpam-python

or

yum install libpam-python

To make the usage more comfortable and to also be able to simply add two factor authentication to your other services like ssh, gdm or kdm, we define a stackable auth file common-linotp:

auth    [success=1 default=ignore]      pam_python.so /lib/security/pam_linotp.py \
debug url=https://localhost/validate/check
auth requisite pam_deny.so
auth required pam_permit.so

Please note, the first parameter after the pam_python.so module is the python module, that you installed or copied. And you need to provide a URL, where the LinOTP server is located. If you installed LinOTP on the same machine like OpenVPN is about to run, you can leave this as "localhost". Otherwise adapt the name or IP address accordingly.

In the URL you also need to adapt the protocol (running LinOTP on https or http) and the port.

We now have a simple file common-linotp, that we can later use to include into our PAM definitions.

 

Setting up OpenVPN with PAM

On the client machine setup your client configuration client.ovpn like this:

client
dev tun
proto udp
remote your.server.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
comp-lzo
verb 3
auth-user-pass

Of course you need to adapt the servername and the certificate names.

On your OpenVPN server set up the server.conf like this:

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 192.168.42.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn

Adapt your certificate names and your IP pool.

Finally we need to edit /etc/pam.d/openvpn which should contain the following lines:

@include common-linotp 
session    sufficient pam_permit.so
account    sufficient  pam_permit.so

The session and the account use pam_permit.so, so that we do not need to create local user accounts for the VPN users on the OpenVPN server.

When the user entered the correct OTP value and optional OTP PIN the VPN is established.

 

Conclusion

We set up an OpenVPN server to authenticate with OTP tokens managed by LinOTP.

The interesting part is, that we were also using client certificates, so that the VPN only gets established if the machine has the right client certificate and the user has the right OTP token.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Raju Singh (not registered) on Thu, 2012-10-25 09:37.
Great work Cornelius :) !
Submitted by Cornelius (not registered) on Sun, 2012-10-28 11:39.
Thanks you, too! ;-)