Installing OpenVPN on Ubuntu 24.04
DEV Community

Installing OpenVPN on Ubuntu 24.04

Installing OpenVPN on Ubuntu 24.04

OpenVPN is an open-source, full-featured VPN solution that enables secure site-to-site and point-to-point connections. OpenVPN creates encrypted tunnels using TLS (Transport Layer Security) to secure data transmission over untrusted networks such as the Internet between clients and servers. It supports multiple encryption algorithms, including AES-256, to encrypt traffic and protect network communication from man-in-the-middle and eavesdropping attacks. This guide walks through installing OpenVPN on Ubuntu 24.04 and configuring it to create secure end-to-end encrypted connections between the VPN server and client devices. By the end, you'll have a working OpenVPN server with a signed client certificate ready to import into any OpenVPN client. Before you begin, you need access to an Ubuntu 24.04 server as a non-root user with sudo privileges.

1. Install OpenVPN

OpenVPN is available in the default package repositories on Ubuntu 24.04.

  1. Update the APT package index:

    $ sudo apt update
    
  2. Install OpenVPN:

    $ sudo apt install openvpn -y
    
  3. Verify the installed OpenVPN version:

    $ openvpn --version
    

    Your output should be similar to the one below.

    OpenVPN 2.6.12 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO] library versions: OpenSSL 3.0.13 30 Jan 2024, LZO 2.10 DCO version: N/A Originally developed by James Yonan .................................................................
    

2. Create the OpenVPN Server Private Key, Certificate, and TLS Encryption Files

OpenVPN requires a server certificate, private key, and encryption files signed by a trusted certificate authority (CA) to enable VPN tunnel connections. Easy-RSA is a certificate authority management tool for applications like OpenVPN that issue digital certificates, including server certificates and private key pairs.

  1. Install Easy-RSA:

    $ sudo apt install easy-rsa -y
    
  2. Navigate to your user's home directory:

    $ cd
    
  3. Create a new easy-rsa directory:

    $ mkdir easy-rsa
    
  4. Link the /usr/share/easy-rsa directory to easy-rsa to access the Easy-RSA script and package files:

    $ ln -s /usr/share/easy-rsa/ * easy-rsa/
    
  5. List the easy-rsa directory and verify the linked files:

    $ ls easy-rsa
    

    Output:

    easyrsa openssl-easyrsa.cnf vars.example x509-types
    
  6. Change to the easy-rsa directory:

    $ cd easy-rsa
    
  7. Create a new vars configuration using a text editor such as nano:

    $ nano vars
    
  8. Add the following certificate authority configuration to the file:

    set_var EASYRSA_REQ_COUNTRY "US"
    set_var EASYRSA_REQ_PROVINCE "Georgia"
    set_var EASYRSA_REQ_CITY "Atlanta"
    set_var EASYRSA_REQ_ORG "Example Org"
    set_var EASYRSA_REQ_EMAIL "li*******@example.com"
    set_var EASYRSA_REQ_OU "Community"
    set_var EASYRSA_ALGO "ec"
    set_var EASYRSA_DIGEST "sha512"
    

    This configuration specifies the organizational information for building your CA, including the country, city, administrative email, and unit details.

  9. Initialize the PKI using the easy-rsa script:

    $ ./easyrsa init-pki
    

    Output:

    Notice ------ 'init-pki' complete; you may now create a CA or requests. Your newly created PKI dir is: * /home/linuxuser/easy-rsa/pki Using Easy-RSA configuration: * /home/linuxuser/easy-rsa/vars
    
  10. Build the CA to generate the root public certificate and private key pair:

    $ ./easyrsa build-ca
    

    Enter a strong passphrase for signing certificate requests and repeat it when prompted to secure the CA, then enter a common name for the CA, such as OpenVPN-CA. Verify the generated ca.crt CA certificate path in the output:

    Notice ------ CA creation complete. Your new CA certificate is at: * /home/linuxuser/easy-rsa/pki/ca.crt
    
  11. Generate a new server certificate request. Replace vpnserver with your desired server common name.

    $ ./easyrsa gen-req vpnserver nopass
    

    Press Enter when prompted to verify the common name, then verify the generated public certificate request and private key paths when successful:

    Notice ------ Private-Key and Public-Certificate-Request files created. Your files are: * req: /home/linuxuser/easy-rsa/pki/reqs/vpnserver.req * key: /home/linuxuser/easy-rsa/pki/private/vpnserver.key
    
  12. Sign the server certificate request using the CA:

    $ ./easyrsa sign-req server vpnserver
    

    Enter yes and press Enter when prompted to verify the certificate request, then enter your CA passphrase when prompted to sign it. Your output should look like the one below when successful.

    Notice ------ Certificate created at: * /home/linuxuser/easy-rsa/pki/issued/vpnserver.crt
    
  13. List the pki/issued directory to verify the generated server certificate:

    $ ls pki/issued
    

    Output:

    vpnserver.crt
    
  14. Generate a ta.key HMAC signature file to enable TLS verification and authentication on the OpenVPN server:

    $ sudo openvpn --genkey secret ta.key
    
  15. List your working directory files to verify the generated ta.key file:

    $ ls
    

    Output:

    df.pem easyrsa openssl-easyrsa.cnf pki ta.key vars vars.example x509-types
    
  16. Create a strong Diffie-Hellman parameters file to secure key exchange for encrypted OpenVPN sessions:

    $ ./easyrsa gen-dh
    

    Output:

    Generating DH parameters, 2048 bit long safe prime ..................... DH parameters appear to be ok. Notice ------ DH parameters of size 2048 created at: * /home/linuxuser/easy-rsa/pki/dh.pem
    
  17. List the pki directory to verify the generated dh.pem file:

    $ ls pki/
    

    Output:

    ca.crt dh.pem .....................
    
  18. Copy the ca.crt, vpnserver.key, vpnserver.crt, ta.key, and dh.pem files to the /etc/openvpn directory:

    $ sudo cp ta.key pki/ca.crt pki/private/vpnserver.key pki/issued/vpnserver.crt pki/dh.pem /etc/openvpn/
    

