rss logo

How To Set Up OpenVPN on Debian 12 Bookworm

OpenVPN Logo

Here is a practical guide to setting up an OpenVPN server on Debian 12 Bookworm.

The aim is to turn our Debian server into a VPN gateway, allowing our remote Windows clients to connect to our entire network.

This is generally the solution I prefer as it allows easy access to all the company's internal networks (see the gateway mode section).

Network diagram

OpenVPN windows client/debian server architecture
  • OpenVPN Server:
    • OS: Debian GNU/Linux 12 (bookworm)
    • Role: OpenVPN Server + Gateway
    • IP: 192.168.0.254

Server (Debian)

Debian Logo

Installation

  • Install the openvpn package:
root@host:~# apt update && apt install openvpn
  • Enable automatic start-up of the OpenVPN service:
root@host:~# sed -i 's/#AUTOSTART="all"/AUTOSTART="all"/' /etc/default/openvpn ; systemctl daemon-reload

PKI

  • Enter the /etc/openvpn/ directory:
root@host:~# cd /etc/openvpn/
  • Initialise the pki:
root@host:~# /usr/share/easy-rsa/easyrsa clean-all root@host:~# /usr/share/easy-rsa/easyrsa init-pki
  • Type yes to initialise:
WARNING!!! You are about to remove the EASYRSA_PKI at: /etc/openvpn/pki and initialize a fresh PKI here. Type the word 'yes' to continue, or any other input to abort. Confirm removal: yes
  • If, like me, you don't want to regenerate certificates often, edit the file /etc/openvpn/pki/vars:
#Sets the validity period of the EasyRSA certificate authority to 10 years (3650 days). set_var EASYRSA_CA_EXPIRE 3650 #Sets the validity period of EasyRSA-issued certificates to 10 years (3650 days). set_var EASYRSA_CERT_EXPIRE 3650 #Sets the key size for the EasyRSA certificate authority to 4096 bits, ensuring high security without excessive processing load. set_var EASYRSA_KEY_SIZE 4096 #Sets EasyRSA certificate revocation list validity to 10 years. set_var EASYRSA_CRL_DAYS 3650
  • Create the certificate authority in /etc/openvpn/pki/ca.crt:
root@host:~# /usr/share/easy-rsa/easyrsa build-ca nopass
  • Give a Common Name:
* Notice: Using Easy-RSA configuration from: /etc/openvpn/pki/vars * Notice: Using SSL: openssl OpenSSL 3.0.8 7 Feb 2023 (Library: OpenSSL 3.0.8 7 Feb 2023) Using configuration from /etc/openvpn/pki/cca2af5c/temp.3299e061 .........+++++ ............................+++++ ----- 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) [Easy-RSA CA]:openvpn-host CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: /etc/openvpn/pki/ca.crt

Server certificates

  • Generate a certificate and key for the server:
root@host:~# /usr/share/easy-rsa/easyrsa build-server-full server nopass
  • Generate the Diffie Hellman parameters in /etc/openvpn/pki/dh.pem:
root@host:~# /usr/share/easy-rsa/easyrsa gen-dh

Client certificates

  • Generate the client01 certificate:
Note: Client certificates are located in the /etc/openvpn/pki/private/ and /etc/openvpn/pki/issued/ directories. root@host:~# /usr/share/easy-rsa/easyrsa build-client-full client01 nopass
  • Generate 10 clients certificates in a single command:
root@host:~# for i in $(seq -w 1 10);do /usr/share/easy-rsa/easyrsa build-client-full client"$i" nopass; done

/etc/openvpn/server.conf

  • Edit the configuration file /etc/openvpn/server.conf:
