Introduction

OpenVPN is a full-featured SSL VPN which implements OSI layer 2 or 3 secure network extension using the industry standard SSL/TLS protocol, supports flexible client authentication methods based on certificates, smart cards, and/or username/password credentials, and allows user or group-specific access control policies using firewall rules applied to the VPN virtual interface. OpenVPN is not a web application proxy and does not operate through a web browser.

OpenVPN 2.0 expands on the capabilities of OpenVPN 1.x by offering a scalable client/server mode, allowing multiple clients to connect to a single OpenVPN server process over a single TCP or UDP port. OpenVPN 2.3 includes a large number of improvements, including full IPv6 support and PolarSSL support.

Basic topology multi-client server

Installation on CentOS 7 with easy-rsa 3

[root@openvpn 3]# yum install epel-release
[root@openvpn 3]# yum update -y; yum upgrade
[root@openvpn 3]# yum install openvpn easy-rsa 

[root@openvpn 3]# openvpn --version
[root@openvpn 3]# ls -lah /usr/share/easy-rsa/

Configure easy-rsa 3 (create new vars)

[root@openvpn 3]# cd /etc/openvpn/
[root@openvpn 3]# cp -r /usr/share/easy-rsa /etc/openvpn/

[root@openvpn 3]# cd /etc/openvpn/easy-rsa/3/
[root@openvpn 3]# cat >> vars
set_var EASYRSA                 "$PWD"
set_var EASYRSA_PKI             "$EASYRSA/pki"
set_var EASYRSA_DN              "cn_only"
set_var EASYRSA_REQ_COUNTRY     "ID"
set_var EASYRSA_REQ_PROVINCE    "Jakarta"
set_var EASYRSA_REQ_CITY        "Jakarta"
set_var EASYRSA_REQ_ORG         "Darin-labs Certificate Authority"
set_var EASYRSA_REQ_EMAIL       "[email protected]"
set_var EASYRSA_REQ_OU          "Darin-labs Easy CA"
set_var EASYRSA_KEY_SIZE        2048
set_var EASYRSA_ALGO            rsa
set_var EASYRSA_CA_EXPIRE       7500
set_var EASYRSA_CERT_EXPIRE     365
set_var EASYRSA_NS_SUPPORT      "no"
set_var EASYRSA_NS_COMMENT      "Darin-labs Certificate Authority"
set_var EASYRSA_EXT_DIR         "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF        "$EASYRSA/openssl-1.0.cnf"
set_var EASYRSA_DIGEST          "sha256"

#Change values of the variables as you need.
#Increase the 'EASYRSA_KEY_SIZE' for better security.
#Change 'EASYRSA_CA_EXPIRE' and 'EASYRSA_CERT_EXPIRE'.

[root@openvpn 3]# chmod +x vars

Build OpenVPN keys

Build the OpenVPN keys based on the easy-rsa 3 'vars' file that we've created.
Build the CA key, Server and Client keys, DH and CRL PEM file.

[root@openvpn 3]# cd /etc/openvpn/easy-rsa/3/
[root@openvpn 3]# ./easyrsa init-pki #Initiate the PKI directory 
[root@openvpn 3]# ./easyrsa build-ca #Build the CA key

#Type the password for CA key, you will get ca.crt and ca.key
...
PKI dir is: /etc/openvpn/easy-rsa/3/pki
...
Your new CA certificate file for publishing is at:
/etc/openvpn/easy-rsa/3/pki/ca.crt

Build server key

[root@openvpn 3]# ./easyrsa gen-req darin-server nopass
#nopass = option for disable password for the key.

Generating a 2048 bit RSA private key
......................+++
..+++
writing new private key to '/etc/openvpn/easy-rsa/3/pki/private/darin-server.key.yVGJEl5Rbr'
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/3/pki/reqs/darin-server.req
key: /etc/openvpn/easy-rsa/3/pki/private/darin-server.key

Sign the 'darin-server.key' using our CA certificate.