3. Configure OpenVPN

OpenVPN uses server and client configurations in the /etc/openvpn directory to create tunnel interfaces and the respective systemd services. /etc/openvpn contains the server configurations you can manage with the openvpn@ service, while /etc/openvpn/server contains additional configurations manageable with the openvpn-server@ service.

  1. Copy the sample OpenVPN server configuration template to the /etc/openvpn directory:

    $ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/
    
  2. Navigate to the /etc/openvpn directory:

    $ cd /etc/openvpn
    
  3. Open the copied server.conf file:

    $ sudo nano server.conf
    

    Make the following edits:

    • Optional: Remove ; to uncomment the local directive and replace a.b.c.d with the server IP address OpenVPN should use to listen for incoming connections. Replace 192.0.2.100 with your server's actual public IP address.

      local 192.0.2.100
      
    • Find the dev directive and verify the default OpenVPN tunnel type (tun creates routed IP tunnels, while tap creates Ethernet tunnels).

      dev tun
      
    • Find the ca, cert, and key options, then replace the default ca.crt, server.crt, and server.key values with the actual paths to your certificate authority, server certificate, and server private key files.

      ca /etc/openvpn/ca.crt
      cert /etc/openvpn/vpnserver.crt
      key /etc/openvpn/vpnserver.key
      
    • Find the dh directive and replace dh2048.pem with your actual Diffie-Hellman file path.

      dh /etc/openvpn/dh.pem
      
    • Find the data-ciphers directive, remove ; to uncomment it to enable OpenVPN to use strong, modern ciphers for encryption, then add data-ciphers-fallback AES-256-CBC as a fallback.

      data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
      data-ciphers-fallback AES-256-CBC
      
    • Add the following auth directive below data-ciphers to specify the HMAC digest algorithm, such as SHA512, for authenticating each packet.

      auth SHA512
      
    • Find the server directive and specify the VPN subnet to assign client addresses. For example, change the default 10.8.0.0 subnet to 10.10.10.0.

      server 10.10.10.0 255.255.255.0
      
    • Find the ;push "redirect-gateway def1 bypass-dhcp" directive and remove ; to uncomment it, redirecting all traffic through the VPN.

      push "redirect-gateway def1 bypass-dhcp"
      
    • Find the dhcp-option directives and replace the default addresses with your preferred DNS servers, such as 8.8.8.8 and 1.1.1.1, then remove ; to uncomment the options.

      push "dhcp-option DNS 8.8.8.8"
      push "dhcp-option DNS 1.1.1.1"
      
    • Find the tls-auth directive, uncomment it, replace ta.key with your actual key path, and keep 0 as the direction.

      tls-auth /etc/openvpn/ta.key 0 # This file is secret
      
    • Find the user and group pair, replace openvpn with nobody and nogroup respectively to run OpenVPN with reduced privileges, then remove ; to uncomment the options.

      user nobody group nogroup
      

      Save and close the file. Your modified server.conf file should look like the one below.

    port 1194
    proto udp
    dev tun
    ca /etc/openvpn/ca.crt
    cert /etc/openvpn/vpnserver.crt
    key /etc/openvpn/vpnserver.key
    dh /etc/openvpn/dh.pem
    data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
    data-ciphers-fallback AES-256-CBC
    auth SHA512
    topology subnet
    server 10.10.10.0 255.255.255.0
    ifconfig-pool-persist /var/log/openvpn/ipp.txt
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 8.8.8.8"
    push "dhcp-option DNS 1.1.1.1"
    keepalive 10 120
    tls-auth /etc/openvpn/ta.key 0
    user nobody group nogroup
    persist-key
    persist-tun
    status /var/log/openvpn/openvpn-status.log
    verb 3
    explicit-exit-notify 1
    
  4. Test the OpenVPN server configuration and verify it runs without errors:

    $ sudo openvpn --config /etc/openvpn/server.conf
    

    Your output should be similar to the one below when the configuration test is successful. Press Ctrl+C to stop the configuration test.

    ... 2025-07-10 22:21:00 IFCONFIG POOL IPv4: base=10.10.10.2 size=253 2025-07-10 22:21:00 IFCONFIG POOL LIST 2025-07-10 22:21:00 Initialization Sequence Completed
    

