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 ( and private IP is and It is in Public Subnet.

VPN subnet is:

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 script that will help you generate the certificate

$ sudo vi /etc/openvpn/server/

The content of this script


# Copyright © 2014 Steffan Karger <>

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 ]


echo “Please run this script from the sample directory”

exit 1


# 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 \


-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/”

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



plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/ login

push “redirect-gateway def1”

push “dhcp-option DNS”

push “dhcp-option DNS”

keepalive 10 120


user nobody

group nogroup



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

dev tun
redirect-gateway def1
remote 1194 udp
comp-lzo yes
auth-user-pass pass.txt
The contents of ca.crt that you generate on server

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:


$ 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 -o eth0 -j ACCEPT

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

DevOps Engineer