[root@openvpn 3]# ./easyrsa sign-req server darin-server
You are about to sign the following certificate.
....
commonName = openvpn.darin.web.id
Confirm request details: yes
Using configuration from /etc/openvpn/easy-rsa/3/openssl-1.0.cnf
Enter pass phrase for /etc/openvpn/easy-rsa/3/pki/private/ca.key:
Check that the request matches the signature
Signature ok
....
commonName            :ASN.1 12:'openvpn.darin.web.id'
Certificate is to be certified until May  2 07:32:04 2020 GMT (365 days)
Write out database with 1 new entries Data Base Updated Certificate created at:
/etc/openvpn/easy-rsa/3/pki/issued/darin-server.crt     

Verify the certificate file

[root@openvpn 3]# openssl verify -CAfile pki/ca.crt pki/issued/darin-server.crt
pki/issued/darin-server.crt: OK

Build the client key

[root@openvpn 3]# ./easyrsa gen-req client01 nopass
[root@openvpn 3]# ./easyrsa gen-req client02 nopass

Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/3/pki/reqs/client01.req
key: /etc/openvpn/easy-rsa/3/pki/private/client01.key
...
req: /etc/openvpn/easy-rsa/3/pki/reqs/client02.req 
key: /etc/openvpn/easy-rsa/3/pki/private/client02.key

Sign the 'client.key' using our CA certificate.

[root@openvpn 3]# ./easyrsa sign-req client client01
[root@openvpn 3]# ./easyrsa sign-req client client02
...
Certificate created at: /etc/openvpn/easy-rsa/3/pki/issued/client01.crt 
Certificate created at: /etc/openvpn/easy-rsa/3/pki/issued/client02.crt 

Verify the certificate file

[root@openvpn 3]# openssl verify -CAfile pki/ca.crt pki/issued/client01.crt
[root@openvpn 3]# openssl verify -CAfile pki/ca.crt pki/issued/client02.crt
...
pki/issued/client02.crt: OK
pki/issued/client02.crt: OK

Build Diffie-Hellman key

[root@openvpn 3]# ./easyrsa gen-dh
DH parameters of size 2048 created at /etc/openvpn/easy-rsa/3/pki/dh.pem  

Copy certificate files

[root@openvpn 3]# cp pki/ca.crt /etc/openvpn/server/
[root@openvpn 3]# cp pki/issued/darin-server.crt /etc/openvpn/server/
[root@openvpn 3]# cp pki/private/darin-server.key /etc/openvpn/server/

[root@openvpn 3]# mkdir /etc/openvpn/client01/
[root@openvpn 3]# mkdir /etc/openvpn/client02/
[root@openvpn 3]# cp pki/ca.crt /etc/openvpn/client01/
[root@openvpn 3]# cp pki/ca.crt /etc/openvpn/client02/
[root@openvpn 3]# cp pki/issued/client01.crt /etc/openvpn/client01/
[root@openvpn 3]# cp pki/issued/client02.crt /etc/openvpn/client02/
[root@openvpn 3]# cp pki/private/client01.key /etc/openvpn/client01/
[root@openvpn 3]# cp pki/private/client02.key /etc/openvpn/client02/

[root@openvpn 3]# cp pki/dh.pem /etc/openvpn/server/

Configure OpenVPN

Sample configuration, according to topology
[root@openvpn 3]# vi /etc/openvpn/server.conf

# OpenVPN Port, Protocol and the Tun
port 1194
proto udp
dev tun

tun-mtu 1500
mssfix 1400    

# OpenVPN Server Certificate - CA, server key and certificate
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/darin-server.crt
key /etc/openvpn/server/darin-server.key

#DH and CRL key
dh /etc/openvpn/server/dh.pem

# Network Configuration - Internal network
# Redirect all Connection through OpenVPN Server
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1"

# Using the DNS from https://dns.watch
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

#Enable multiple client to connect with same Certificate key
duplicate-cn

