×
setup openvpn on ubuntu 18

Introduction

OpenVPN is a free, open source, one of the most popular and widely used software that implements virtual private network for creating secure point-to-point or site-to-site connections in routed or bridged configurations. OpenVPN uses SSL protocol that allows you to connect to other devices within secure network. OpenVPN allows you to connect a group of computers in a remote location as LAN network in your system over the public network.

In this tutorial, we are going to set up an OpenVPN server on an Ubuntu 18.04 server.

Requirements

  • A server running Ubuntu 18.04.
  • A static IP address 192.168.0.101 is set up to your server.
  • A root password is set up to your server.

Getting Started

Before starting, you will need to update your server to the latest version. You can do it with the following command:

apt-get update -y
apt-get upgrade -y

Once your server is updated, restart your server to apply the changes.

Install OpenVPN

By default, OpenVPN is available in the Ubuntu 18.04 default repository. You can install it by just running the following command:

apt-get install openvpn -y

Once the installation has been completed, start the OpenVPN service and enable it to start on boot with the following command:

systemctl start openvpn@server
systemctl enable openvpn@server

Download and Configure EasyRSA

Next, you will need to set up your own simple certificate authority (CA). EasyRSA can be used to build your CA public key infrastructure (PKI). To do so, download the latest version of EasyRSA from the official GitHub repository.

wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.4/EasyRSA-3.0.4.tgz

Once the download has been completed, extract the downloaded file with the following command:

tar -xvzf EasyRSA-3.0.4.tgz

Next, chaneg the directory to EasyRSA and rename the file named vars.example to vars.

cd EasyRSA-3.0.4
mv vars.example vars

Next, open the file and make changes as per your location:

nano vars

Make the following changes:

set_var EASYRSA_REQ_COUNTRY "INDIA"
set_var EASYRSA_REQ_PROVINCE "Gujarat"
set_var EASYRSA_REQ_CITY "Ahmedabad"
set_var EASYRSA_REQ_ORG "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL "admin@example.com"
set_var EASYRSA_REQ_OU "Webserver Talk"

Save and close the file, when you are finished.

Next, run the easyrsa utility with the init-pki option to initiate the public key infrastructure on the CA server:

./easyrsa init-pki

You should see the following output:

Note: using Easy-RSA configuration from: ./vars

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /root/EasyRSA-3.0.4/pki

Next, run the following command to build the CA:

./easyrsa build-ca nopass

You will be asked to confirm the CA, press ENTER to accept the default name:

Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
..........................................+++
......+++
writing new private key to '/root/EasyRSA-3.0.4/pki/private/ca.key.5jg057vEJa'
-----
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

Create the Server Certificate, Key, and Encryption Files

Your CA certificate is now ready. Next, you will need to generate a private key and certificate request from your server to your CA to be signed.

cd /root/EasyRSA-3.0.4/
./easyrsa gen-req server nopass

Output:

Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
...................................................................................................................................+++
.........+++
writing new private key to '/root/EasyRSA-3.0.4/pki/private/server.key.J9mQs5Hu6D'
-----
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.
-----
Common Name (eg: your user, host, or server name) [server]:server

Keypair and certificate request completed. Your files are:
req: /root/EasyRSA-3.0.4/pki/reqs/server.req
key: /root/EasyRSA-3.0.4/pki/private/server.key

The above command will create a private key for the server and a certificate request file called server.req.

Next, copy the server key to the /etc/openvpn/ directory with the following command:

cp /root/EasyRSA-3.0.4/pki/private/server.key /etc/openvpn/

Next, sign the request by running the following command:

./easyrsa sign-req server server

Type yes and press ENTER, you should see the following output:

Note: using Easy-RSA configuration from: ./vars

You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 3650 days:

subject=
commonName = server

Type the word ‘yes’ to continue, or any other input to abort.
Confirm request details: yes
Using configuration from ./openssl-easyrsa.cnf
Can’t open /root/EasyRSA-3.0.4/pki/index.txt.attr for reading, No such file or directory
139883743228352:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:74:fopen(‘/root/EasyRSA-3.0.4/pki/index.txt.attr’,’r’)
139883743228352:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:81:
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
commonName :ASN.1 12:’serevr’
Certificate is to be certified until Apr 2 16:33:46 2029 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /root/EasyRSA-3.0.4/pki/issued/server.crt

Next, copy the server.crt and ca.crt files into your /etc/openvpn/ directory with the following command:

cp /root/EasyRSA-3.0.4/pki/ca.crt /root/EasyRSA-3.0.4/pki/issued/server.crt /etc/openvpn/

Next, create a strong Diffie-Hellman key with the following command:

./easyrsa gen-dh

You should see the following output:

Note: using Easy-RSA configuration from: ./vars
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
.......................................................+..............................................................................+..................................................+.......................+...........+................................+....................................................................................................................................+..............................................................................................................................................................+.....................................................+..................................................................................................................
DH parameters of size 2048 created at /root/EasyRSA-3.0.4/pki/dh.pem

Next, generate an HMAC signature to strengthen the server’s TLS integrity verification capabilities

