In this guide, we are going to learn how to install OpenVPN Server on Debian 11/Debian 10.
Installing OpenVPN Server on Debian
Run system update
apt update
Install OpenVPN on Debian 11/Debian 10
OpenVPN package is available on the default Debian 11/Debian 10 repos.
apt install openvpn -y
Create OpenVPN Public Key Infrastructure
Initialize the OpenVPN PKI. The PKI consists of:
- a public key and private key for the server and each client
- a master Certificate Authority (CA) certificate and key which is used to sign each of the server and client certificates.
Thus, copy the easy-rsa configuration directory to a different location to ensure that that future OpenVPN package upgrades won’t overwrite your modifications.
cp -r /usr/share/easy-rsa /etc/
Next, initialize the PKI.
cd /etc/easy-rsa/
./easyrsa init-pki
Sample command output;
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/easy-rsa/pki
Create the Certificate Authority (CA) Certificate and Key
Next, generate the CA certificate and key for signing OpenVPN server and client certificates.
cd /etc/easy-rsa/
./easyrsa build-ca
This will prompt you for the CA key passphrase and the server common name.
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus (2 primes)
.............................................+++++
...................................+++++
e is 65537 (0x010001)
Can't load /etc/easy-rsa/pki/.rnd into RNG
139670192284800:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/etc/easy-rsa/pki/.rnd
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]:Kifarunix-demo CA
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/easy-rsa/pki/ca.crt
The CA certificate is generated and stored at /etc/easy-rsa/pki/ca.crt
.
Generate Diffie Hellman Parameters
Generate Diffie-Hellman keys used for key exchange during the TLS handshake between OpenVPN server and the connecting clients. This command has be executed within the Easy-RSA directory;
./easyrsa gen-dh
DH parameters of size 2048 will be created at /etc/easy-rsa/pki/dh.pem
.
Generate OpenVPN Server Certificate and Key
To generate a certificate and private key for the OpenVPN server, run the command below;
cd /etc/easy-rsa
./easyrsa build-server-full server nopass
Enter the CA key passphrase create above to generate the certificates and keys.
nopass
disables the use of passphrase.
Sample output;
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating a RSA private key
........................................+++++
.......................................+++++
writing new private key to '/etc/easy-rsa/pki/private/server.key.MMFHTTtpKD'
-----
Using configuration from /etc/easy-rsa/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'server'
Certificate is to be certified until Oct 10 18:23:08 2024 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
Generate Hash-based Message Authentication Code (HMAC) key
TLS/SSL pre-shared authentication key is used as an additional HMAC signature on all SSL/TLS handshake packets to avoid DoS attack and UDP port flooding. This can be generated using the command;
openvpn --genkey secret /etc/easy-rsa/pki/ta.key
Generate OpenVPN Revocation Certificate
To invalidate a previously signed certificate, you need to generate a revocation certificate.
Run the script within the Easy-RSA directory;
./easyrsa gen-crl
The revocation certificate is generated and stored at /etc/easy-rsa/pki/crl.pem
.
Sample output;
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Using configuration from /etc/easy-rsa/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/easy-rsa/pki/private/ca.key:
An updated CRL has been created.
CRL file: /etc/easy-rsa/pki/crl.pem
Copy Server Certificates and Keys to Server Config Directory
Copy all generated server certificates/keys to OpenVPN server configuration directory.
cp -rp /etc/easy-rsa/pki/{ca.crt,dh.pem,ta.key,crl.pem,issued,private} /etc/openvpn/server/
Generate OpenVPN Client Certificates and Keys
OpenVPN clients certificates and private keys can be generated as follows
cd /etc/easy-rsa
./easyrsa build-client-full koromicha nopass
- where
koromicha
is the name of the client for which the certificate and keys are generated. - Always use a unique common name for each client that you are generating certificate and keys for.
Sample command output;
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating a RSA private key
...........................+++++
...........................................................................................................................+++++
writing new private key to '/etc/easy-rsa/pki/private/koromicha.key.saAaE6L0tX'
-----
Using configuration from /etc/easy-rsa/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'koromicha'
Certificate is to be certified until Oct 10 18:25:37 2024 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
To generate for the second client,
./easyrsa build-client-full janedoe nopass
You can see how to use easyrsa
command with ./easyrsa --help
.
Copy Client Certificates and Keys to Client Directory
Create OpenVPN clients directories. For example, we have generated certificates and key files for two clients, koromicha and janedoe, hence we create directories as;
mkdir /etc/openvpn/client/{koromicha,janedoe}
After that, copy the client generated certificates/keys and server CA certificate to OpenVPN client configuration directory. You can
cp -rp /etc/easy-rsa/pki/{ca.crt,issued/koromicha.crt,private/koromicha.key} /etc/openvpn/client/koromicha
cp -rp /etc/easy-rsa/pki/{ca.crt,issued/janedoe.crt,private/janedoe.key} /etc/openvpn/client/janedoe/
Configure OpenVPN Server on Debian 11/Debian 10
The next step is to configure OpenVPN server. Copy the sample OpenVPN server configuration to /etc/openvpn/server
directory as shown below;
On Debian 10;
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/server/
Extract the configuration.
cd /etc/openvpn/server/
gunzip server.conf.gz
On Debian 11;
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server/
Modify the configuration file, server.conf
, to suite your needs;
This is how our configurations looks like with no comments.
cp /etc/openvpn/server/server.conf{,.bak}
cat > /etc/openvpn/server/server.conf << 'EOL'
port 1194
proto udp
dev tun
ca ca.crt
cert issued/server.crt
key private/server.key # This file should be kept secret
dh dh.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 8.8.8.8"
client-to-client
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
auth SHA512
EOL
Save and exit the config once done editing.
Configure OpenVPN IP Forwarding
To ensure that traffic from the client is routed through the OpenVPN server’s IP address (helps masks the the client IP address), you need to enable IP forwarding on the OpenVPN server.
Uncomment the line, net.ipv4.ip_forward=1
, on /etc/sysctl.conf
to enable packet forwarding for IPv4
sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
Apply the changes without rebooting the server.
sysctl -p
Allow OpenVPN service port through firewall;
ufw allow 1194/udp
Configure IP Masquerading on UFW
Find your default interface through which your packets are sent.
ip route get 8.8.8.8
8.8.8.8 via 10.0.2.2 dev enp0s3 src 10.0.2.15 uid 0
Next, update UFW rules;
vim /etc/ufw/before.rules
Add the following highlighted lines just before the *filter
table settings. Note the interface used shoud match the interface name above.
...
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/8 -o enp0s3 -j MASQUERADE
COMMIT
# Don't delete these required lines, otherwise there will be errors
*filter
...
Save and exit the config.
Enable UFW packet forwarding;
sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
Reload UFW;
ufw reload
Running OpenVPN Server on Debian 11/Debian 10
Start and enable OpenVPN server to run on system boot;
systemctl enable --now openvpn-server@server
Checking the status;
systemctl status openvpn-server@server
● [email protected] - OpenVPN service for server
Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-10-26 15:06:18 EDT; 9s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Main PID: 1595 (openvpn)
Status: "Initialization Sequence Completed"
Tasks: 1 (limit: 2359)
Memory: 2.4M
CGroup: /system.slice/system-openvpn\x2dserver.slice/[email protected]
└─1595 /usr/sbin/openvpn --status /run/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf
Oct 26 15:06:18 debian systemd[1]: Starting OpenVPN service for server...
Oct 26 15:06:18 debian systemd[1]: Started OpenVPN service for server.
When OpenVPN service runs, it will create a tunnelling interface, tun0;
ip add s
...
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/none
inet 10.8.0.1/24 brd 10.8.0.255 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::bf6a:bdf4:58e1:ec24/64 scope link stable-privacy
valid_lft forever preferred_lft forever
Also, be sure to check the logs;
tail /var/log/openvpn/openvpn.log
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.8.0.1/24 broadcast 10.8.0.255
Could not determine IPv4/IPv6 protocol. Using AF_INET
Socket Buffers: R=[212992->212992] S=[212992->212992]
UDPv4 link local (bound): [AF_INET][undef]:1194
UDPv4 link remote: [AF_UNSPEC]
MULTI: multi_init called, r=256 v=256
IFCONFIG POOL: base=10.8.0.2 size=252, ipv6=0
IFCONFIG POOL LIST
Initialization Sequence Completed
The OpenVPN server is now ready to accept and route connections from clients.
That marks the end of our guide.
You can now configure your clients accordingly.
Related Tutorials
Install and Configure OpenVPN Client on CentOS 8/Ubuntu 18.04
Thank You for this info. Done very well. A few commands left out the directory /etc/openvpn///.. other than that 5 STARS.
what is that:
2022-01-19 16:50:23 Closing TUN/TAP interface
2022-01-19 16:50:23 net_addr_v4_del: 192.168.169.1 dev tun0
2022-01-19 16:50:23 sitnl_send: rtnl: generic error (-1): Operation not permitted
2022-01-19 16:50:23 Linux can’t del IP from iface tun0
2022-01-19 16:50:23 SIGTERM[hard,] received, process exiting
Run it with sudo
Thank you for the tutorial. I believe a “–” is missing in “openvpn –genkey secret /etc/easy-rsa/pki/ta.key” behind “secret”
This is a very thorough and good tutorial, it’s only missing one key thing and that is if you want to use your OpenVPN server as a way to access the internet from your client. The way this is written the client will connect, but internet will not be routed through the server.
To do that your will need to follow this example
https://community.openvpn.net/openvpn/wiki/HOWTO#Routingallclienttrafficincludingweb-trafficthroughtheVPN
You already have this in the conf
push “redirect-gateway def1 bypass-dhcp”
which is needed , but the missing command to run is this:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
That creates the tunnel.
Then add to the server.conf to your VPN server can also handle DNS queries
push “dhcp-option DNS 10.8.0.1”
Hope this helps.
Thank you for the feedback, Dee.
Hey!
Mi client doesn’t connect and the log keep with this message:
TLS Error: cannot locate HMAC in incoming packet from x.x.x.x
Could you post a client file example?
thanks.