# TLS Security
cipher AES-256-CBC
tls-version-min 1.2
auth SHA512
auth-nocache

remote-cert-tls client

# Other Configuration
keepalive 20 60
persist-key
persist-tun
comp-lzo yes
daemon
user nobody
group nobody

# OpenVPN Log
log-append /var/log/openvpn.log
verb 3
explicit-exit-notify 1
Enable Port-Forwarding and Configure Routing Firewalld
[root@openvpn 3]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@openvpn 3]# sysctl -p

[root@openvpn 3]# firewall-cmd --permanent --add-service=openvpn
[root@openvpn 3]# firewall-cmd --permanent --zone=trusted --add-interface=tun0
[root@openvpn 3]# firewall-cmd --permanent --zone=trusted --add-masquerade

[root@openvpn 3]# SERVERIP=$(ip route get [ip-public] | awk 'NR==1 {print $(NF-2)}')
[root@openvpn 3]# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s  10.8.0.0/24 -o $SERVERIP -j MASQUERADE
[root@openvpn 3]# firewall-cmd --reload

Start OpenVPN Service

[root@openvpn 3]# systemctl start openvpn@server
[root@openvpn 3]# systemctl enable openvpn@server
[root@openvpn 3]# systemctl status openvpn@server
[root@openvpn 3]# netstat -plntu

Configure OpenVPN Client

[root@openvpn 3]# cd /etc/openvpn/client01
[root@openvpn 3]# cat >> client01.ovpn
client
dev tun
proto udp
tun-mtu 1500
mssfix 1400
remote [ip-public] 1194
remote-cert-tls server
ca ca.crt
cert client01.crt
key client01.key
comp-lzo
resolv-retry infinite
compress lzo
nobind
persist-key
persist-tun
mute-replay-warnings
verb 3
cipher AES-256-CBC
auth-nocache

[root@openvpn 3]# cd /etc/openvpn/client02
[root@openvpn 3]# cat >> client02.ovpn
client
dev tun
proto udp
tun-mtu 1500
mssfix 1400
remote [ip-public] 1194
remote-cert-tls server
ca ca.crt
cert client02.crt
key client02.key
comp-lzo
resolv-retry infinite
compress lzo
nobind
persist-key
persist-tun
mute-replay-warnings
verb 3
cipher AES-256-CBC
auth-nocache

Compress and send the client folder

[root@openvpn 3]# cd /etc/openvpn/
[root@openvpn 3]# zip -r client01.zip client01
[root@openvpn 3]# zip -r client02.zip client02
[root@openvpn 3]# scp client.zip root@client01-ip://
[root@openvpn 3]# scp client.zip root@client02-ip://

Testing from the client (linux machine)

apt/yum -y install openvpn
cd /root; unzip clientx.zip
openvpn --config clientx.ovpn
test ping to the openvpn server and between client

Additional

  1. How to listing which vpn clients are connected?

    • Add status /var/log/openvpn-status.log in your /etc/openvpn/server.conf and restart vpn server.
    • Use this command to view connected clients from the log.
      while true; do cat /var/log/openvpn-status.log | sed -n '/OpenVPN CLIENT LIST/,/ROUTING TABLE/p' | tail -n+4 | sed "s/ROUTING TABLE//g"; sleep 4s; done
  2. How to revoke client key? Use CRL (Certificate Revoking List)

    • ./easyrsa gen-crl
    • The CRL PEM file has been generated under the 'pki' directory
    • Copy CRL Key to server : ```cp /usr/share/easy-rsa/3.0.3/pki/crl.pem /etc/openvpn/server/
    • Add new line to openvpn configuration file, copy this script : crl-verify /etc/openvpn/server/crl.pem
    • Restart OpenVPN Service
    • Revoke client key : ./easyrsa revoke someone

Reference :
https://www.howtoforge.com/tutorial/how-to-install-openvpn-server-and-client-with-easy-rsa-3-on-centos-7/