OpenVPN Two-Factor Authentication with Authy

  02 Feb 2016


The installation in this article will be in CentOS, I hope that most configurations here will be the same in other distros except package name. And, you have to signup at Authy in order to get an API key. First, making sure you install epel repo and everything is up to update:

$yum update
$yum install epel-release

Then, do install openvpn and easy-rsa.

$yum -y install openvpn easy-rsa
$rsync -av /usr/share/easy-rsa/2.0/ /etc/openvpn/easy-rsa/
$cd /etc/openvpn/easy-rsa

Open the vars file to config for our certificate, edit the file similar to the following:

export KEY_COUNTRY="TH"
export KEY_PROVINCE="BKK"
export KEY_CITY="Bangkhen"
export KEY_ORG="ZDK"
export KEY_EMAIL="admin@local"
export KEY_CN=zdk.github.io
export KEY_NAME=server
export KEY_OU=server

After that, save the file and source it.

$. ./vars NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

You can now run clean-all.

$./clean-all

And start generating our CA:

$./build-ca

Generating a 2048 bit RSA private key
.................................................................+++
...........................................................................................................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [TH]:
State or Province Name (full name) [Bangkok]:
Locality Name (eg, city) [Bangkok]:
Organization Name (eg, company) [zdk.github.io]:
Organizational Unit Name (eg, section) [zdk]:
Common Name (eg, your name or your server's hostname) [zdk CA]:
Name [EasyRSA]:
Email Address [root@local]:

Also, server key:

$./build-key-server server1

Generating a 2048 bit RSA private key
.......................................................................................................+++
..............................+++
writing new private key to 'server1.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [TH]:
State or Province Name (full name) [Bangkok]:
Locality Name (eg, city) [Bangkok]:
Organization Name (eg, company) [zdk.github.io]:
Organizational Unit Name (eg, section) [zdk]:
Common Name (eg, your name or your server's hostname) [server1]:
Name [EasyRSA]:
Email Address [root@local]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'TH'
stateOrProvinceName   :PRINTABLE:'Bangkok'
localityName          :PRINTABLE:'Bangkok'
organizationName      :PRINTABLE:'zdk.github.io'
organizationalUnitName:PRINTABLE:'zdk'
commonName            :PRINTABLE:'server1'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'root@local'
Certificate is to be certified until Jan 18 07:16:07 2026 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Then we generate Diffie–Hellman key exchange:

$./build-dh

In order to connect to server, we have to create client key:

$./build-key di

Move all what we have just generated to /etc/openvpn directory

$cd /etc/openvpn && cp easy-rsa/keys/{dh2048.pem,ca.crt,server1.crt, server1.key}. Copy the sample server config to `/etc/openvpn`
$cp /usr/share/doc/openvpn-2.3.9/sample/sample-config-files/server.conf /etc/openvpn/

Start the openvpn service.

systemctl start openvpn@server.service
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p

Here is we use the recommended installation steps for Authy plugin, like so:

yum groupinstall 'Development Tools'
yum install libcurl-devel
curl -L "https://github.com/authy/authy-openvpn/archive/master.tar.gz" -o authy-openvpn.tar.gz
tar -zxvf authy-openvpn.tar.gz
cd authy-openvpn-master
make && make install

Add Authy user:

authy-vpn-add-user
This script is to add users to Authy Open VPN
For each user you will need to provide the vpn login, e-mail, country code and cellphone
For PAM, login is the *nix login or your PAM login username.
For certificate based Auth we recommend you use e-mails as the login.
Login: zdk@cpan.org
Email: liz@authy.com
Country Code (EG. 1 for US): 66
Cellphone: 819965659
Registering the user with Authy
...
Success: User zdk@cpan.org was registered with AUTHY_ID 12345.

On your desktop or client, download ca.crt, cert.crt and key.key file

I use Viscosity ( http://www.sparklabs.com/viscosity/ ) as a VPN client, open it and import the configuration as following:

remote <Server IP> 1194 udp
persist-key
auth-user-pass
comp-lzo adaptive
pull
ca ca.crt
nobind
persist-tun
cert cert.crt
tls-client
dev tun
key key.key
verb 5
resolv-retry infinite
reneg-sec 28800

You can now try to our VPN server with Viscosity. Also you will be prompted to enter login details, the password must be in PamPassword-AuthyToken format.

After connected, the Viscosity icon will be shown as the following:

VPN

Eventually, you have a perfect Two-factor authentication over secure connection with OpenVPN that you can connect and access your server!

comments powered by Disqus