23 August 2014

OpenVPN with OTP one time password by google authenticator working all the time

So why OpenVPN but not l2tp or pptp or ipsec ?

The good thing :

- It can be run at tcp:80 or tcp:443. No more worry about firewall or behind NAT.

- Also can be used with http proxied.

- SSLv3 + PKI Cert Authentication.

- Totally free.

- Multiple platforms supported : Windows, Linux, Mac, Ios, Android ...

The bad thing :

- Some vpn solution like l2tp or pptp is supported natively by Windows, when using OpenVPN you need to manually install the client.

1. Install OpenVPN server : 

You can install some pre-build binary packages here : http://www.rpmse.org/#/dashboard?s=openvpn

Or if you have time and want to rebuild by yourself, follow the section below.

Follow https://openvpn.net/index.php/download/community-downloads.html to download the source tarball :

# wget http://swupdate.openvpn.org/community/releases/openvpn-2.3.4.tar.gz

Install these required packages to build the OpenVPN rpm.

# yum install make gcc rpm-build openssl-devel lzo-devel pam-devel
# rpmbuild -tb openvpn-2.3.4.tar.gz
..............................
..............................
Wrote: /root/rpmbuild/RPMS/x86_64/openvpn-2.3.4-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/openvpn-devel-2.3.4-1.x86_64.rpm

When finish, we have two newly rpm packages. Let's install it.

# yum install /root/rpmbuild/RPMS/x86_64/openvpn-2.3.4-1.x86_64.rpm

2. Config OpenVPN using certificate to authenticate users

The working dir of openvpn is /etc/openvpn/.

# cd /etc/openvpn/

To make Openvpn working, we will need :

- A dh.pem file.
- A pair of private key and certificate corresponding.

Create the dh.pem file using openssl

# openssl dhparam -out dh.pem 2048

It will take a while, so be patient. When finishing you will have something like this :

# cat dh.pem
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA/V5PVY4jA7wRrnhasXvUocb2Y6AzzF+O04HcxYggcQo3a/MNvFyr
/zazbUF5bnJc3snl3lqMmBF6moVhfyMdetVIjwLj+olFpEk5o48VF58PJ1ElweTp
QgXRrU/hTqOA7qzfDc8t1CJEA5Zue6e615JB6nAZf/WNy3+GIZqHvPrE/rQPfsi0
Oja4fzWgALK7bap4lNYc9w1E1MR+aLekQ5EPfhMhWIRBwhNmtSKydn8hZgUGH252
asL6tYPfKwlYCiencOdJyVUF9nw6gLl5nBA2pg9lTHTuKrY05GLovm8v5a3XDfLR
5RBIVLKk6xEAAAjFeocknIBfcCPqb0MVYwIBAg==
-----END DH PARAMETERS-----

We will create a local rootCA then using this rootCA to sign the certificate for the Server, and certificates for the Clients. More detail about certificate autthention can be read here : Authenticate-users-with-client-certificates-on-Apache-and-IIS

Generate the self-signed root CA :

# openssl genrsa -out rootCA.key 2048
# openssl req -out rootCA.cert -key rootCA.key -new -x509 -days 3650

Generate the server private key :

# openssl genrsa -out VPNserver.key 2048

Generate the server certificate request :

Notice: The common name (CN) should match your vpn-server fully domain, for e.g : vpn.tipstuff.org / Read more here to see why.

# openssl req -out VPNserver.req -key VPNserver.key -new -days 365

Using rootCA to sign the server request :

# openssl x509 -in VPNserver.req -out VPNserver.cert -days 365 -req -CA rootCA.cert -CAkey rootCA.key -CAcreateserial

By default there is no config file, we need to make a new one. The config file should have the .conf extension :

# vim openvpn.conf 

#Listen on tcp 443
port 443
proto tcp-server
keepalive 10 120

# Using TUN device / Route Mode.
dev tun
dh dh.pem
ca rootCA.cert
cert VPNserver.cert
key VPNserver.key

# Client will receive IP in this range.
server 10.0.0.0 255.255.255.0

# Push DNS server and static route to clients (optional)
push "dhcp-option DNS 208.67.222.222"
push "route 1.2.3.4 255.255.255.255"

Start the openvpn service :

# /etc/init.d/openvpn start

A new tun0 interface has been created :

# ifconfig
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.0.0.1  P-t-P:10.0.0.2  Mask:255.255.255.255