openvpn --genkey --secret ta.key

Next, copy ta.key and dh.pem file to your /etc/openvpn/ directory with the following command:

cp /root/EasyRSA-3.0.4/ta.key /etc/openvpn/
cp /root/EasyRSA-3.0.4/pki/dh.pem /etc/openvpn/

Now, all the certificate and key file have been generated.

Create Client Certificate and Key Pair

Next, you will need to generate a private key and certificate for your client.

First, create a directory structure to store the client certificate and key files:

mkdir -p /root/client/keys

Next, change the directory to EasyRSA directory and generate client certificate using the following command:

cd EasyRSA-3.0.4
./easyrsa gen-req client nopass

You should see the following output:

Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
...............................+++
.................+++
writing new private key to '/root/EasyRSA-3.0.4/pki/private/client.key.BuZeMCbgyp'
-----
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.
-----
Common Name (eg: your user, host, or server name) [client]:

Keypair and certificate request completed. Your files are:
req: /root/EasyRSA-3.0.4/pki/reqs/client.req
key: /root/EasyRSA-3.0.4/pki/private/client.key

Next, copy client.key file to client/keys directory:

cp /root/EasyRSA-3.0.4/pki/private/client.key /root/client/keys/

Next, sign the certificate request for client with the following command:

./easyrsa sign-req client client

Output:

Note: using Easy-RSA configuration from: ./vars

You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a client certificate for 3650 days:

subject=
commonName = client

Type the word ‘yes’ to continue, or any other input to abort.
Confirm request details: yes
Using configuration from ./openssl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
commonName :ASN.1 12:’client’
Certificate is to be certified until Apr 2 16:46:49 2029 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /root/EasyRSA-3.0.4/pki/issued/client.crt

Next, copy client certificate file client.crt file to client/keys directory:

cp /root/EasyRSA-3.0.4/pki/issued/client.crt /root/client/keys/

Next, also copy the ca.crt and ta.key files to the client/keys directory:

cp /root/EasyRSA-3.0.4/ta.key /root/client/keys/
cp /etc/openvpn/ca.crt /root/client/keys/

Your server and client certificates are now ready to use.

Configure OpenVPN

Next, you will need to configure OpenVPN service to use all the certificates which you have created earlier.
First, copy a sample OpenVPN configuration file into OpenVPN directory:

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/

Next, extract the configuration file with the following command:

gzip -d /etc/openvpn/server.conf.gz

Next, open /etc/openvpn/server.conf file and make some changes:

nano /etc/openvpn/server.conf

Make the following changes:

tls-auth ta.key 0
key-direction 0
cipher AES-256-CBC
auth SHA256
dh dh.pem
user nobody
group nogroup
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
##Change the following files name, if you selected a different name during the ./build-key-server:
cert server.crt
key server.key

Save and close the file, when you are finished.

Next, enable your server’s default IP forwarding setting by editing /etc/sysctl.conf file:

nano /etc/sysctl.conf

Change the following line:

net.ipv4.ip_forward=1

Save and close the file. Then, apply the settings with the following command:

sysctl -p

Next, you will need to configure UFW rules listed in the before.rules file. You can do it with the following command:

nano /etc/ufw/before.rules

Add the following lines:

# ufw-before-output
# ufw-before-forward
#
*nat
:POSTROUTING ACCEPT [0:0]
# Change the network interface name from enp0s3 to your server's interface name:
-A POSTROUTING -s 10.8.0.0/8 -o enp0s3 -j MASQUERADE
COMMIT

Save and close the file. Then, allow the forwarded packets with the following command:

nano /etc/default/ufw

Make the following changes:

DEFAULT_FORWARD_POLICY="ACCEPT"

Save and close the file. Then, allow port 1194 and 22 through UFW with the following command:

ufw allow 1194/udp
ufw allow OpenSSH

Next, reload the UFW with the following command:

ufw disable
ufw enable

Finally, restart the OpenVPN service with the following command:

systemctl restart openvpn@server

Create Client Configuration

Next, you will need to create a configuration files for OpenVPN client.

First, create a directory under client/ with the following command:

mkdir client/files

Next, create a configuration file for Client with the following command:

nano client/base.conf

Add the following lines:

client
dev tun
proto udp
remote 192.168.0.101 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
key-direction 1
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
verb 3

Save and close the file.

Next, create a simple script to generate client configuration file using base.conf file:

nano client/make_config.sh

Add the following lines:

#!/bin/bash

KEY_DIR=~/client//keys
OUTPUT_DIR=~/client/files
BASE_CONFIG=~/client/base.conf

cat ${BASE_CONFIG} \
<(echo -e ‘<ca>’) \
${KEY_DIR}/ca.crt \
<(echo -e ‘</ca>\n<cert>’) \
${KEY_DIR}/${1}.crt \
<(echo -e ‘</cert>\n<key>’) \
${KEY_DIR}/${1}.key \
<(echo -e ‘</key>\n<tls-auth>’) \
${KEY_DIR}/ta.key \
<(echo -e ‘</tls-auth>’) \
> ${OUTPUT_DIR}/${1}.ovpn