Enable IP Forwarding

  1. Open the /etc/sysctl.conf file to enable IP forwarding on the server:

    $ sudo nano /etc/sysctl.conf
    
  2. Find the # net.ipv4.ip_forward=1 directive and remove # to uncomment it:

    net.ipv4.ip_forward = 1
    

    This configuration enables IP forwarding, allowing OpenVPN clients to route traffic through the VPN.

  3. Apply the /etc/sysctl.conf configuration changes:

    $ sudo sysctl -p
    

    Output:

    net . ipv4 . ip_forward = 1
    
  4. Run the following command to verify the public network interface on your server:

    $ ip route | grep default
    

    Note the public interface name like enp1s0 in your output, similar to the one below.

    default via 192.0.2.1 dev enp1s0 proto dhcp src 192.0.2.100 metric 100
    
  5. Check the UFW status and verify that it's installed:

    $ sudo ufw status
    

    If it's not installed, run the following command to install UFW and allow SSH traffic:

    $ sudo apt install ufw -y && sudo ufw allow ssh
    
  6. Open the /etc/ufw/before.rules file to enable NAT through the firewall:

    $ sudo nano /etc/ufw/before.rules
    
  7. Add the following POSTROUTING policy configuration before the *filter section. Replace enp1s0 with your actual public interface name.

    *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.10.10.0/24 -o enp1s0 -j MASQUERADE COMMIT
    

    This firewall configuration modifies the default POSTROUTING policy in the nat table to masquerade all traffic from the 10.10.10.0/24 VPN subnet through the server's enp1s0 public network interface.

  8. Open the /etc/ufw/sysctl.conf file to enable IP forwarding through UFW:

    $ sudo nano /etc/ufw/sysctl.conf
    
  9. Find the #net/ipv4/ip_forward=1 directive and remove # to uncomment it:

    net/ipv4/ ip_forward = 1
    

    This configuration enables IP forwarding through the firewall to route packets between the OpenVPN tun interface and other interfaces on the server.

  10. Open the /etc/default/ufw file to allow forwarded packets through UFW:

    $ sudo nano /etc/default/ufw
    
  11. Find the DEFAULT_FORWARD_POLICY directive and change the default value from DROP to ACCEPT:

    DEFAULT_FORWARD_POLICY = "ACCEPT"
    
  12. Reload UFW to apply the firewall configuration changes:

    $ sudo ufw reload
    

4. Secure the OpenVPN Server

  1. Allow incoming connections to the tun0 OpenVPN interface:

    $ sudo ufw allow in on tun0
    
  2. Allow outgoing connections from the tun0 interface:

    $ sudo ufw allow out on tun0
    
  3. Allow network connections to the 1194 OpenVPN server port:

    $ sudo ufw allow 1194/udp
    
  4. Reload UFW to apply the firewall configuration changes:

    $ sudo ufw reload
    
  5. Check the UFW status to verify the active firewall rules:

    $ sudo ufw status
    

    Output:

    Status: active To ActionFrom -- ---------- 22/tcp ALLOW Anywhere Anywhere on tun0 ALLOW Anywhere 1194/udp ALLOW Anywhere 22/tcp (v6)ALLOW Anywhere (v6) Anywhere (v6) on tun0ALLOW Anywhere (v6) 1194/udp (v6)ALLOW Anywhere (v6) Anywhere ALLOW OUT Anywhere on tun0 Anywhere (v6)ALLOW OUT Anywhere (v6) on tun0
    

5. Manage the OpenVPN Server

OpenVPN uses systemd to manage the VPN interfaces based on the server configurations in the /etc/openvpn directory.

  1. Enable the OpenVPN service to start automatically at boot:

    $ sudo systemctl enable o******@server.service
    

    Output:

    Created symlink /etc/systemd/system/multi-user.target.wants/o******@server.service โ†’ /usr/lib/systemd/system/openvpn@.service.
    
  2. Start the OpenVPN service:

    $ sudo systemctl start o******@server.service
    
  3. View the OpenVPN service status and verify that it runs without errors:

    $ sudo systemctl status o******@server.service
    

    Output:

    โ— o******@server.service - OpenVPN connection to server Loaded: loaded (/usr/lib/systemd/system/openvpn@.service ; enabled; preset: enabled) Active: active (running) since Thu 2025-07-10 22:27:07 UTC ; 6s ago ...
    
  4. Verify that the tun0 OpenVPN interface is active and correctly configured on the server:

    $ ip addr show dev tun0
    

    Output:

    4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 500 link/none inet 10.10.10.1/24 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::42ab:ad8b:dd59:baf4/64 scope link stable-privacy valid_lft forever preferred_lft forever
    

Create a Client Certificate and Private Key Pair

OpenVPN requires a valid client certificate and private key pair to connect to the VPN server.

  1. Create a new keys directory in /etc/openvpn/client to store the client encryption keys:
    $ sudo mkdir -p /etc/openvpn/client/keys
    
  2. Navigate to the easy-rsa directory:
    $ cd ~/easy-rsa
    
  3. Generate a new certificate request usin
Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.