OpenVPN on Debian

Updated 28-Jun-2024

OpenVPN on Debian is the second step in securing an operating system. Below we include ufw firewall installation and configuration as well.


Related Artices in Debian Services and Applications


Note: install and configure ufw prior to openvpn installation and configuration

apt-get install ufw
sudo ufw allow http
sudo ufw allow https
sudo ufw allow 1194/udp
sudo ufw allow ssh
sudo ufw status
sudo ufw enable
sudo service ufw restart

> set the default to DROP

Edit the ufw config file

nano /etc/default/ufw
  • Change line from DROP to: DEFAULT_FORWARD_POLICY="ACCEPT"
  • Save

Edit the before.rules

nano /etc/ufw/before.rules

Add the START OPENVPN RULES as follows:

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.10.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
# Don't delete these required lines, otherwise there will be errors
*filter

Save file

Enable UFW

ufw enable

Check status

ufw status

Next install and configure the OpenVPN Server

Note: do this as root as it may not work otherwise, even with sudo

sudo apt-get install -y openvpn easy-rsa
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf > /etc/openvpn/server.conf
nano /etc/openvpn/server.conf
  • uncomment push "redirect-gateway def1 bypass-dhcp"
  • uncomment/modify push "dhcp-option DNS 84.200.69.80"
  • uncomment/modify push "dhcp-option DNS 84.200.70.40"
  • uncomment/modify user nobody
  • uncomment/modify group nogroup

Save file.

Note at some point the file should look like this:

port 1194
proto udp
dev tun
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
reneg-sec 0
ca ca.crt
cert fir.crt
key fir.key  # This file should be kept secret
dh dh2048.pem
server 10.10.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
duplicate-cn
keepalive 10 120
;tls-auth ta.key 0 # This file is secret
;cipher BF-CBC        # Blowfish (default)
;cipher AES-128-CBC   # AES
;cipher AES-256-CBC   # AES 256
;cipher DES-EDE3-CBC  # Triple-DES
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
explicit-exit-notify 0

Next, enable forwarding:

echo 1 > /proc/sys/net/ipv4/ip_forward

Enable forwarding again:

nano /etc/sysctl.conf

Uncomment net.ipv4.ip_forward=1

Next Configure and Build Certificates

Copy scripts and templates as follows:

cp -r /usr/share/easy-rsa/ /etc/openvpn
mkdir /etc/openvpn/easy-rsa/keys
nano /etc/openvpn/easy-rsa/vars
  • Change export KEY_ variables (there are six of them) to match the organization
  • Change the export KEY_NAME="EasyRSA" to your servername
  • Change the line export KEY_CONFIG=$EASY_RSA/whichopensslcnf $EASY_RSA` to

export KEY_CONFIG=/etc/openvpn/easy-rsa/openssl-1.0.0.cnf

  • Save and exit

Next, generate the dh parameters

openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Next, clean up and build the ca, as follows:

cd /etc/openvpn/easy-rsa
chmod 0755 *
source ./vars
./clean-all
./build-ca

Generate Certificate and Key for the Server

Note: servername is your servername

./build-key-server servername

Note it will ask you to hit enter to accept variables multiple times, do that, and any additional questions just use enter.

When it asks to sign the cert and commit the cert, use y and y.

Next, move the certs/keys, but make sure to change the servername as above:

cp /etc/openvpn/easy-rsa/keys/{servername.crt,servername.key,ca.crt} /etc/openvpn

Verify files were copied:

ls -la /etc/openvpn

Start the service and check status:

service openvpn start
service openvpn status

Make sure you see Active: active (exited) since...

Generate Client Certs

Note that clientname is the client name, but in reality it is actually for the servername, so you know what/where you will connect to. The main point is to rename the clientname.ovpn file to servername.ovpn after it has concatenated and moved to the client.

Note: can use one client cert for everyone as long as the following line is added to the server.conf file: duplicate-cn

cd /etc/openvpn/easy-rsa
./build-key clientname

Next, copy and rename the client.conf to clientname.ovpn

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/clientname.ovpn

Edit the .ovpn file:

nano /etc/openvpn/easy-rsa/keys/clientname.ovpn

Should be something like:


-----BEGIN CERTIFICATE----- -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- key-direction 1 client dev tun remote 1.2.3.4 1194 udp resolv-retry infinite nobind tun-mtu 1500 user nobody group nogroup persist-key persist-tun pull tls-client push "redirect-gateway def1" mssfix 1450 tun-mtu-extra 32 reneg-sec 0 ;ca ca.crt ;cert client.crt ;key client.key ns-cert-type server comp-lzo verb 3

Note that the concatenated (unified) OpenVPN profile includes the ca, cert, and key. This can be done as follows (fix the below, it puts stuff at the end, not begining:

echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
cat /etc/openvpn/ca.crt >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
cat /etc/openvpn/easy-rsa/keys/clientname.crt >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
cat /etc/openvpn/easy-rsa/keys/clientname.key >> /etc/openvpn/easy-rsa/keys/clientname.ovpn
echo '' >> /etc/openvpn/easy-rsa/keys/clientname.ovpn

One can scp the file from server to client with the following command from the client:

scp -i /home/usr/drive/.ssh/servername.pem admin@servername:etc/openvpn/easy-rsa/keys/clientname.ovpn /home/usr/drive/.ssh/clientname.ovpn

Change names of drives and users as applicable.