Save and close the file. Then, generate client configuration file with the following command:

chmod 700 client/make_config.sh
bash client/make_config.sh

This will generate a client configuration file client.ovpn in /root/client/files directory.

Install and Configure OpenVPN Client

OpenVPN server is now ready to use. It’s time to install OpenVPN on Client system and connect with OpenVPN server.

On the Client system, install OpenVPN package with the following command:

apt-get install openvpn -y

Next, copy client.ovpn file from server to client machine with the following command:

scp root@192.168.0.101:/root/client/files/client.ovpn .

Next, connect the OpenVPN server by just running the following command:

openvpn --config client.ovpn

You should see the following output:

Fri Apr 5 23:21:17 2019 Outgoing Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
Fri Apr 5 23:21:17 2019 Incoming Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
Fri Apr 5 23:21:17 2019 Socket Buffers: R=[212992->212992] S=[212992->212992]
Fri Apr 5 23:21:17 2019 UDPv4 link local: [undef]
Fri Apr 5 23:21:17 2019 UDPv4 link remote: [AF_INET]192.168.0.101:1194
Fri Apr 5 23:21:17 2019 TLS: Initial packet from [AF_INET]192.168.0.101:1194, sid=3f05939f fb08f058
Fri Apr 5 23:21:17 2019 VERIFY OK: depth=1, CN=ChangeMe
Fri Apr 5 23:21:17 2019 Validating certificate key usage
Fri Apr 5 23:21:17 2019 ++ Certificate has key usage 00a0, expects 00a0
Fri Apr 5 23:21:17 2019 VERIFY KU OK
Fri Apr 5 23:21:17 2019 Validating certificate extended key usage
Fri Apr 5 23:21:17 2019 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Fri Apr 5 23:21:17 2019 VERIFY EKU OK
Fri Apr 5 23:21:17 2019 VERIFY OK: depth=0, CN=server
Fri Apr 5 23:21:17 2019 Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Fri Apr 5 23:21:17 2019 Data Channel Encrypt: Using 512 bit message hash 'SHA512' for HMAC authentication
Fri Apr 5 23:21:17 2019 Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Fri Apr 5 23:21:17 2019 Data Channel Decrypt: Using 512 bit message hash 'SHA512' for HMAC authentication
Fri Apr 5 23:21:17 2019 Control Channel: TLSv1, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-SHA, 2048 bit RSA
Fri Apr 5 23:21:17 2019 [server] Peer Connection Initiated with [AF_INET]192.168.0.101:1194
Fri Apr 5 23:21:20 2019 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Fri Apr 5 23:21:20 2019 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 8.8.8.8,dhcp-option DNS 8.8.4.4,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0'
Fri Apr 5 23:21:20 2019 OPTIONS IMPORT: timers and/or timeouts modified
Fri Apr 5 23:21:20 2019 OPTIONS IMPORT: --ifconfig/up options modified
Fri Apr 5 23:21:20 2019 OPTIONS IMPORT: route options modified
Fri Apr 5 23:21:20 2019 OPTIONS IMPORT: route-related options modified
Fri Apr 5 23:21:20 2019 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
Fri Apr 5 23:21:20 2019 ROUTE_GATEWAY 192.168.0.1/255.255.255.0 IFACE=wlan0 HWADDR=4c:bb:58:9c:f5:55
Fri Apr 5 23:21:20 2019 TUN/TAP device tun0 opened
Fri Apr 5 23:21:20 2019 TUN/TAP TX queue length set to 100
Fri Apr 5 23:21:20 2019 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Fri Apr 5 23:21:20 2019 /sbin/ip link set dev tun0 up mtu 1500
Fri Apr 5 23:21:20 2019 /sbin/ip addr add dev tun0 10.8.0.2/24 broadcast 10.8.0.255
Fri Apr 5 23:21:20 2019 /sbin/ip route add 192.168.0.101/32 via 192.168.0.1
Fri Apr 5 23:21:20 2019 /sbin/ip route add 0.0.0.0/1 via 10.8.0.1
Fri Apr 5 23:21:20 2019 /sbin/ip route add 128.0.0.0/1 via 10.8.0.1
Fri Apr 5 23:21:20 2019 Initialization Sequence Completed

You can also see the IP address receive from OpenVPN server with the following command:

ifconfig

You should see that tun0 interface has been created with IP address 10.8.0.2:

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:6509 errors:0 dropped:0 overruns:0 frame:0
TX packets:6509 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:598491 (598.4 KB) TX bytes:598491 (598.4 KB)

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.2 P-t-P:10.8.0.2 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:53 errors:0 dropped:0 overruns:0 frame:0
TX packets:449 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:16144 (16.1 KB) TX bytes:37566 (37.5 KB)

wlan0 Link encap:Ethernet HWaddr 4c:bb:58:9c:f5:55
inet addr:192.168.0.103 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::4ebb:58ff:fe9c:f555/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:127168 errors:0 dropped:0 overruns:0 frame:0
TX packets:111519 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:133910878 (133.9 MB) TX bytes:17131699 (17.1 MB)