Friday, April 12, 2019

How to Install OpenVPN (Easy-RSA 3) on Linux / CentOS 7 / AWS


Why OpenVPN with CentOS
A VPN (Virtual Private Network) enables you to create a secure connection to a remote network over the Internet through a virtual encrypted tunnel.
By routing the internet traffic through this encrypted tunnel, a VPN service not only masks your identity/location but also encrypts the data so that it can only be read by your VPN client and server.
So in general a VPN keeps your internet activity private and secure, preventing authorities and ISP to snoop your internet activity.
There are number of enterprise level and open source VPN solutions out there like OpenVPN, OpenSWAN, Softether to mention few.
In this article we will look at details about how to install and configure OpenVPN server in CentOS 7 followed by configuring a OpenVPN client.
Prerequisites:
  • You have a CentOS 7 system with credentials of root or a sudo enabled user
Installing OpenVPN on CentOS 7
OpenVPN package is not available with default CentOS repository. Therefore before proceeding with installation of OpenVPN server, you need to install the EPEL (Extra Packages for Enterprise Linux) repository.
Once EPEL package is there in the system, install OpenVPN by issuing following commands from the terminal.
# sudo yum install epel-release
# sudo yum update
# sudo yum install openvpn git
Next proceed with installing/configuring Easy-RSA (Version 3) which is a very handy key management tool for use with OpenVPN in the process of generating RSA keys.

Download and Configure Easy-RSA
Now that OpenVPN has been installed, use the following steps to download easy-rsa using git and then leveraging easy-rsa script, generate keys and certificates starting with Certificate authority(ca) file needed by OpenVPN server.
To start with, “cd” to OpenVPN configuration folder and download the easy-RSA script.
# cd /etc/openvpn/
# sudo git clone git://github.com/OpenVPN/easy-rsa
The only folder that we really need is the “easyrsa3” folder which holds the script for generating keys.
Since the keys and certificates are needed by both VPN client and OpenVPN server, create a directory for storing them.
But before that adjust few parameters in the easy-rsa variable definition file “vars” that is shipped along with Easy-RSA to reflect your environment.
# mkdir -p /etc/openvpn/keys
# cd /etc/openvpn/easy-rsa/easyrsa3
# cp vars.example vars
# vi vars

set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_CA_EXPIRE 3650
set_var EASYRSA_KEY_EXPIRE 3650
set_var EASYRSA_REQ_COUNTRY "IN"
set_var EASYRSA_REQ_PROVINCE "Telangana"
set_var EASYRSA_REQ_CITY "Hyderabad"
set_var EASYRSA_REQ_ORG "webhosting"
set_var EASYRSA_REQ_EMAIL "admin@web-hosting.org"
set_var EASYRSA_REQ_OU "webhosting-OU"
set_var EASYRSA_KEY_NAME "Easy RSA"
Now copy all the files and folders from “easyrsa3” to the location that we have created earlier for storing the keys and certificates.
# cp -rf /etc/openvpn/easy-rsa/easyrsa3/* /etc/openvpn/keys
At this point, the easy-rsa script is in right place for generating keys and certificates.
Proceed with generating certificates and keys for client and server in the next step.


Generate Certificate and Keys
Generate Server Certificate
Since the information required (country, organization, department etc.) for generating the certificate authority(CA) are already set through “vars” config file in the previous step, Let us start generating the same starting with initializing public key infrastructure (PKI) environment.
# cd /etc/openvpn/keys
# sudo ./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/keys/pki
Run the following command to create the “ca” files. You will be prompted for a passphrase, provide a reasonably strong passphrase as per your choice.

Easy-RSA script will ask to provide this passphrase again at later stage while creating server and client certificates.
# sudo ./easyrsa build-ca
The above command will generate all the files that one need to manage CA and are listed below.
- /etc/openvpn/keys/pki
- /etc/openvpn/keys/pki/ca.crt

Now that our CA is ready, let’s create a certificate for the server.
The only parameter that is needed is the CN and will be asked during the process. You can use user name or server hostname or whatever you want to name it.
# cd /etc/openvpn/keys
# sudo ./easyrsa gen-req BestWebHosting nopass

The relevant files those are generated during the process are:
- /etc/openvpn/keys/pki/private/BestWebHosting.key
- /etc/openvpn/keys/pki/reqs/BestWebHosting.req
- /etc/openvpn/keys/pki/issued/BestWebHosting.crt

Finally, sign your own request using CA. The script will prompt you for confirmation to create the certificate.

Moreover, it will also prompt to provide the passphrase that you have entered during CA certificate creation step.
# cd /etc/openvpn/server
# sudo ./easyrsa sign-req server BestWebHosting


Generate Client Certificates
This step is exactly same as previous step but the certificates generated in this step will be used by clients to connect to the OpenVPN server.
Lets generate a certificate for client say “john”, so make a request for john’s certificate.
# cd /etc/openvpn/keys
# sudo ./easyrsa gen-req john nopass
Then sign john’s request using CA to generate john’s certificate:
# sudo ./easyrsa sign-req client john

keypass: secretkey

