Establishing a Virtual Private Network (VPN) offers a secure and private way to connect to a remote network over the internet, making it appear as though you're directly connected to a private network. This is particularly useful for accessing office networks remotely or protecting your data on public Wi-Fi networks. In this guide, we'll walk through setting up an OpenVPN server on Ubuntu 20.04, covering everything from installing the necessary packages to configuring both the server and client.
Installation
To begin, you'll need to install the OpenVPN package available in Ubuntu's official repositories. This package includes both the server and client components.
sudo apt install openvpn
OpenVPN uses SSL certificates to encrypt data between the server and clients. To manage these certificates, we'll set up our own Certificate Authority (CA). For security reasons, it's recommended to set up the CA on a separate machine from the OpenVPN server; this way, if the server is compromised, the CA's private key remains secure.
We'll use the 'Easy-RSA' tool to handle certificate generation and management. Install Easy-RSA on the CA machine, the OpenVPN server machine, and the client machine, as we'll need to perform configurations on all three.
sudo apt install easy-rsa
Now, let's configure the Certificate Authority on the CA machine and prepare the OpenVPN server accordingly.
Certificate Authority setup
Initial setup on CA machine
Step 1: Create a directory for the Certificate Authority using the make-cadir
command and navigate into it.
make-cadir cert_authority && cd cert_authority
Open the vars
file in this directory. Uncomment lines 91-96, which contain configuration variables for organizational fields, and replace the sample values with your own information.
Save and exit the file. If you're using vim, press Esc
, type :wq
, and press Enter
.
Step 2: Initialize the Public Key Infrastructure (PKI) by running:
./easyrsa init-pki
Step 3: Build the Certificate Authority. You'll be prompted to set a password for the CA key and enter a common name (you can leave it blank to use the default).
./easyrsa build-ca
The CA key and certificate are now generated. Keep the CA key secure, as it's used to sign server and client certificates.
Generating server key and certificate on the server machine
On the server machine, perform similar initial steps for Easy-RSA.
Step 1: Create the Easy-RSA directory and navigate into it:
make-cadir cert_authority && cd cert_authority
Edit the vars
file, updating the organizational fields as you did on the CA machine. Initialize the PKI:
./easyrsa init-pki
Step 2: Generate the server's private key and certificate request. The nopass
option allows OpenVPN to start without a password prompt.
./easyrsa gen-req server nopass
When prompted for a common name, you can leave it blank to use 'server' by default.
Step 3: Move the generated server key to the /etc/openvpn
directory.
sudo mv pki/private/server.key /etc/openvpn
Step 4: Transfer the server certificate request to the CA machine using scp
(secure copy).
scp pki/reqs/server.req user@CA_MACHINE_IP:/root
Replace user
and CA_MACHINE_IP
with your CA machine's username and IP address.
Signing the server certificate on the CA machine
On the CA machine, ensure the server's certificate request has been received.
Step 1: Import the server's certificate request into Easy-RSA.
cd cert_authority
./easyrsa import-req /root/server.req server
Step 2: Sign the server's certificate request. Type yes
when prompted and enter the CA key password.
./easyrsa sign-req server server
Step 3: Clean up by removing the server request file and transferring the signed certificate and CA certificate back to the server machine.
rm /root/server.req
scp pki/issued/server.crt root@SERVER_IP:/root
scp pki/ca.crt root@SERVER_IP:/root
Replace SERVER_IP
with your server's IP address.
Generating DH parameters
On the server machine, move the certificates to the OpenVPN directory.
Step 1: Move the certificates:
sudo mv /root/server.crt /root/ca.crt /etc/openvpn
Step 2: Generate the Diffie-Hellman (DH) parameters (this may take some time):
cd cert_authority
./easyrsa gen-dh
Step 3: Move the generated dh.pem
file to /etc/openvpn
.
sudo mv pki/dh.pem /etc/openvpn
Generating TLS authentication key
Step 4: Generate the TLS authentication key:
openvpn --genkey --secret tls_auth.key
Step 5: Move the key to the OpenVPN directory:
sudo mv tls_auth.key /etc/openvpn
With these steps, the server's key configuration and Certificate Authority setup are complete.
OpenVPN server configuration
Next, we'll configure the OpenVPN server using a sample configuration file provided by the OpenVPN package.
Step 1: Copy the sample server configuration file to /etc/openvpn
and decompress it:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Step 2: Edit the server configuration file:
sudo vim /etc/openvpn/server.conf
Update the paths to match your key and certificate files. Since we used the default names, lines 78 can remain unchanged. On line 85, change the dh
parameter file name to dh.pem
to match the file we generated.
Uncomment lines 192, 274, and 275 by removing the leading semicolons to adjust server privileges and enable client traffic routing.
Save and exit the file.
Step 3: Change the ownership of the OpenVPN directory to root
:
sudo chown -R root:root /etc/openvpn
Networking and firewall setup
Step 4: Enable IP forwarding by editing /etc/sysctl.conf
. Uncomment the line net.ipv4.ip_forward=1
by removing the leading #
.
Save and exit the file, then apply the changes:
sudo sysctl -p
Step 5: Adjust UFW settings by editing /etc/default/ufw
. Change DEFAULT_FORWARD_POLICY
from DROP
to ACCEPT
.
Save and exit the file.
Step 6: Add the following rules to /etc/ufw/before.rules
before the *filter
line to allow NAT:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/8 -o <interface> -j MASQUERADE
COMMIT
Replace <interface>
with your network interface name (use ifconfig
to find it).
Step 7: Allow OpenVPN through the firewall and open port 1194:
sudo ufw allow openvpn
sudo ufw allow 1194
Reload UFW to apply the changes:
sudo ufw reload
Step 8: Restart the OpenVPN service and enable it to start on boot:
sudo systemctl restart openvpn
sudo systemctl enable openvpn
The OpenVPN server is now configured and running.
OpenVPN client configuration
To allow a client to connect, we'll generate a key and certificate for the client on the server machine.
Step 1: On the server, navigate to the Easy-RSA directory and generate the client request (replace client1
with a unique identifier for your client):
cd cert_authority
./easyrsa gen-req client1 nopass
When prompted for a common name, you can use the default or enter a unique one.
Step 2: Transfer the client certificate request to the CA machine:
scp pki/reqs/client1.req root@CA_MACHINE_IP:/root
Step 3: On the CA machine, import and sign the client's certificate request:
cd cert_authority
./easyrsa import-req /root/client1.req client1
./easyrsa sign-req client client1
Type yes
when prompted and enter the CA key password.
Step 4: Transfer the signed client certificate back to the server:
scp pki/issued/client1.crt root@SERVER_IP:/root
rm /root/client1.req
Step 5: Create a directory on the server to store client files and move the client key and certificate there:
mkdir ~/client-configs
sudo mv ~/client1.crt ~/cert_authority/pki/private/client1.key ~/client-configs
Step 6: Copy the sample client configuration file to the client configurations directory:
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs
Step 7: Edit the client configuration file:
vim ~/client-configs/client.conf
Update the remote
directive on line 42 with your server's IP address or hostname.
Uncomment lines 61 and 62 to adjust privileges.
Comment out lines 88-90 and line 108 to embed certificates and keys directly in the configuration file.
At the end of the file, add these sections, inserting the actual contents of the corresponding files:
<ca>
# Paste the contents of ca.crt here
</ca>
<cert>
# Paste the contents of client1.crt here
</cert>
<key>
# Paste the contents of client1.key here
</key>
key-direction 1
<tls-auth>
# Paste the contents of tls_auth.key here
</tls-auth>
Save and exit the file, then rename it to have a .ovpn
extension:
mv client.conf client1.ovpn
Step 8: Transfer the client configuration file to the client machine:
scp ~/client-configs/client1.ovpn user@CLIENT_IP:/path/to/destination
Step 9: On the client machine, you can start the VPN connection from the command line:
sudo openvpn --config client1.ovpn
Alternatively, import the configuration file using your system's network manager.
Step 10: Go to Settings » Network on your client machine.
Click the '+' button under 'VPN' and choose 'Import from file...'. Select the client1.ovpn
file.
Click 'Add' to save the VPN connection.
Toggle the VPN connection to 'On' to initiate the connection.
Once connected, verify that your traffic is routing through the VPN:
curl https://ipinfo.io/ip
The returned IP should match your server's IP address.
By completing these steps, you've successfully set up an OpenVPN server on Ubuntu 20.04 and connected a client, ensuring secure access to your network over the internet.
Member discussion