Setup OpenVPN server on Debian 9

1. Installing OpenVPN and EasyRSA

On the OpenVPN server:

sudo apt update
sudo apt install openvpn -y

# Choose the newest release
wget -P ~/server https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz
cd server
tar xvf EasyRSA-nix-3.0.5.tgz

On the CA server:

# Choose the newest release
wget -P ~/ca https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz
cd ca
tar xvf EasyRSA-nix-3.0.5.tgz
cd ca/EasyRSA-3.0.5/

2. Configure EasyRSA and build CA

On the CA server:

cp vars.example vars

vi vars
# uncomment and fill in your information: 
set_var EASYRSA_REQ_COUNTRY    "LT"
set_var EASYRSA_REQ_PROVINCE   "Vilnius"
set_var EASYRSA_REQ_CITY       "Vilnius"
set_var EASYRSA_REQ_ORG        "Jonas"
set_var EASYRSA_REQ_EMAIL      "admin@example.com"
set_var EASYRSA_REQ_OU         "Organisational unit"

./easyrsa init-pki
./easyrsa build-ca nopass

3. Create the Server Certificate, Key, and Encryption Files

On the OpenVPN server:

cd server/EasyRSA-3.0.5/
./easyrsa init-pki
./easyrsa gen-req server nopass
sudo cp pki/private/server.key /etc/openvpn/

# copy server.req file to CA server
mkdir ~/ca/tmp && cp pki/reqs/server.req ~/ca/tmp/

On the CA server:

cd ~/ca/EasyRSA-3.0.5/
./easyrsa import-req ../tmp/server.req server
./easyrsa sign-req server server
mkdir ~/server/tmp && cp pki/issued/server.crt ../../server/tmp/
cp pki/ca.crt ../../server/tmp/ 

On the OpenVPN server:

cd ~/server/EasyRSA-3.0.5/
sudo cp ../tmp/server.crt /etc/openvpn/
sudo cp ../tmp/ca.crt /etc/openvpn/
./easyrsa gen-dh
sudo openvpn --genkey --secret ta.key
sudo cp ta.key /etc/openvpn/
sudo cp pki/dh.pem /etc/openvpn/

4. Generate a Client Certificate and Key Pair

On the OpenVPN server:

mkdir -p ~/server/client-configs/keys
chmod -R 700 ~/server/client-configs
./easyrsa gen-req client1 nopass
cp pki/private/client1.key ~/server/client-configs/keys/

# copy client1.req file to CA server
cp pki/reqs/client1.req ../../ca/tmp/

On the CA server:

cd ../../ca/EasyRSA-3.0.5/
./easyrsa import-req ../tmp/client1.req client1
./easyrsa sign-req client client1

#copy client1.crt file to OpenVPN server
cp pki/issued/client1.crt ../../server/tmp/

On the OpenVPN server:

cd ~/server/EasyRSA-3.0.5/
cp ../tmp/client1.crt ~/server/client-configs/keys/
sudo cp ta.key ~/server/client-configs/keys/
sudo cp /etc/openvpn/ca.crt ~/server/client-configs/keys/

5. Set up the OpenVPN service

On the OpenVPN server:

cd
sudo gzip -d /etc/openvpn/server.conf.gz

sudo vi /etc/openvpn/server.conf

# uncomment this line: 
tls-auth ta.key 0 # This file is secret

#add this line bewlow: 
key-direction 0

# uncomment this line: 
cipher AES-256-CBC

# add this line below: 
auth SHA256

#change line
dh dh2048.pem 
#to line
dh dh.pem

# uncomment these two lines: 
user nobody
group nogroup

# push DNS Changes to Redirect All Traffic Through the VPN
# uncomment these lines: 
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"

6. Adjust network accordingly

sudo vi /etc/sysctl.conf

# uncomment this line: 
net.ipv4.ip_forward=1

# read the file and apply changes to the current session
sudo sysctl -p

7. Enable the OpenVPN Sercice

sudo systemctl start openvpn@server
sudo systemctl status openvpn@server
ip addr show tun0
sudo systemctl enable openvpn@server

8. Forward all VPN client traffic through VPN server

# Masquerade outgoing traffic
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# Allow return traffic
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Forward everything
iptables -A FORWARD -j ACCEPT

# Save iptables configuration
sudo iptables-save | sudo tee /etc/iptables/rules.active

sudo vi editor /etc/network/if-pre-up.d/iptables
#!/bin/sh
/sbin/iptables-restore < /etc/iptables/rules.active

sudo chmod +x /etc/network/if-pre-up.d/iptables

9. Create client configuration infrastructure

mkdir -p server/client-configs/files
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/server/client-configs/base.conf

vi server/client-configs/base.conf

remote your_server_ip 1194
proto udp

# uncomment these lines for non-windows clients
user nobody
group nogroup

# comment out these lines
#ca ca.crt
#cert client.crt
#key client.key

# make sure these lines are
cipher AES-256-CBC
auth SHA256

# add these lines as well and uncomment if yout linux client has an /etc/openvpn/update-resolv-conf file
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
vi server/client-configs/make_config.sh

#!/bin/bash
# First argument: Client identifier

KEY_DIR=/home/jonas/server/client-configs/keys
OUTPUT_DIR=/home/jonas/server/client-configs/files
BASE_CONFIG=/home/jonas/server/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '\n') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '\n') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '\n') \
    ${KEY_DIR}/ta.key \
    <(echo -e '') \
    > ${OUTPUT_DIR}/${1}.ovpn
chmod 700 ~/server/client-configs/make_config.sh

10. Generate client config file

cd ~/server/client-configs/
sudo ./make_config.sh client1
ls -al files/

11. Connect to OpenVPN server from Ubuntu 18

sudo apt install openvpn 
sudo openvpn --config client1.ovpn