OpenVPN Server with Username/Password Authentication

In this tutorial I’m going to show you how to configure OpenVPN server using username / password authentication on the client. The configuration will be pretty straight forward 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 instal 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 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, this 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 difference (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 for 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

There are many things that 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 tutorial has been useful to you, once you have a basic configuration you can always add more advanced options. If you enjoyed this, please share it with your friends and/or colleagues!

Forum Replies

  1. Another question: I’ve messed up my client.conf file by previously installing a user cert & key files to my client. Even though I completely removed openvpn & reinstalled it, it did not create a new client.conf. After doing the openvpn command to setup the use of the client it still contained the following:

    ca ca.crt
    cert Laptop.crt
    key Laptop.key
    

    What should I do with the latter 2 lines?

    Also, I do not yet have a static ip address (for my router) & ddclient has disappeared from the Ubunto repos. What’s the recommended procedure (in Precise & Trusty) to use hostname provider?

  2. Hi John,

    If you don’t want user certificates then using Basic with username/password authentication is the way to go. The only requirement is adding the ca.crt file from the OpenVPN server.

    Once you are able to connect you will have a VPN tunnel between your client and the server but that’s it. If you want the VPN to access other networks then first we need to tell the server that it should forward IP traffic:

    <strong>cat /proc/sys/net/ipv4/ip_forward</strong>
    0
    

    The “0” means no forwarding so let’s change it:

    <strong>sudo sysctl -w net
    ... Continue reading in our forum

  3. Hi Rene,

    Thanks for your reply and wonderful link.
    Can i check if my following understanding is correct

    1a) tunneling is used when the src/dst network is prohibited/unreachable between 2 connected points due to FW issue or as in your example, internal network going over WAN to another.

    1b) if the source and destination network are reachable to one another, there will be no need for tunneling.

    2a) tunnel interface are “virtual/logical” interface in which they are “tag” to the actual physical interface and uses the physical interface to actually send out the enc

    ... Continue reading in our forum

  4. Here are the answers to your questions:

    1a) This is correct, this is probably the main reason why you want to use tunneling.

    1b) There is another reason why you want to use tunneling. For example, IPsec doesn’t support multicast. If you want to encrypt multicast traffic with IPsec then you will have to create a GRE tunnel and then encrypt the GRE tunnel with IPsec.

    2a) These are virtual interfaces yes but they aren’t really “attached” to the physical interface.

    2b) This is correct but we don’t use the word gateway for this. From the router’s perspective, the IP

    ... Continue reading in our forum

  5. 2a) That’s correct, you’ll always need the physical interface to actually transmit the data.

    2b) The normal gateway will remain the default gateway. However, some extra entries might appear in the routin table of the computer.

    If you want to play with VPNs on your computer then you could use two virtual machines with OpenVPN (one server, one client) or you could try GNS3 to emulate a Cisco router and use one virtual machine as the VPN client.

    Normally with a VPN client, the VPN server won’t know the network behind the computer. Also, your computer is no router

    ... Continue reading in our forum

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