OpenVPN Server with Username/Password Authentication

In this lesson, I’m going to show you how to configure an OpenVPN server using username/password authentication on the client. The configuration will be pretty straightforward and will be a great starting point for more complex OpenVPN configurations. First I will show you how to configure the server and then the client, in my example I’m using Ubuntu 12.04 but you should be able to do this on any Linux distribution.

Server Configuration

Let’s install OpenVPN:

sudo apt-get install openvpn

OpenVPN is in the default repositories, so that’s easy enough. Now we have to configure our CA (Certificate Authority) and generate some keys:

sudo mkdir /etc/openvpn/easy-rsa/

OpenVPN uses the /etc/openvpn folder and this is where we create a new folder called “easy-rsa”. It also comes with some example files which we’ll use:

sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/

Now we need to edit the “vars” file, which holds some information about the certificate:

sudo vim /etc/openvpn/easy-rsa/vars

You can leave everything default except for the following fields:

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"

Change these fields to your liking, save the file and we can generate the master CA certificate and key. Make sure you are doing this as the root user:

sudo su

And then we’ll build the certificate:

source vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
./clean-all
./build-ca 
Generating a 1024 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) [NL]:
State or Province Name (full name) [NB]:
Locality Name (eg, city) [Amsterdam]:
Organization Name (eg, company) [NETWORKLESSONS]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [NETWORKLESSONS CA]:
Name []:
Email Address [info@networklessons.com]:

Now we will build the server keys. I’m calling mine “SERVERNAME” :

