In this article we’ll consider the installation and configuration of an OpenVPN server running Linux CentOS/RHEL (7/8) and show how to join two remote computers (or offices) behind NAT into a single network using a configured OpenVPN server. VPN clients will be authenticated using certificates.
OpenVPN is one of the open source SSL/TLS-based implementations of the VPN technology based on OpenSSL. Using OpenVPN, you can connect both remote offices and individual computers behind a NAT device into a single network.
Install OpenVPN and Easy-RSA
In the first step, you must connect EPEL repository and update your host:
# yum install epel-release -y
# yum update -y
After the system has updated, install OpenVPN and Easy-RSA using yum package manager (we’ll need it to implement PKI key infrastructure on the VPN server).
# yum install openvpn easy-rsa -y
How to Configure Easy-RSA and Generate X.509 Certificates?
Copy all easy-rsa scripts to /etc/openvpn/:
# cp -r /usr/share/easy-rsa /etc/openvpn/
Go to /etc/openvpn/easy-rsa/3/ and create the vars file there:
# cd /etc/openvpn/easy-rsa/3/
# nano vars
Add the file contents (you can modify the config according to your needs):
set_var EASYRSA "$PWD" set_var EASYRSA_PKI "$EASYRSA/pki" set_var EASYRSA_DN "cn_only" set_var EASYRSA_REQ_COUNTRY "DE" set_var EASYRSA_REQ_PROVINCE "MUN" set_var EASYRSA_REQ_CITY "BY" set_var EASYRSA_REQ_ORG "WOSHUB" set_var EASYRSA_REQ_EMAIL "email@example.com" set_var EASYRSA_REQ_OU "IT dept" set_var EASYRSA_KEY_SIZE 4096 set_var EASYRSA_ALGO rsa set_var EASYRSA_CA_EXPIRE 7500 set_var EASYRSA_CERT_EXPIRE 3650 set_var EASYRSA_NS_SUPPORT "no" set_var EASYRSA_NS_COMMENT "CERTIFICATE AUTHORITY" set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-1.0.cnf" set_var EASYRSA_DIGEST "sha512"
You can specify any data in the file, it will not influence the configuration and further operation of the server.
The file must be executable, so run:
# chmod +x vars
Generate OpenVPN Certificates and Keys
Prior to creating a key, initialize the PKI directory and create a CA key.
# cd /etc/openvpn/easy-rsa/3/
# ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars init-pki complete; you may now create a CA or requests. Your newly created PKI dir is: /etc/openvpn/easy-rsa/3/pki
Create a CA key:
# ./easyrsa build-ca
After running the command, you will need to enter the password to generate the key and certificates. You will need the password later to sign the certificates.
Create a server key (the server name is vpn.woshub.com):
the nopass option disables password
# ./easyrsa gen-req vpn.woshub.com nopass
Note: using Easy-RSA configuration from: ./vars Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 Generating a 4096 bit RSA private key .........................++ writing new private key to '/etc/openvpn/easy-rsa/3/pki/private/vpn.woshub.com.key.R4IYCbD1zP' ----- 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) [vpn.woshub.com]: Keypair and certificate request completed. Your files are: req: /etc/openvpn/easy-rsa/3/pki/reqs/vpn.woshub.com.req key: /etc/openvpn/easy-rsa/3/pki/private/vpn.woshub.com.key
When issuing a certificate, press Enter in the Common Name column.
Sign the vpn.woshub.com key using our CA certificate:
# ./easyrsa sign-req server vpn.woshub.com
To sign the certificate, we will need the password we have set when issuing the CA certificate:
As shown in the screenshot, you will have to enter yes and CA password in process.
To make sure the certificates have been generated with no errors, run this command:
# openssl verify -CAfile pki/ca.crt pki/issued/vpn.woshub.com.crt
All OpenVPN server certificates have been created.
- The root certificate
- The private server key
- The server certificate
To generate a client key, run the following command:
# ./easyrsa gen-req client_name nopass
Let’s generate admin1 client key:
# ./easyrsa gen-req admin1 nopass
Note: using Easy-RSA configuration from: ./vars Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 Generating a 4096 bit RSA private key ..........++ writing new private key to '/etc/openvpn/easy-rsa/3/pki/private/admin1.key.R5OY6reT2e' ----- 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) [admin1]: Keypair and certificate request completed. Your files are: req: /etc/openvpn/easy-rsa/3/pki/reqs/admin1.req key: /etc/openvpn/easy-rsa/3/pki/private/admin1.key
You must sign it using the CA certificate, like the server key:
# ./easyrsa sign-req client admin1
The certificate for the user has been created.
Additionally, you have to generate a Diffie-Hellman key to be used for key exchange:
# ./easyrsa gen-dh
It takes some time to generate:
Then generate a TSL certificate:
# openvpn --genkey --secret ta.key
If later we are going to revoke client certificates, we need to generate a CRL key:
# ./easyrsa gen-crl
Note: using Easy-RSA configuration from: ./vars Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 Using configuration from /etc/openvpn/easy-rsa/3/pki/safessl-easyrsa.cnf Enter pass phrase for /etc/openvpn/easy-rsa/3/pki/private/ca.key: An updated CRL has been created. CRL file: /etc/openvpn/easy-rsa/3/pki/crl.pem
To revoke a certificate, run this command:
./easyrsa revoke admin1 — where admin1 is the certificate name
The necessary certificates have been created. Now copy them to the work directories.
Here are the server certificates:
# cp pki/ca.crt /etc/openvpn/server/
# cp pki/issued/vpn.woshub.com.crt /etc/openvpn/server/
# cp pki/private/vpn.woshub.com.key /etc/openvpn/server/
# cp pki/private/dh.pem /etc/openvpn/server/
# cp pki/private/ta.key /etc/openvpn/server/
# cp pki/crl.pem /etc/openvpn/server/
Here are the client certificates:
# cp pki/issued/admin1.crt /etc/openvpn/client/
# cp pki/private/admin1.key /etc/openvpn/client/
OpenVPN Server Configuration File, Firewall Rules
Let’s move on to the settings of OpenVPN configuration file. First of all, create your OpenVPN configuration file server.conf:
# cd /etc/openvpn/ && nano server.conf
Change the file contents as follows:
# Specify the port, protocol and device port 1194 proto udp dev tun # Specify the paths to the server certificates ca /etc/openvpn/server/ca.crt cert /etc/openvpn/server/vpn.woshub.com.crt key /etc/openvpn/server/vpn.woshub.com.key # Paths to key CRL and DH dh /etc/openvpn/server/dh.pem crl-verify /etc/openvpn/server/crl.pem # Specify the IP settings of the network VPN clients will get addresses from server 10.1.2.0 255.255.255.0 push "redirect-gateway def1" # Specify the assigned DNS servers push "dhcp-option DNS 184.108.40.206" push "dhcp-option DNS 220.127.116.11" # Allow connection to different clients with the same key duplicate-cn # TLS protection tls-auth /etc/openvpn/server/ta.key 0 cipher AES-256-CBC tls-version-min 1.2 tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 auth SHA512 auth-nocache # Other configuration details keepalive 20 60 persist-key persist-tun comp-lzo yes daemon user nobody group nobody # Path to the log file log-append /var/log/openvpn.log verb 3
Then save the file. I have specified the default UDP port 1194 for my VPN server, but you can specify any free port on your server for your OpenVPN.
Now you just have to set firewall rules to allow connection and routing between segments.
If you are using firewalld, activate the forwarding kernel module first:
# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
# sysctl -p
net.ipv4.ip_forward = 1
Add openvpn service to firewalld, and tun0 interface to the trusted zone:
# firewall-cmd --permanent --add-service=openvpn
# firewall-cmd --permanent --zone=trusted --add-interface=tun0
Activate ‘MASQUERADE’ for the firewalld trusted zone:
# firewall-cmd --permanent --zone=trusted --add-masquerade
# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.1.2.0/24 -o Server_IP -j MASQUERADE
# firewall-cmd –reload
# iptables -t nat -A POSTROUTING -s 10.1.2.0/24 -o eth0 -j MASQUERADE
# iptables -A INPUT -p udp –dport 1194 -j ACCEPT
# service iptables save
Run OpenVPN service and add it to startup:
# systemctl start openvpn@server
# systemctl enable openvpn@server
Make sure that the udp\1194 port is listening by the openvpn service:
# lsof -i:1194
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME openvpn 12327 nobody 5u IPv4 45122 0t0 UDP *:openvpn
Check the IP settings of the network interface:
# ip a
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.1.2.1 peer 10.1.2.2/32 scope global tun0 valid_lft forever preferred_lft forever
As you can see, the network specified during the configuration is added to the tun0 device.
These are the minimum settings to make your OpenVPN work.
How to Connect Multiple Offices (Computers) Using OpenVPN?
Let’s see how to connect to the OpenVPN server from two remote computers having Internet access through NAT and join them into a single network. To connect from a computer running Windows to an OpenVPN server, I am using an official client. You can download it on the official website, but we won’t describe it in detail, and go directly to its configuration.
After you have installed the client, move on to creating the configuration file here:
I have created a file with the name client and added the following contents to it:
client dev tun proto udp remote 18.104.22.168 1194 resolv-retry infinite nobind block-outside-dns persist-key persist-tun mute-replay-warnings remote-cert-tls server tls-client auth SHA512 tls-auth "C:\\Program Files\\OpenVPN\\config\\ta.key" 1 remote-cert-eku "TLS Web Server Authentication" ca "C:\\Program Files\\OpenVPN\\config\\ca.crt" cert "C:\\Program Files\\OpenVPN\\config\\admin1.crt" key "C:\\Program Files\\OpenVPN\\config\\admin1.key" cipher AES-256-CBC comp-lzo verb 3
To configure it, we’ll need the client, security and server certificates we created earlier. You must download them from your server and place to a local folder. Then specify the path to them in the OpenVPN client configuration file.
Then you can connect to the server by clicking the OpenVPN icon in the tray:
I have connected and got the following IP address for my device:
IPv4 address. . . . . . . . . . . . : 10.1.2.14 Subnet mask . . . . . . . . . . : 255.255.255.0
On the second computer behind a NAT, I performed the same actions and created a certificate for the second user in advance. After connecting, the second PC also got an IP address from the VPN network:
IPv4 address. . . . . . . . . . . . : 10.1.2.16 Subnet mask . . . . . . . . . . : 255.255.255.0
After connecting, both computers are in the same network and see each other.
Ping the second PC:
Pinging 10.1.2.16 with 32 bytes of data: Reply from 10.1.2.16: bytes=32 time=73ms TTL=127
Ping on the first PC:
Pinging 10.1.2.14 with 32 bytes of data: Reply from 10.1.2.14: bytes=32 time=79ms TTL=127
Both connected VPN clients can send packets and transfer files directly to each other. Thus, we could join two device physically located in different places of the country into a single local network.
You can create any number of keys or certificates for users on your OpenVPN server. If you need a new certificate, run these commands for /etc/openvpn/easy-rsa/3:
# ./easyrsa gen-req clientname nopass
# ./easyrsa sign-req client clientname
Don’t forget to revoke client certificates if they are not used to keep your network secure.