How To Setup OpenVPN Authentication by Username and Password

OpenVPN is an open source VPN protocol across all OS platforms.

In this article, I will go over a step by step how to set up an OpenVPN server on Ubuntu (But you can apply for the other Linux distro like CentOS, Fedora,..).

And in this article, I will be setting OpenVPN to authenticate users using PAM (Username/Password).

In this scenario, I will run a VPN server on an AWS EC2 Instance, bellow is the diagram.

VPN server has external IP is EIP (198.51.100.1) and private IP is 10.0.0.5 and It is in Public Subnet.

VPN subnet is: 10.8.0.0/24

When users connect VPN success they can access the internal services through private IP (ex: DB, Web, Fileserver,..)

Note: To get more details about VPC on AWS you can refer here.

Installing OpenVPN Server

$ sudo apt-get install openvpn

Configure OpenVPN

$ sudo mkdir -p /etc/openvpn/server

Copy openssl.conf to /etc/openvpn/server/

$ sudo cp /usr/share/doc/openvpn/examples/sample-keys/openssl.cnf /etc/openvpn/server/

Create a gen-keys.sh script that will help you generate the certificate

$ sudo vi /etc/openvpn/server/gen-keys.sh

The content of this script

#!/bin/sh

# Copyright © 2014 Steffan Karger <steffan@karger.me>

set -eu

command -v openssl >/dev/null 2>&1 || { echo >&2 “Unable to find openssl. Please make sure openssl is installed and in your path.”; exit 1; }

if [ ! -f openssl.cnf ]

then

echo “Please run this script from the sample directory”

exit 1

fi

# Generate static key for tls-auth (or static key mode)

openvpn — genkey — secret ta.key

# Create required directories and files

mkdir -p sample-ca

rm -f sample-ca/index.txt

touch sample-ca/index.txt

echo “01” > sample-ca/serial

# Generate CA key and cert

openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 \

-extensions easyrsa_ca -keyout sample-ca/ca.key -out sample-ca/ca.crt \

-subj “/C=VN/ST=SAIGON/L=SAIGON/O=OpenVPN-TEST/emailAddress=vpn@test.net” \

-config openssl.cnf

# Create server key and cert

openssl req -new -nodes -config openssl.cnf -extensions server \

-keyout sample-ca/server.key -out sample-ca/server.csr \

-subj “/C=VN/ST=SAIGON/O=OpenVPN-TEST/CN=VPN-Server/emailAddress=vpn@test.net”

openssl ca -batch -config openssl.cnf -extensions server \

-out sample-ca/server.crt -in sample-ca/server.csr

# Generate DH parameters

openssl dhparam -out dh2048.pem 2048

Change to /etc/openvpn/server/sample-ca/ and copy server.key, server.crt, ca.crt, dh2048.pem to /etc/openvpn/

Create OpenVPN server configure server.conf

$ sudo vi /etc/openvpn/server.conf

The contents of the server configure are:

port 1194

proto udp

dev tun

ca ca.crt

cert server.crt

key server.key # This file should be kept secret

dh dh2048.pem

server 10.8.0.0 255.255.255.0

client-cert-not-required

plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/openvpn-plugin-auth-pam.so login

push “redirect-gateway def1”

push “dhcp-option DNS 8.8.8.8”

push “dhcp-option DNS 8.8.4.4”

keepalive 10 120

comp-lzo

user nobody

group nogroup

persist-key

persist-tun

status /var/log/openvpn/openvpn-status.log

log /var/log/openvpn/openvpn.log

log-append /var/log/openvpn/openvpn.log

verb 3

Start OpenVPN server

$ sudo systemctl start openvpn@server

Check the status

$ sudo systemctl status openvpn@server

See log

$ sudo tail -f /var/log/openvpn/openvpn.log

Client connect to OpenVPN server

  1. On the OpenVPN server create a Linux account test/test@1234
  2. Install OpenVPN client on your PC/Laptop: Linux, MAC, Windows
  3. Create client config (client.ovpn) and
  4. The contents of client.ovpn

client
nobind
dev tun
redirect-gateway def1
remote 198.51.100.1 1194 udp
comp-lzo yes
auth-user-pass pass.txt
auth-nocache
<ca>
— — -BEGIN CERTIFICATE — — -
The contents of ca.crt that you generate on server
— — -END CERTIFICATE — — -
</ca>

5. Create a pass.tx file at the same folder with client.ovpn with the content is username/password of VPN client, In this case, is test/test@1234

6. Connect to VPN server base on your client, I use Tunnelblick.

How to make your VPN client access internal services by private IP and Internet

On the server

  1. Enable IP Forwarding

$ sudo vi /etc/sysctl.d/IPforwarding.conf

which contains:

net.ipv4.ip_forward=1

$ sudo sysctl -p /etc/sysctl.d/IPforwarding.conf

2. Forward package by IPTables

iptables -A FORWARD -i eth0 -o tun0 -m state — state ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -s 10.8.0.0/24 -o eth0 -j ACCEPT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -o eth0 -j MASQUERADE

DevOps Engineer