./build-key-server SERVERNAME
Generating a 1024 bit RSA private key
.....++++++
...............................++++++
writing new private key to 'SERVERNAME.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) [NL]:
State or Province Name (full name) [NB]:
Locality Name (eg, city) [Amsterdam]:
Organization Name (eg, company) [NETWORKLESSONS]:
Organizational Unit Name (eg, section) [changeme]:
Common Name (eg, your name or your server's hostname) [SERVERNAME]:
Name [changeme]:
Email Address [mail@host.domain]:

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.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'NL'
stateOrProvinceName   :PRINTABLE:'NB'
localityName          :PRINTABLE:'Amsterdam'
organizationName      :PRINTABLE:'NETWORKLESSONS'
organizationalUnitName:PRINTABLE:'changeme'
commonName            :PRINTABLE:'SERVERNAME'
name                  :PRINTABLE:'changeme'
emailAddress          :IA5STRING:'mail@host.domain'

Certificate is to be certified until Feb  3 09:26:00 2024 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

Make sure you sign and commit the certificate! We’ll continue by building the DH parameters:

./build-dh 
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
........................................................................+...................................+...........+................................+...............................................

We now have all the certificates and keys that we need for the server. It’s a common practice to copy these to the /etc/openvpn folder:

cd /etc/openvpn/easy-rsa/keys/
cp SERVERNAME.key SERVERNAME.crt ca.crt dh1024.pem /etc/openvpn

The certificates and keys are now in place, we still have to create a configuration file for the server, however. We’ll create a new one:

vim /etc/openvpn/server.conf

You can copy and paste mine which only has the minimum number of items required to make this work. You can always edit it later to add more options:

# Port Number.
port 1194

# TCP or UDP server.
proto udp

# Interface type, TUN or TAP.
dev tun

# Certificates.
ca ca.crt
cert SERVERNAME.crt
key SERVERNAME.key  # This file should be kept secret

# Diffie hellman parameters.
dh dh1024.pem

# Subnet to use for OpenVPN Connections.
server 10.8.0.0 255.255.255.0

# Keepalive: send ping every 10 seconds, tunnel down after 120 seconds no response.
keepalive 10 120

# LZO Compression for the tunnel.
comp-lzo

# Drop privileges to user/group nobody.
user nobody
group nogroup

# Makes the link more resistant to connection failures.
persist-key
persist-tun

# Username and Password authentication.
client-cert-not-required
plugin /usr/lib/openvpn/openvpn-auth-pam.so login

# OpenVPN Status Log files.
status openvpn-status.log

# LOG FILE VERBOSITY:
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

The OpenVPN server is now ready. You can run it as a server or just from the command line, it’s best to do it from the command line first so you can see in real-time what is going on:

cd /etc/openvpn
openvpn server.conf

You’ll see something like this:

Wed Feb  5 10:49:54 2014 OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Feb 27 2013
Wed Feb  5 10:49:54 2014 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Wed Feb  5 10:49:54 2014 PLUGIN_INIT: POST /usr/lib/openvpn/openvpn-auth-pam.so '[/usr/lib/openvpn/openvpn-auth-pam.so] [login]' intercepted=PLUGIN_AUTH_USER_PASS_VERIFY 
Wed Feb  5 10:49:54 2014 Diffie-Hellman initialized with 1024 bit key
Wed Feb  5 10:49:54 2014 WARNING: POTENTIALLY DANGEROUS OPTION --client-cert-not-required may accept clients which do not present a certificate
Wed Feb  5 10:49:54 2014 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Wed Feb  5 10:49:54 2014 Socket Buffers: R=[212992->131072] S=[212992->131072]
Wed Feb  5 10:49:54 2014 ROUTE default_gateway=10.56.100.254
Wed Feb  5 10:49:54 2014 TUN/TAP device tun0 opened
Wed Feb  5 10:49:54 2014 TUN/TAP TX queue length set to 100
Wed Feb  5 10:49:54 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Wed Feb  5 10:49:54 2014 /sbin/ifconfig tun0 10.8.0.1 pointopoint 10.8.0.2 mtu 1500
Wed Feb  5 10:49:54 2014 /sbin/route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.2
Wed Feb  5 10:49:54 2014 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Wed Feb  5 10:49:54 2014 UDPv4 link local (bound): [undef]
Wed Feb  5 10:49:54 2014 UDPv4 link remote: [undef]
Wed Feb  5 10:49:54 2014 MULTI: multi_init called, r=256 v=256
Wed Feb  5 10:49:54 2014 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Wed Feb  5 10:49:54 2014 Initialization Sequence Completed

OpenVPN is now ready for incoming client connections, if for some reason a client is unable to connect you’ll see it on the console. Once everything is working, it’s better to use the daemon:

service openvpn start
 * Starting virtual private network daemon(s)...                                                                                           *   Autostarting VPN 'server'

With the OpenVPN server running, it will create a tunnel interface. You can see it like this:

# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

By default it will create a tun0 interface and the IP address of the server will be 10.8.0.1. Let’s move on to the client so we can test our connection!

Client Configuration

First, we’ll install OpenVPN, which is the same as the server:

sudo apt-get install openvpn

Copy the ca.crt file from the server to your client and then use the following command:

sudo openvpn --remote 10.56.100.53 --comp-lzo --dev tun --auth-user-pass --ca ca.crt --client

This tells the client to use the remote OpenVPN server at IP address 10.56.100.53, use LZO compression, a tunnel interface, authenticate with username/password and check if the certificate of the server matches. There are many different (GUI) clients for OpenVPN, but this is just a quick method to connect.

If everything went ok, you’ll see this:

Wed Feb  5 11:25:35 2014 OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Feb 13 2013
Enter Auth Username:vmware
Enter Auth Password:
Wed Feb  5 11:25:43 2014 IMPORTANT: OpenVPN's default port number is now 1194, based on an official port number assignment by IANA.  OpenVPN 2.0-beta16 and earlier used 5000 as the default port.
Wed Feb  5 11:25:43 2014 WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.
Wed Feb  5 11:25:43 2014 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Wed Feb  5 11:25:43 2014 LZO compression initialized
Wed Feb  5 11:25:43 2014 UDPv4 link local (bound): [undef]
Wed Feb  5 11:25:43 2014 UDPv4 link remote: [AF_INET]10.56.100.53:1194
Wed Feb  5 11:25:43 2014 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Wed Feb  5 11:25:43 2014 [SERVERNAME] Peer Connection Initiated with [AF_INET]10.56.100.53:1194
Wed Feb  5 11:25:45 2014 TUN/TAP device tun0 opened
Wed Feb  5 11:25:45 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Wed Feb  5 11:25:45 2014 /sbin/ifconfig tun0 10.8.0.10 pointopoint 10.8.0.9 mtu 1500
Wed Feb  5 11:25:45 2014 Initialization Sequence Completed

The client is now connected, and just like the server, it will have a tun0 interface:

ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.10  P-t-P:10.8.0.9  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:72 (72.0 B)

It receives IP address 10.8.0.10 from the server. Let’s see if we can ping:

ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_req=1 ttl=64 time=0.927 ms

Great! The VPN is up and running. You now have a basic OpenVPN server/client configuration with username/password authentication. Anything else we need to think about?

Firewall

In case you have a firewall on the server, you will need to make some changes to allow the traffic through. Here’s an example of IPTables:

-A INPUT -p state --state NEW -p udp --dport 1194 -j ACCEPT

This allows the client to connect to the server by using UDP port 1194 (the default).

Troubleshooting

Many things could go wrong. One of the issues that I encountered is that on Ubuntu 12.04, I got an error that there was no openssl config file:

# source vars
**************************************************************
No /etc/openvpn/easy-rsa/openssl.cnf file could be found
Further invocations will fail
**************************************************************
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

There’s an easy fix for this, however:

$ openssl version
OpenSSL 1.0.1 14 Mar 2012

If you look in the /etc/openvpn/easy-rsa folder you’ll see that there is no config file for OpenSSL 1.0.1, so we’ll link it ourselves:

sudo ln -s openssl-1.0.0.cnf openssl.cnf

When you run the source vars command again, you shouldn’t get this error anymore!

Hopefully, this lesson has been useful to you. Once you have a basic configuration, you can always add more advanced options.

Tags: ,


Forum Replies

  1. OK that’s fine for a Ubuntu client. Now I want to have an Android client. Is it possible to do this? Re Android apps: OpenVPN Connect app requires a .ovpn profile but gives no info on them; OpenVPN For Android app wants a Client Certificate and a User Certificate. Any ideas as to whoich (or other Android app) to use?
    PS My Android devices use Jelly Bean & Kit Kat.

  2. Hi John,

    I am using “OpenVPN for Android” but I can choose between certificates and just username/password authentication. The only certificate you need to add is the server certificate…no client certificates.

    Do you have this option? I’m using Android 4.4 on a Google Nexus 5.

    Rene

  3. Rene,

    I’m using Android 4.4.2 on a Google Nexus 10. I’ve reinstalled 'OpenVPN for Android". It immediately asked me to add a Profile. I did this & it showed me a screen containing hotspots for Basic, IP and DNS, Routing, Authentication/Encryption, Advanced, Generated Config. I’ve set Type in Basic to Username/Password. I’ve set the server address in Basic to the Internet IP Address set in my router. I’ve set the CA Certificate to the ca.crt created file. I’ve left the Client Certificate as ‘No Certificate’. I’ve set username in Basic & left Password blank. Idea

    ... Continue reading in our forum

  4. I forgot to ask another question. At the moment my laptop (running the client) connects using a Laptop.crt & Laptop.key files created by “./build-key Laptop” to my desktop running the server: I followed the procedure from Ubuntu’s Community Documentation for Ubuntu Server OpenVPN. Am I correct in stating that the same server configuration file & created ca.crt file will still work for user/password authentication from the client? The reason that I want to do this is that it seems a good idea to use user/password authentication for Android devices (since, if I l

    ... Continue reading in our forum

  5. Answering the question in my last message, it’s not possible to use user/password auth on Android devices but not on laptop (without configuring 2 VPN servers), due to the server.conf containing:

    #Username and Password authentication.
    client-cert-not-required
    plugin /usr/lib/openvpn/openvpn-auth-pam.so login
    So I will use user/password authentication on both laptop & Android devices.

10 more replies! Ask a question or join the discussion by visiting our Community Forum