OpenVPN is a powefrul Virtual Private Network system to create secure access to remote machines and remote networks. It uses state-of-the-art encryption algorithms to provide military grade security.
OpenVPN creates a specific network TUN/TAP device over which the network traffic is routed, then encrypted and sent to the peer. As a consequence of the need to create a device, OpenVPN can be installed on bare metal machines and virtual machines, but not on LXC containers (unless some privileges are granted to create devices on the host, but this is typically considered unsafe).
In Ubuntu, OpenVPN can be installed by running the following command:
root@otherhost:~# apt install openvpn
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
liblzo2-2 libpkcs11-helper1
Suggested packages:
resolvconf openvpn-systemd-resolved easy-rsa
The following NEW packages will be installed:
liblzo2-2 libpkcs11-helper1 openvpn
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 716 kB of archives.
After this operation, 1988 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
The configuration directory is located in /etc/openvpn and contains two more subdirectories, the one containing the configuration files for client connections, and the other containing the configuration file for the local server. Both of them are initially empty.
root@otherhost:~# cd /etc/openvpn
root@otherhost:/etc/openvpn# ls -la
total 17
drwxr-xr-x 4 root root 5 Jun 27 17:39 .
drwxr-xr-x 73 root root 158 Jun 27 17:39 ..
drwxr-xr-x 2 root root 2 Jul 14 2022 client
drwxr-xr-x 2 root root 2 Jul 14 2022 server
-rwxr-xr-x 1 root root 1468 Jul 14 2022 update-resolv-conf
root@otherhost:/etc/openvpn# ls -l client/ server/
client/:
total 0
server/:
total 0
root@otherhost:/etc/openvpn#
The OpenVPN system is enabled by default but, since no configuration file is provided, it just starts and exits at the system startup.
root@otherhost:~# systemctl status openvpn.service
● openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2023-06-27 17:39:14 CEST; 23min ago
Process: 1055 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1055 (code=exited, status=0/SUCCESS)
CPU: 915us
Jun 27 17:39:14 otherhost systemd[1]: Starting OpenVPN service...
Jun 27 17:39:14 otherhost systemd[1]: Finished OpenVPN service.
To show the server side configuration of OpenVPN, suppose we have a machine running Ubuntu Server 22.04.2 LTS acting as gateway on the local network 10.10.50.0/24 of mycompany.com and then named gw. The server has a WAN interface, ens18, with public IP address/class 100.100.100.100/24, whose gateway is 100.100.100.254, and another interface, ens19, with IP address/class 10.10.50.1/24 connected to the LAN.
The output of the command ip address show looks like this:
root@gw:~# ip address show
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: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 02:00:00:8d:dd:7b brd ff:ff:ff:ff:ff:ff
altname enp0s18
inet 100.100.100.100/24 brd 100.100.100.255 scope global ens18
valid_lft forever preferred_lft forever
inet6 fe80::ff:fe8d:dd7b/64 scope link
valid_lft forever preferred_lft forever
3: ens19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 32:d7:1f:79:7a:1a brd ff:ff:ff:ff:ff:ff
altname enp0s19
inet 10.10.50.1/24 brd 10.10.50.255 scope global ens19
valid_lft forever preferred_lft forever
inet6 fe80::30d7:1fff:fe79:7a1a/64 scope link
valid_lft forever preferred_lft forever
The network configuration file can be found in the /etc/netplan directory. It is generated by the installer at the installation time and has a .yaml extension, as shown in the following.
root@gw:~# cd /etc/netplan
root@gw:/etc/netplan# ls -l
total 4
-rw-r--r-- 1 root root 473 Jun 29 13:10 00-installer-config.yaml
root@gw:/etc/netplan#
Running cat 00-installer-config.yaml, its structure can be printed.
root@gw:/etc/netplan# cat 00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
version: 2
renderer: networkd
ethernets:
ens18:
addresses:
- 100.100.100.100/24
nameservers:
addresses:
- 8.8.8.8
search: []
routes:
- to: default
via: 100.100.100.254
ens19:
addresses:
- 10.10.50.1/24
nameservers:
addresses:
- 10.10.50.1
search: [mycompany.com]
Observe that modern implementations of netplan deprecated the use of the key gateway4: to define the default routing. Now, the default routing is defined within the block routes: through the statement to: default.
The output of the command ip route show is as follows:
root@gw:~# ip route show
default via 100.100.100.254 dev ens18 proto static
10.10.50.0/24 dev ens19 proto kernel scope link src 10.10.50.1
The current configuration uses the Source Network Address Translation (SNAT) to mask local IP addresses, thus providing a transparent internet connection to local computers. This result is obtained by setting a specific rule on the Linux firewall, as shown in the following (Linux firewall setting will be in-depth analyzed in section Linux firewall basics).
root@gw:~# iptables -t nat -A POSTROUTING -o ens18 -j SNAT --to 100.100.100.100
root@gw:~# iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 259 packets, 79948 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 259 packets, 79948 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 195 packets, 14062 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 73 packets, 5000 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all -- any ens18 anywhere anywhere to:100.100.100.100
Packet forwarding must also be enabled on gw to make it forwarding packets through interfaces. To do this for IPv4, uncomment the following line in /etc/sysctl.conf and restart the machine.
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1
What is requested now is to make gw acting as a VPN server so that remote machines on internet can connect in a secured manner to the local network of mycompany.com. Then, we need to create a server side installation of OpenVPN on gw.
First of all, must to install the OpenVPN package on gw by following the instructions reported in the section Installation.
Then we need some cryptographic stuff since, of course, OpenVPN uses cryptography to protect and secure the connection. We already have a CA certificate (see Generating a CA Root Certificate) and a key and certificate for gw (see Generating certificates based on elliptic curve P-256).
We can then copy them in the /etc/openvpn/server so as to obtain the following situation.
root@gw:~# cd /etc/openvpn/server
root@gw:/etc/openvpn/server# ls -l
total 12
-rw------- 1 root root 2171 Jun 29 17:26 cacert.pem
-rw------- 1 root root 1602 Jun 29 17:25 gwCert.pem
-rw------- 1 root root 241 Jun 29 17:24 gwKey.pem
For additional security, we have to generate new Diffie-Hellman paramters and an additional TLS key to be privately exchanged between server and clients to further protect the connection.
root@gw:/etc/openvpn/server# openssl dhparam -out dh2048.pem 2048
Generating DH parameters, 2048 bit long safe prime
.......+...................................................................+........................+.....
..........................................................................................................
...
...
...
....++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*
++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*++*
root@gw:/etc/openvpn/server# chmod 600 dh2048.pem
root@gw:/etc/openvpn/server# openvpn --genkey tls-auth ta.key
root@gw:/etc/openvpn/server# ls -l
total 20
-rw------- 1 root root 2171 Jun 29 17:26 cacert.pem
-rw------- 1 root root 424 Jun 29 17:00 dh2048.pem
-rw------- 1 root root 1602 Jun 29 17:25 gwCert.pem
-rw------- 1 root root 241 Jun 29 17:24 gwKey.pem
-rw------- 1 root root 636 Jun 29 17:07 ta.key
Now, what remains to do is creating the server configuration file. We then need to create a text file named server.conf and putting it into the directory /etc/openvpn/server. This task can be done by running the command nano /etc/openvpn/server/server.conf and copying in it the following content (note that IP addresses are related to this example and must be updated according to the specific case).
dev tun
verb 3
local 100.100.100.100
lport 1194
proto tcp4-server
ca cacert.pem
cert gwCert.pem
key gwKey.pem
dh dh2048.pem
auth SHA256
tls-auth ta.key 0
tls-server
remote-cert-tls client
data-ciphers AES-256-GCM:CAMELLIA-256-CBC
data-ciphers-fallback AES-256-GCM
allow-compression asym
topology subnet
server 10.10.80.0 255.255.255.0
client-to-client
duplicate-cn
push "route 10.10.50.0 255.255.255.0"
push "dhcp-option DOMAIN mycompany.com"
push "dhcp-option DNS 10.10.50.5"
push "dhcp-option WINS 10.10.50.6"
push "dhcp-option NBT 2"
push "block-outside-dns"
push "register-dns"
push "redirect-gateway def1"
keepalive 20 120
ping-timer-rem
persist-key
persist-tun
The dev tun option tells OpenVPN to create a routed tunnel. The verb option configures the verbosity level: increase it if you need more verbosity (6 enables debug mode). The local and lport options specify the local IP address to bind to (set it to the WAN address for server purposes) and the local listening port, respectively. The proto option can be used to restrict the protocol to be used: in our case, tcp4-server was used to limit the protocol to the TCP over IPv4.
Some cryptographic stuff must also be specified to let encryption take place. The options ca, cert, and key allows to specify the files containing the certificates and the key, located by default in /etc/openvpn/server. The option dh specifies the location of the file containing the Diffie-Hellman paramters, while auth determines the hashing algorithm used for authentication. The tls-auth option increases the security level by adding an additional layer of authentication thorugh the use of the secret key ta.key previoulsly created and that must also be confidentially given to clients; the following number, 0 (recommended for the server setup), specifies the authentication direction. The tls-server statement tells OpenVPN to assume server role during TLS handshake, while the remote-cert-tls client option forces OpenVPN to only accept peers presenting a client type certificate. Finally, the data-ciphers and data-ciphers-fallback options list the ciphers the encryption engine is allowd to use.
The allow-compression option determines the behaviour of the server in terms of data stream compression. It can take values asym, no, and yes. Administrators are generally advised to not enable compression in encrypted tunnels, this because the knowledge of the compression algorithm can permit some kind of attacks. So, the final choice should be no. Nevertheless, basically to allow a soft migration, the value asym can be adopted to tell the server to not compress outgoing packets, while allowing incoming compressed flow.
The next block of options instructs OpenVPN about the subnet that is proposed to clients. The options topology subnet and server 10.10.80.0 255.255.255.0 will put the clients on a subnet with address 10.10.80.0/24. The OpenVPN server will take the first address in the class, so the clients will see the server with IP address 10.10.80.1, that will also be their default gateway. The OpenVPN server will also act as DHCP server for the clients. Then, the options client-to-client allows the clients to see each other, while the option duplicate-cn allows multiple clients to connect with the same certificate. This latter option is useful if a single certificate is issued to a person needing to connect with multiple devices. The statement push "route 10.10.50.0 255.255.255.0" makes the client aware of the existence of the LAN network attached to the interface ens19 on the server forcing the client to set up a dedicated static route. The next rows starting with push "dhcp-option ..." set up some DNS specific parameters; in this case, it has been supposed that the DNS server and the WINS server are located in the LAN owning IP addresses 10.10.50.5 and 10.10.50.6, respectively. A public DNS server, such as 8.8.8.8, can also be used, but this reduces the privacy of the connection and prevents the name resolution of machines located within the LAN. Finally, the remaining options push "block-outside-dns", push "register-dns", and push "redirect-gateway def1" force the client to redirect all the outgoing traffic through the VPN, DNS traffic included.
The remaining rows set up some general behaviour of the OpenVPN server.
Further details about the configuration options can be found in the Reference manual for OpenVPN 2.6.
Once the configuration file is ready, our OpenVPN server instance must be added the system. Since we named the configuration file server.conf, the instance will take the name server. Then, the OpenVPN instance can be enabled by running the following command:
root@gw:~# systemctl -f enable openvpn-server@server.service
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-server@server.service → /lib/systemd/system/openvpn-server@.service.
root@gw:~# systemctl status openvpn-server@server.service
○ openvpn-server@server.service - OpenVPN service for server
Loaded: loaded (/lib/systemd/system/openvpn-server@.service; enabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
The OpenVPN server instance, being enabled, will automatically start at every system reboot. We can do now a manual start just to check if it works normally.
root@gw:~# systemctl start openvpn-server@server.service
root@gw:~# systemctl status openvpn-server@server.service
● openvpn-server@server.service - OpenVPN service for server
Loaded: loaded (/lib/systemd/system/openvpn-server@.service; enabled; vendor preset: enabled)
Active: active (running) Thu 2023-10-05 10:11:32 CEST; 4s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Main PID: 1360 (openvpn)
Status: "Initialization Sequence Completed"
Tasks: 1 (limit: 4549)
Memory: 3.0M
CPU: 14ms
CGroup: /system.slice/system-openvpn\x2dserver.slice/openvpn-server@server.service
└─1360 /usr/sbin/openvpn --status /run/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf
Oct 05 10:11:32 gw openvpn[1360]: net_iface_up: set tun0 up
Oct 05 10:11:32 gw openvpn[1360]: net_addr_v4_add: 10.10.80.1/24 dev tun0
Oct 05 10:11:32 gw openvpn[1360]: Socket Buffers: R=[131072->131072] S=[16384->16384]
Oct 05 10:11:32 gw openvpn[1360]: Listening for incoming TCP connection on [AF_INET]100.100.100.100:1194
Oct 05 10:11:32 gw openvpn[1360]: TCPv4_SERVER link local (bound): [AF_INET]100.100.100.100:1194
Oct 05 10:11:32 gw openvpn[1360]: TCPv4_SERVER link remote: [AF_UNSPEC]
Oct 05 10:11:32 gw openvpn[1360]: MULTI: multi_init called, r=256 v=256
Oct 05 10:11:32 gw openvpn[1360]: IFCONFIG POOL IPv4: base=10.10.80.2 size=253
Oct 05 10:11:32 gw openvpn[1360]: MULTI: TCP INIT maxclients=1024 maxevents=1028
Oct 05 10:11:32 gw openvpn[1360]: Initialization Sequence Completed
As can be seen by running the following command, OpenVPN created a new network device tun0 and updated the routing table to let the system manage packets related to its internal network 10.10.80.0/24.
root@gw:~# ip route show
default via 100.100.100.254 dev ens18 proto static onlink
10.10.50.0/24 dev ens19 proto kernel scope link src 10.10.50.1
10.10.80.0/24 dev tun0 proto kernel scope link src 10.10.80.1
The OpenVPN server is now operating and can accept incoming connections.
The OpenVPN client side configuration requires that configuration files are put into the directory /etc/openvpn/client. Here, we will generate a configuration file in which the cryptographic material is directly contained in it, this improving the portability.
The configuration file takes the extension .conf by deafults on Ubuntu Linux. In this section, we will configure the OpenVPN client on a host called myhost having IP address 200.200.200.200 to enable the connection to our server gw.mycompany.com with IP address 100.100.100.100 that we configured in the section OpenVPN server configuration.
First of all, we must install the OpenVPN package on gw by following the instructions reported in the section Installation.
Then, we need valid user certificates, that is, certificates signed by the same CA as the one used for the server side configuration. The generation of user certificates is explained in the section Creating a user certificate and, in this example, the certificate created for the user Henry Smith will be used. Specifically, the encrypted version of Henry's key is used to prevent any possibility of the key being stolen.
In the following, the required contents of the configuration file are shown, where keys and certificates are directly reported in a html-like tag style.
client
nobind
dev tun
verb 3
remote 100.100.100.100 1194
proto tcp4-client
allow-compression asym
auth SHA256
remote-cert-tls server
askpass
auth-nocache
data-ciphers AES-256-GCM:CAMELLIA-256-CBC
data-ciphers-fallback AES-256-GCM
<ca>
-----BEGIN CERTIFICATE-----
MIIGFjCCA/6gAwIBAgIUYNZ7F8MfEpUUHVCQqTutsemdLpkwDQYJKoZIhvcNAQEL
...
...
...
2jOy1El81v5tP3t+3CIw8cU/GnT2th92MtvlQi2wKoysPGdmJrsa4RJncHmy1VGf
xNcy47qtNHGNzUdUDYKQtKAStvJxH5lPp3M=
-----END CERTIFICATE-----
</ca>
key-direction 1
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
e8b808068a63110713c59a431aa750e5
...
...
...
9db1cba7281cd85c7ba66514fac0990a
-----END OpenVPN Static key V1-----
</tls-auth>
<cert>
-----BEGIN CERTIFICATE-----
MIIFSTCCAzGgAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMCVVMx
...
...
...
NuiLV4DAAQryBsBIywdap5oaifgm6N2tj9tOCO882RTObqe5mzeEOmKmQLV5kU56
Lm3BUui4cb2ZT5D5jA==
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQItCFWX/bMiiICAggA
...
...
...
CWg2z+4J6XogczG+JGWRhXalDqEXeCypKah6kcvgwRhuwm22G5BZOSCWSnMgyh9c
r+9kEalVtyd8o6SmsdvNfg==
-----END ENCRYPTED PRIVATE KEY-----
</key>
keepalive 120 240
persist-tun
resolv-retry infinite
At the top of the file, the options client and nobind define the basics for operating as a client, while the option remote is needed to specify the address and the port of the server. The option proto tcp4-client tells OpenVPN to use only IPv4 on this connection and not to listen for incoming connections (it is the server side that listen for incoming connections, not the client side).
Notice the use of the html-like tags to embed keys and certificates directly in the configuration file; specifically, the <tls-auth>...</tls-auth> block must report the same contents of the file ta.key of the server and the option key-direction 1 must also be specified. Since the key is encrypted, the option askpass is added so OpenVPN will prompt for the decrypting secret every time the connection is started and will forget it immediately as a consequence of the option auth-nocache. The option remote-cert-tls server requires that the certificate of the peer, i.e. the server in this case, presents a certificate with explicit server key usage, otherwise the connection will not be allowed.
Now, put the above reported configuration in a text file that can be called, according to our example, gw-mycompany-com.conf and save it in the directory /etc/openvpn/client on myhost. The directory should look like this:
root@myhost:/etc/openvpn/client# ls -l
total 8
-rw-r--r-- 1 root root 6919 Oct 31 14:08 gw-mycompany-com.conf
To start the OpenVPN client connection run the following command. Notice that the service takes the name of the configuration file. In this way, more OpenVPN client configurations can be installed and run individually simply by targeting their name.
root@myhost:~# systemctl start openvpn-client@gw-mycompany-com.service
Enter private key password: TYPE_PASSWORD_HERE
root@myhost:~# systemctl status openvpn-client@gw-mycompany-com.service
● openvpn-client@gw-mycompany-com.service - OpenVPN tunnel for gw/mycompany/com
Loaded: loaded (/lib/systemd/system/openvpn-client@.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2023-10-31 15:29:36 CET; 46s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Main PID: 4318 (openvpn)
Status: "Initialization Sequence Completed"
Tasks: 1 (limit: 4599)
Memory: 2.0M
CPU: 28ms
CGroup: /system.slice/system-openvpn\x2dclient.slice/openvpn-client@gw-mycompany-com.service
└─4318 /usr/sbin/openvpn --suppress-timestamps --nobind --config gw-mycompany-com.conf
ott 31 15:29:36 myhost openvpn[4318]: ROUTE_GATEWAY 200.200.200.254/255.255.255.0 IFACE=ens18 HWADDR=02:00:00:8d:dd:7b
ott 31 15:29:36 myhost openvpn[4318]: TUN/TAP device tun0 opened
ott 31 15:29:36 myhost openvpn[4318]: net_iface_mtu_set: mtu 1500 for tun0
ott 31 15:29:36 myhost openvpn[4318]: net_iface_up: set tun0 up
ott 31 15:29:36 myhost openvpn[4318]: net_addr_v4_add: 10.10.80.2/24 dev tun0
ott 31 15:29:36 myhost openvpn[4318]: net_route_v4_add: 100.100.100.100/32 via 200.200.200.254 dev [NULL] table 0 metric -1
ott 31 15:29:36 myhost openvpn[4318]: net_route_v4_add: 0.0.0.0/1 via 10.10.80.1 dev [NULL] table 0 metric -1
ott 31 15:29:36 myhost openvpn[4318]: net_route_v4_add: 128.0.0.0/1 via 10.10.80.1 dev [NULL] table 0 metric -1
ott 31 15:29:36 myhost openvpn[4318]: net_route_v4_add: 10.10.50.0/24 via 10.10.80.1 dev [NULL] table 0 metric -1
ott 31 15:29:36 myhost openvpn[4318]: Initialization Sequence Completed
To make the connection starting automatically at every reboot, the unencrypted version of the key must be put in the configuration file in place of the encrypted one and the option askpass must also be removed (do also a chmod 600 gw-mycompany-com.conf to restrict file access). Then, the OpenVPN client service needs to be enabled with the following command:
root@myhost:~# systemctl -f enable openvpn-client@gw-mycompany-com.service
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-client@gw-mycompany-com.service → /lib/systemd/system/openvpn-client@.service.
VPN providers are companies providing worldwide VPN access to their customers. This is really useful for persons who travel the world frequently, especially in countries where privacy regulations are weak, but also in general, to keep the internet activity secreted against third party untrusted subjects. There are a lot of good VPN providers, such as NordVPN, ExpressVPN, and so on.
Even if any VPN providers can provide its customers with tailored applications for simplifying VPN connections, practically all of them uses OpenVPN as server side VPN engine. Hence, it is of interest to understand how to connect to a VPN provider just using the OpenVPN client. In this example, we will refer to NordVPN to show the configuration steps, but the procedure remains more or less the same also for other providers.
The procedure here described refers to the configuration on Linux machines, but it can also be carried out on MS Windows machines simply by using the configuration file here generated and following the procedure described in the section OpenVPN client on MS Windows.
Let us suppose that our host is named myhost and has IP address 200.200.200.200. We have then to install the OpenVPN package on myhost by following the instructions reported in the section Installation.
The next thing to do is to buy a subscription to receive a VPN account, that is, a username and a password. Then, it is convenient to store them in a file in the /etc/openvpn/client directory. The file must be a text file containing the username in the first line and the password in the second one. The file can be created by means of the following commands.
root@myhost:~# cd /etc/openvpn/client
root@myhost:/etc/openvpn/client# cat > vpnaccount.info << EOF
> TYPE_USERNAME_HERE
> TYPE_PASSWORD_HERE
> EOF
root@myhost:/etc/openvpn/client# chmod 600 vpnaccount.info
root@myhost:/etc/openvpn/client# ls -l
total 4
-rw------- 1 root root 50 Oct 28 17:37 vpnaccount.info
Then, we need to obtain the configuration file, that is typically downloadable from the website of the VPN provider. As an example, for NordVPN, the username and the passowrd can be found here, while the configuration file can be obtained at the link https://nordvpn.com/servers/tools/ that opens the page reported in the following picture.
Just above the button Reset, a link named Show advanced options can be clicked to show additional choices, specifically related to the VPN server type and the protocol, as shown here.
Now, the options allow us to
After having selected the proper options, the left side of the page will show the suggested server. Just below the server name, the link Show available protocols can be clicked to show the link for downloading the configuration file, as reported in the following picture.
By clicking on the link Download config, the configuration file for the OpenVPN client can be downloaded. The contents of the file are shown in the following; the rows highlighted in red color need be added to tell the system that the account details are stored in our file vpnaccount.info. It can also be noticed the use of the tags <ca> and <tls-auth> to embed certificates and keys data directly in the configuration file, as an alternative to import them from external files.
client
dev tun
proto tcp
remote 156.146.36.39 443
resolv-retry infinite
remote-random
nobind
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
persist-key
persist-tun
ping 15
ping-restart 0
ping-timer-rem
reneg-sec 0
comp-lzo no
verify-x509-name CN=us6482.nordvpn.com
remote-cert-tls server
auth-user-pass vpnaccount.info
auth-nocache
verb 3
pull
fast-io
cipher AES-256-CBC
auth SHA512
<ca>
-----BEGIN CERTIFICATE-----
MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ
MA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2
...
...
...
VPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S
PApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA==
-----END CERTIFICATE-----
</ca>
key-direction 1
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
e685bdaf659a25a200e2b9e39e51ff03
0fc72cf1ce07232bd8b2be5e6c670143
...
...
...
9427e7b372d348d352dc4c85e18cd4b9
3f8a56ddb2e64eb67adfc9b337157ff4
-----END OpenVPN Static key V1-----
</tls-auth>
Take the downloaded file, add the red lines as reported in the picture, and save it in the directory /etc/openvpn/client with the name, e.g., NordVPN_US.conf (remember to use the extension .conf that is the default in Ubuntu Linux).
The directory should now appear like this:
root@myhost:/etc/openvpn/client# ls -l
total 8
-rw-rw-r-- 1 root root 2876 Oct 28 17:35 NordVPN_US.conf
-rw------- 1 root root 50 Oct 28 17:37 vpnaccount.info
To install our OpenVPN client service, run the following command. Notice that the service takes the name of the configuration file. In this way, more OpenVPN client configurations can be installed and run individually simply by targeting their name.
root@myhost:~# systemctl -f enable openvpn-client@NordVPN_US.service
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-client@NordVPN_US.service → /lib/systemd/system/openvpn-client@.service.
Now the OpenVPN connection can be manually started:
root@myhost:~# systemctl start openvpn-client@NordVPN_US.service
root@myhost:~# systemctl status openvpn-client@NordVPN_US.service
● openvpn-client@NordVPN_US.service - OpenVPN tunnel for NordVPN_US
Loaded: loaded (/lib/systemd/system/openvpn-client@.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-10-29 19:30:03 CET; 5s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Main PID: 5011 (openvpn)
Status: "Initialization Sequence Completed"
Tasks: 1 (limit: 4550)
Memory: 2.0M
CPU: 16ms
CGroup: /system.slice/system-openvpn\x2dclient.slice/openvpn-client@NordVPN_US.service
└─5011 /usr/sbin/openvpn --suppress-timestamps --nobind --config NordVPN_US.conf
Oct 29 19:30:05 myhost openvpn[5011]: net_route_v4_best_gw result: via 200.200.200.254 dev ens18
Oct 29 19:30:05 myhost openvpn[5011]: ROUTE_GATEWAY 200.200.200.254/255.255.255.0 IFACE=ens18 HWADDR=02:00:00:8d:dd:7b
Oct 29 19:30:05 myhost openvpn[5011]: TUN/TAP device tun0 opened
Oct 29 19:30:05 myhost openvpn[5011]: net_iface_mtu_set: mtu 1500 for tun0
Oct 29 19:30:05 myhost openvpn[5011]: net_iface_up: set tun0 up
Oct 29 19:30:05 myhost openvpn[5011]: net_addr_v4_add: 10.7.1.6/24 dev tun0
Oct 29 19:30:05 myhost openvpn[5011]: net_route_v4_add: 156.146.36.39/32 via 200.200.200.254 dev [NULL] table 0 metric -1
Oct 29 19:30:05 myhost openvpn[5011]: net_route_v4_add: 0.0.0.0/1 via 10.7.1.1 dev [NULL] table 0 metric -1
Oct 29 19:30:05 myhost openvpn[5011]: net_route_v4_add: 128.0.0.0/1 via 10.7.1.1 dev [NULL] table 0 metric -1
Oct 29 19:30:05 myhost openvpn[5011]: Initialization Sequence Completed
Since we enabled the OpenVPN client service NordVPN_US, it will be started automatically every time the system reboots. If this behaviour is not the wanted one, it can be disabled by running systemctl disable openvpn-client@NordVPN_US.service and then manually started and stopped as needed.
Suppose we own a remote machine connected to the internet, whose public interface (i.e, the WAN) has IP address 100.100.100.100 and name myhost. For safety reasons, we have decided to install OpenVPN client on that machine so that all the outgoing traffic is routed through a VPN provider (i.e., the VPN is the default routing), just as we discussed in the paragraph Connect to VPN providers.
Since tha machine is remote, i.e. we do not have physical access to it, we need to open an SSH server, listening on port 22, to guarantee access for remote management (see also the section OpenSSH configuration).
It is clear that, as a consequence of the fact that the default routing for outgoing packets is over the VPN, incoming connections to the SSH server will not work. The reason resides in the fact that the peer will initiate the connection towards the IP address 100.100.100.100, but it will see returining packets coming from the IP address of the VPN provider, producing an inconsistencty in the connection.
To solve this problem, we have to create a specific routing policy on the remote machine so that outgoing packets sourcing from port 22 (i.e., the SSH server port) are routed through the interface 100.100.100.100 and not through the VPN tunnel.
To achieve this goal, the first thing to do is creating a custom routing table. This can be done by acting on the file rt_tables located in the directory /etc/iproute2, as reported in the following:
root@myhost:~# cd /etc/iproute2
root@myhost:/etc/iproute2# ls -l
total 44
-rw-r--r-- 1 root root 85 Nov 2 2021 bpf_pinning
-rw-r--r-- 1 root root 81 Nov 2 2021 ematch_map
-rw-r--r-- 1 root root 31 Nov 2 2021 group
-rw-r--r-- 1 root root 262 Nov 2 2021 nl_protos
-rw-r--r-- 1 root root 331 Nov 2 2021 rt_dsfield
-rw-r--r-- 1 root root 219 Nov 2 2021 rt_protos
drwxr-xr-x 2 root root 4096 Feb 17 2023 rt_protos.d
-rw-r--r-- 1 root root 112 Nov 2 2021 rt_realms
-rw-r--r-- 1 root root 92 Nov 2 2021 rt_scopes
-rw-r--r-- 1 root root 87 Nov 2 2021 rt_tables
drwxr-xr-x 2 root root 4096 Feb 17 2023 rt_tables.d
Opening the file with the command nano rt_tables, an additional routing table can be added at its end. We identify this new routing table with the number 201 and call this novpn. The following block reports the contents of the file rt_tables with the modification highlighted in red color.
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
201 novpn
Do a system reboot to activate the new routing table.
Now that we have a new routing table, we can add a specific rotuing policy by acting on the configuration file of netplan that can be found in the directory /etc/netplan and has a .yaml extension. In our installation it is named 00-installer-config.yaml. In the following, the content of the file is reported together with the new lines that must be added, highlighted in red.
# This is the network config written by 'subiquity'
network:
version: 2
renderer: networkd
ethernets:
ens18:
addresses:
- 100.100.100.100/24
nameservers:
addresses:
- 8.8.8.8
search: [mycompany.com]
routes:
- to: default
via: 100.100.100.100
- to: 0.0.0.0/0
table: 201
via: 100.100.100.100
routing-policy:
- to: 0.0.0.0/0
table: 201
mark: 65
As can be seen, a new route was added telling the kernel to check if outgoing packets directed to any IPv4 address match with table 201 and, in this case, to route those through the 100.100.100.100 interface. Then, a routing policy was added to determine whether or not a packet is associated with table 201; this is done, in our example, by checking if the packet is marked with the decimal number 65 (that corresponds to the hexadecimal number 41).
At this point, run netplan try to check if the new configuration file works, then confirm it.
Finally, the last thing to do is marking the packets exiting the system and sourcing from the SSH server port, that is, port number 22. This task is carried out by the linux firewall throught the mangle table (further insights about linux firewall configuration are given in the section Linux firewall basics, that also explains how to make firewall rules persistent after system reboot).
We can then add a specific rule by running the following command:
root@myhost:~# iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 22 -j MARK --set-xmark 0x41/0xffffffff
root@myhost:~# iptables -t mangle -L -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MARK tcp -- any any anywhere anywhere tcp spt:ssh MARK set 0x41
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Now, every packet exiting the system, then walking through the OUTPUT chian, with protocol TCP and source port 22 will be marked with the hexadecimal number 41, that corresponds to the decimal value 65.
At this point everything should work, correctly routing outgoing packets sourcing from port 22 through the interface 100.100.100.100.
VPN passthrough for other services listening on static ports can be easily configured by simply adding the related rule in the mangle table, just like done for SSH.
In this section, the minimum set of firewall rules to secure OpenVPN connections will be reported, while an in-depth explaination of Linux firewall settings will be discussed in the chapter Linux firewall basics. As an example, we will consider to operate on the host myhost having public network interface ens18 with IP address 100.100.100.100/24.
First of all, let us define a minimum set of rules in the INPUT chain for having the system operating correctly, also making it possible remote management through SSH.
root@myhost:~# iptables -A INPUT -i lo -j ACCEPT
root@myhost:~# iptables -A INPUT -i ens18 -p icmp -j ACCEPT
root@myhost:~# iptables -A INPUT -i ens18 -m state --state RELATED,ESTABLISHED -j ACCEPT
root@myhost:~# iptables -A INPUT -i ens18 -p tcp -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
The first command allows every packet to enter the localhost interface, the second one lets icmp packects to enter the public network interface, the third one allows any packet related to established connections to enter the public interface, and the last allows to start the TCP handshaking on port 22 (the SSH port) only if the regular handshaking sequence is respected.
At this point, the situation of the rules in the filter table should be the one here reported:
root@myhost:~# iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT icmp -- ens18 any anywhere anywhere
0 0 ACCEPT all -- ens18 any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- ens18 any anywhere anywhere tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
As can be noticed, by default the linux firewall is set to ACCEPT every packet entering any chains. Now that we have guaranteed the possibility of remote administration through port 22, it is time to revert this behaviour for the chain INPUT.
root@myhost:~# iptables -P INPUT DROP
root@myhost:~# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT icmp -- ens18 any anywhere anywhere
0 0 ACCEPT all -- ens18 any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- ens18 any anywhere anywhere tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Practically, we have changed the policy of the chain INPUT so as to incoming packets are dropped by default, hence only packets matching some rules with an ACCEPT target will be allowed to enter the system.
Now, specific rules for OpenVPN can be added. Since we configured OpenVPN to instantiate a tun network interface, packets directed to any of tun0, tun1, ... interfaces must be allowed to enter the system. To do this, the wildcard + can be used by simply appending it to the interface name. Moreover, in the case an OpenVPN server service needs to be installed, incoming connections to its listening port must be allowed too. With respect to our configuration reported in the section OpenVPN server configuration, this is done by opening the TCP port 1194.
root@myhost:~# iptables -I INPUT 2 -i tun+ -j ACCEPT
root@myhost:~# iptables -A INPUT -p tcp -m tcp --dport 1194 --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
root@myhost:~# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT all -- tun+ any anywhere anywhere
0 0 ACCEPT icmp -- ens18 any anywhere anywhere
0 0 ACCEPT all -- ens18 any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- ens18 any anywhere anywhere tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:openvpn flags:FIN,SYN,RST,ACK/SYN
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Just to make the sequence of the rules more clear, we decided to insert the interface wide rule about tun+ in position 2 in the INPUT chain.
What was done is sufficient to have the machine secured while allowing OpenVPN working on both server and client sides.
An additional request might be to block every outgoing packet from any interface except that of the VPN, while still allowing remote management of the machine. To achieve this goal, we have to operate on the OUTPUT chain, as shown in the following.
root@myhost:~# iptables -A OUTPUT -o lo -j ACCEPT
root@myhost:~# iptables -A OUTPUT -o tun+ -j ACCEPT
root@myhost:~# iptables -A OUTPUT -o ens18 -p icmp -j ACCEPT
root@myhost:~# iptables -A OUTPUT -o ens18 -m state --state RELATED,ESTABLISHED -j ACCEPT
root@myhost:~# iptables -A OUTPUT -o ens18 -p tcp -m tcp --dport 1194 -j ACCEPT
root@myhost:~# iptables -A OUTPUT -o ens18 -d 156.146.36.39/32 -p tcp -m tcp --dport 443 -j ACCEPT
root@myhost:~# iptables -P OUTPUT DROP
root@myhost:~# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT all -- tun+ any anywhere anywhere
0 0 ACCEPT icmp -- ens18 any anywhere anywhere
0 0 ACCEPT all -- ens18 any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- ens18 any anywhere anywhere tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:openvpn flags:FIN,SYN,RST,ACK/SYN
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any lo anywhere anywhere
0 0 ACCEPT all -- any tun+ anywhere anywhere
0 0 ACCEPT icmp -- any ens18 anywhere anywhere
0 0 ACCEPT all -- any ens18 anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- any ens18 anywhere anywhere tcp dpt:openvpn
0 0 ACCEPT tcp -- any ens18 anywhere 156.146.36.39 tcp dpt:https
As can be noticed, the first four rules in the OUTPUT chain have the same meaning of the first four ones in the INPUT chain. The fifth one is needed to make it possible the initiation of outgoing connections towards OpenVPN servers that are listening on the standard port 1194. The last rule is instead needed to allow connections to the NordVPN server that is the object of the section Connect to VPN providers; as can be observed, it does not use the standard OpenVPN port but it uses the HTTPS port 443 just because this latter is more likely to be left open on firewalls.
Do not forget to follow the steps reported in the section Incoming connections passthrough to allow remote management over SSH when the VPN client connection is active on the machine.
Please look at the chapter Linux firewall basics to learn how to make firewall rules persisting after system reboots.
Installing OpenVPN client on MS Windows is rather simple. The OpenVPN Community Download page makes the various version of the OpenVPN package available for download. It opens on the last version; by scrolling the page a little bit down, the links for downloading the installer appear.
Since we have a 64-bit Windows version, we will download the Windows 64-bit MSI installer by clicking on the specific button, that currently refers to the version 2.6.6. Once the download is completed, the installation process can be started by clicking on the downloaded file, that in our case is OpenVPN-2.6.6-I001-amd64.msi.
The installation process is fully automated. At the end, a message appears indicating that no configuration file was found. This is typical if it is the first time OpenVPN is installed in the system; we will see in the sequel how to set up a configuration file. At this time, it could be a good idea to restart your Windows machine, so as to be sure that the new network drivers are correctly installed and loaded. OpenVPN automatically starts at Windows startup, and you will see it as an icon in the tray bar.
OpenVPN on MS Windows adopts a per-user based configuration schema, so each user in the system has its own directory for storing the configuration files for the different connections. As an example, since we logged in as user henry, the directory is C:\Users\henry\OpenVPN\config. By default on Windows systems, the connection configuration files take extension .ovpn.
A configuration file for setting up a connection on OpenVPN is then simply a text file with extension .ovpn. So, to create a connection to our server gw.mycompany.com with IP address 100.100.100.100, i.e. the one we configured in the section OpenVPN server configuration, we can simply run the notepad application to create a text file with the following content.
client
nobind
dev tun
verb 3
remote 100.100.100.100 1194
proto tcp4-client
ca "C:\\Users\\henry\\OpenVPN\\config\\cacert.pem"
cert "C:\\Users\\henry\\OpenVPN\\config\\HenryCert.pem"
key "C:\\Users\\henry\\OpenVPN\\config\\HenryKey.encrypted.pem"
auth SHA256
tls-auth "C:\\Users\\henry\\OpenVPN\\config\\ta.key" 1
remote-cert-tls server
auth-nocache
data-ciphers AES-256-GCM:CAMELLIA-256-CBC
data-ciphers-fallback AES-256-GCM
allow-compression asym
keepalive 120 240
persist-tun
resolv-retry infinite
At the top of the file, the options client and nobind define the basics for operating as a client, while the option remote is needed to specify the address and the port of the server. Moreover, some encryption material is needed for the client and, in this example, it is saved in the OpenVPN configuration directory. Specifically, the CA certificate cacert.pem must be the same as the one used for the server configuration, since it is the one against which the system checks certificates validity. Also the file ta.key must be exactly the same used in the server. Finally, to identify our client, the key-pair created for the user Henry Smith (see Creating a user certificate) is used. Note that the encrypted version of the key is used to prevent any possibility of the key being stolen; the system will then prompt for the decryption password every time the connection is started, and will forget it immediately since we added the option auth-nocache.
The configuration file can now be saved on the Desktop with the name gw-mycompany-com.ovpn, as an example, and it will look like this:
By double clicking on the file on the Desktop, OpenVPN will ask the consent to import the file. After confirmation, the file will be copied in a subdirectory called gw-mycompany-com (i.e., the same name of the file) in the configuration directory. The resulting content of the configuration directory is reported in the following picture.
At this point, everyhting is ready and we can try our new connection. Right click on the OpenVPN icon in the tray bar and a menu opens, then click on Connect. OpenVPN will prompt for the password to decrypt the private key, and the connection will be up in few seconds. The tray icon will become green.
To check if the VPN is working well, try connecting to a website like whatismyipaddress.com; you should see the IP address of the server (100.100.100.100 in our example) instead of that of the client.
The procedure seen in this section can also be used to configure OpenVPN client connections to VPN providers on MS Windows. To do so, the configuration file described in the section Connect to VPN providers must be used in place of the one here reported.
As seen in section OpenVPN server configuration, the OpenVPN server configuration file typically contains push directives to force some required configurations on the client. On the other side, the client configuration file, containing the option client, defaults to accept (or pull) every option that is pushed by the server.
It can happen that, for some reasons, a client would not want to accept some options pushed by server. Since the client cannot change the configuration of the server, a specific option called pull-filter is designed to determine whether a push option should be accepted or ignored.
The pull-filter option is specified in the client configuration file, and can appear as many times as needed to define the complete filtering scheme. It takes two parameters: the first is the action, that can be accept, ignore or reject, while the second is a text to be matched to activate the action.
A first use case is when the client does not want all the traffic to be routed through the VPN. So, the client wants to use the VPN just to access some remote private network (i.e., the network 10.10.50.0/24 in our OpenVPN server configuration example). To do this, we must tell the client to ignore the pushed option redirect-gateway def1, as well as to permit DNS queries towards servers located outside the VPN. Therefore, the following lines must be added into the client configuration file.
pull-filter ignore "redirect-gateway"
pull-filter ignore "block-outside-dns"
Another use case is when the client does not want to install the remote LANs. To do this, the following line to be added into the client configuration file blocks all the pushed routes.
pull-filter ignore "route "
Pay attention to the trailing space at the end of the word route. It is essential otherwise the route-gateway options will also be blocked preventing the possibility to create the default gateway.
DISCLAIMER
The material and methods reported in Linux Admin Smart Guide, even if tested, are provided without any guarantee. All the commands are run as privileged (root) user, so it is highly recommended to try them first on non-production machines and, in any case, to always do backups first. Linux Admin Smart Guide is not responsible for any damage or data loss caused by misformulated commands or inadvertently launched commands.
To gain a root shell, run the command sudo su -l from the shell of a regular user who is included in the sudoers list, or simply the command su -l and then providing the root password.