The relevant certificate files for client’s are:
- /etc/openvpn/keys/pki/private/john.key
- /etc/openvpn/keys/pki/reqs/john.req
- /etc/openvpn/keys/pki/issued/john.crt

Remember to repeat this step for each client so that client’s should own unique certificates for better security.

Generate Diffie-Hellman Key Exchange
OpenVPN server also needs a Diffie-Hellman key exchange file. It will take some time to create this file depending on key length.
Of course, You can always change the key length through the last parameter of following “openssl” command.
# mkdir -p /etc/openvpn/ssl
# cd /etc/openvpn/ssl
# sudo openssl dhparam -out dh2048.pem 2048

Generate TLS Key
Adding this feature (tls-auth) is optional, but it adds an “extra protection” to the TLS channel by requiring that incoming packets have a valid signature generated using the PSK key.
Any packets that don’t have the valid signature signed by OpenVPN server will be discarded.
# cd /etc/openvpn/keys
# sudo openvpn --genkey --secret ta.key

Configure OpenVPN
Now create a OpenVPN configuration file by the name “server.conf”.
# cd /etc/openvpn
# sudo vi server.conf

I have used the following configuration options for OpenVPN server. But you can always fine-tune the following configuration for better results.
mode server
tls-server
port 1194
proto udp
dev tap
ca /etc/openvpn/keys/pki/ca.crt
cert /etc/openvpn/keys/pki/issued/vpnsrv.crt
key /etc/openvpn/keys/pki/private/vpnsrv.key
dh /etc/openvpn/ssl/dh2048.pem
crl-verify /etc/openvpn/ssl/crl.pem
tls-auth /etc/openvpn/keys/ta.key 0
server 10.8.0.0 255.255.255.0
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
push "route 172.31.0.0 255.255.0.0"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 5 30
log-append /var/log/vpn/openvpn.log
verb 3

Create log directory/file for OpenVPN server and change the security context of the log file to allow logging if SELINUX is enabled in your system.
# sudo mkdir -p /var/log/vpn
# sudo touch /var/log/vpn/openvpn.log
# sudo chcon -t var_log_t /var/log/vpn/openvpn.log

Configure Firewall/Routing
Assuming the default firewall management tool “Firewalld” have been installed in your system, then at first using firewalld allow OpenVPN traffic to pass through the firewall and make the setting permanent.
Use the “ifconfig” command to find the tunnel interface in your system.
# sudo firewall-cmd --permanent --add-service openvpn
# sudo firewall-cmd --permanent --zone=trusted --add-interface=tun0
Next, enable the masquerade and make it permanent:
# sudo firewall-cmd --permanent --zone=trusted --add-masquerade
Finally, Add the rule for forwarding the network traffic to OpenVPN subnet and reload the firewall.
The following “ROUT” variable will fetch the default interface from the system which is “eth0” in my system and forwards any traffic through it to the tunneled interface.
# ROUT=$(ip route get 8.8.8.8 | awk 'NR==1 {print $(NF-2)}')
# sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.1.1.0/24 -o $ROUT -j MASQUERADE
# sudo firewall-cmd --reload
To enable the OpenVPN server forward IPv4 packets between the interfaces, issue the following two commands from terminal.
# sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# sudo sysctl -p
Start the OpenVPN server:
# cd /etc/openvpn
# sudo openvpn server.conf &
OR
# sudo systemctl start openvpn@server.service

At this stage, OpenVPN server should be running in your server to accept the client’s connection. You can also check the OpenVPN server’s log for any possible issues with the following command.
# tail -f /var/log/vpn/openvpn.log

Configure OpenVPN Client
You need the following four files to connect to the OpenVPN server through any OpenVPN client.
Download these files from the server to your client system.
- ca.crt
- john.crt
- john.key
- ta.key

Once downloaded, create an OpenVPN client configuration file using your favorite editor and paste the contents of above four files along with other parameters like below.
It is also possible to call the above files from the OpenVPN clients configuration file without copying their content.
# cd ~
# vi john.ovpn
client
dev tap
proto udp
remote SERVER_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ca ca.crt
cert john.crt
key john.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
comp-lzo
auth-nocache
verb 3

Connecting from Linux
To connect OpenVPN server from any Linux flavored system, you need to install OpenVPN (client) and then connect to the OpenVPN server using the following command.
But before that you need to copy the above OpenVPN configuration file to your work station.
# cd ~
# sudo yum install openvpn
# sudo openvpn --config ~/john.ovpn


If you are installing OpenVPN on AWS VPC change the following settings:
AWS VPC Routing:
VPC -> Route tables -> edit routes

destination            target
10.8.0.0/24            eni-0038be700a763331cb<nat-instance>
save changes

Goto
Instances -> actions -> networking -> change source/Dest.check -> yes disable

Security Groups
Add UDP Port 1194 and allow 0.0.0.0/0



.............

Revoke vpn certificates for user:

If you want to revoke the access to one of your clients you have to run the following commands, the updated crl will be in /root/easy-rsa-3/pki/crl.pem, remember to copy it to whatever path you configured in openvpn server config and restart the openvpn service after copying it.

./easyrsa revoke <username>
./easyrsa gen-crl
cp -rp /etc/openvpn/keys/pki/crl.pem /etc/openvpn/ssl/