port 1194 proto udp dev tun ca /etc/openvpn/pki/ca.crt cert /etc/openvpn/pki/issued/server.crt key /etc/openvpn/pki/private/server.key # the server.key private key must be kept secret dh /etc/openvpn/pki/dh.pem # internal tun0 connection IP server 10.50.8.0 255.255.255.0 ifconfig-pool-persist ipp.txt keepalive 10 120 # Compression - must be turned on at both end comp-lzo persist-key persist-tun # parameters to be adjusted according to your network configuration push "dhcp-option DNS 192.168.0.200" push "dhcp-option DOMAIN std.local" push "route 192.168.0.0 255.255.255.0" status /var/log/openvpn-status.log # verbose mode verb 3

Systemd

  • Enable the OpenVPN Server service:
root@host:~# systemctl enable openvpn@server.service
  • Start the OpenVPN Server service:
root@host:~# systemctl start openvpn@server.service

Gateway mode

Gateway mode allows us to make the 192.168.0.0/24 network accessible from the client side.

nftables

A few netfilter rules will allow vpn clients to access the entire network.

Identify network interfaces

  • List network interfaces:
root@host:~# ip addr sh 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 01:02:a0:21:fd:54 brd ff:ff:ff:ff:ff:ff inet OPENVPN_IP brd X.X.X.X scope global wan valid_lft forever preferred_lft forever inet6 fe80::ff:fe5d:f333/64 scope link valid_lft forever preferred_lft forever 3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 11:a2:a9:21:fd:54 brd ff:ff:ff:ff:ff:ff inet 192.168.0.254 brd X.X.X.X scope global wan valid_lft forever preferred_lft forever inet6 fe80::6a05:caff:fe39:c153/64 scope link valid_lft forever preferred_lft forever 4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500 link/none inet 10.50.8.1 peer 10.50.8.2/32 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::7ea2:577f:e834:7a20/64 scope link stable-privacy valid_lft forever preferred_lft forever

Temporary rules

  • Enter masquerade rules to make your internal network accessible to Windows VPN clients:
root@host:~# nft add table ip NAT root@host:~# nft add chain ip NAT my_masquerade '{ type nat hook postrouting priority 100; }' root@host:~# nft add rule NAT my_masquerade ip saddr { 10.50.8.0/24 } oifname enp2s0 masquerade

Persistant rules

  • To make our nat persistent, edit the /etc/nftables.conf file:
#!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority 0; } chain forward { type filter hook forward priority 0; } chain output { type filter hook output priority 0; } } table ip NAT { chain my_masquerade { type nat hook postrouting priority 100; policy accept; ip saddr { 10.50.8.0/24 } oifname "enp2s0" masquerade comment "outgoing NAT" } }
  • Enable the nftables service with the systemctl command:
root@host:~# systemctl enable nftables.service

Gateway mode

  • Edit /etc/sysctl.conf and add:
net.ipv4.ip_forward=1
  • And run this command to take this parameter into account:
root@host:~# sysctl -p /etc/sysctl.conf

What do I do if my OpenVPN only has one network interface and it's not my default gateway?

OpenVPN VM server architecture

Of course, we may find ourselves in a situation where we can't install OpenVPN on our router. In this case, we could for example, install our OpenVPN server as a virtual machine.

We obviously need to create a port forwarder on our wan router to redirect OpenVPN traffic (step 1 on the diagram) to our OpenVPN server (step 2).

And that's it, it won't change much in terms of configuration because we still need to enable gateway mode and create a NAT rule.

In fact, all we need to do is apply exactly the same rules as before and we're done.

Windows client configuration

Microsoft Logo
  • Files to be taken from the server and copied to the client:
    • ca.crt: /etc/openvpn/pki/ca.crt
    • client01.crt: /etc/openvpn/pki/issued/client01.crt
    • client01.key: /etc/openvpn/pki/private/client01.key
  • You should see the following client files:
openvpn files on a windows host
  • Edit the file C:\Program Files\OpenVPN\config\client.ovpn:
client dev tun proto udp remote OPENVPN_IP 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert client01.crt key client01.key comp-lzo verb 3
  • Open OpenVPN with administrator rights (otherwise the routing rules will not work) and connect:
Note: Running in administrator mode no longer seems to be necessary in the latest versions. Start openvpn from a windows host
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address