Updated 03-Aug-2025
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
- Debian on AWS Lightsail
- OpenVPN on Debian + UFW Firewall
- Nginx and Letsencrypt on Debian
- PHP & MariaDB on Debian
- Grav CMS on Debian
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
DROPto: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 yourservername - 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.