Skip to main content

Setting Up an OpenVPN Server

··3 mins·
Linux Openvpn
Makoto Morinaga
Author
Makoto Morinaga
A personal notebook for tech notes, coding, and system experiments.
Table of Contents

Remote access to services hosted on a home network is sometimes necessary, but exposing all services to the internet is not ideal from a security standpoint. OpenVPN can be used to establish a secure, encrypted connection between an external network and a home LAN, allowing clients such as iPhones or PCs to access private IP addresses as if they were within the home network.

For security reasons, the Certificate Authority (CA) server and the VPN server are separated. The system consists of:

  • CA Server: Signs certificates for clients and the VPN server.
  • VPN Server: Establishes a VPN tunnel with external clients.
  • Clients: Devices connecting from external networks.

Setting Up the CA Server
#

Installing easy-rsa
#

Terminal
# Arch Linux
sudo pacman -S easy-rsa

Initializing the CA
#

Terminal
cd /etc/easy-rsa
# Arch Linux
sudo easyrsa init-pki
sudo easyrsa build-ca

A passphrase is required for the CA key. The Common Name can be left as default.

Setting Up the VPN Server
#

Installing OpenVPN and easy-rsa
#

Terminal
# Arch Linux
sudo pacman -S openvpn easy-rsa

Copying the CA Certificate
#

The CA’s public key (/etc/easy-rsa/pki/ca.crt) must be copied to /etc/openvpn/server/ on the VPN server with root ownership.

Terminal
# example
scp /etc/easy-rsa/pki/ca.crt vpn-server:/etc/openvpn/server/

Ensure the permissions of ca.crt are restricted to root.

Generating the Server Certificate
#

Terminal
cd /etc/easy-rsa
sudo easyrsa init-pki
sudo easyrsa gen-req server nopass
sudo cp /etc/easy-rsa/pki/private/server.key /etc/openvpn/server/

Common Name can be left as default.

Generating Diffie-Hellman Parameters
#

Terminal
sudo openssl dhparam -out /etc/openvpn/server/dh.pem 2048

Creating an HMAC Key
#

Terminal
sudo openvpn --genkey --secret /etc/openvpn/server/ta.key

This enhances security by rejecting improperly signed packets.

Creating OpenVPN Client Certificates
#

Generating Client Certificates
#

Terminal
cd /etc/easy-rsa
sudo easyrsa gen-req client1 nopass

Common Name can be left as default.

Copying Certificate Requests to the CA Server
#

Terminal
scp /etc/easy-rsa/pki/reqs/{server,client1}.req ca-server:/tmp/

Signing Certificates on the CA Server
#

Terminal
cd /etc/easy-rsa
sudo easyrsa import-req /tmp/server.req server
sudo easyrsa import-req /tmp/client1.req client1
sudo easyrsa sign-req server server
sudo easyrsa sign-req client client1

Enter the CA passphrase when prompted.

Copying Signed Certificates to the VPN Server
#

Terminal
scp /etc/easy-rsa/pki/issued/server.crt vpn-server:/etc/openvpn/server/

Configuring OpenVPN
#

Copying Configuration Samples
#

Terminal
sudo cp /usr/share/openvpn/examples/server.conf /etc/openvpn/server/

Updating server.conf
#

  • Certificate and key settings:

    /etc/openvpn/server/server.conf
    ca ca.crt
    cert server.crt
    key server.key
    dh dh.pem
  • HMAC key:

    /etc/openvpn/server/server.conf
    tls-auth ta.key 0
  • Running OpenVPN as a non-root user:

    /etc/openvpn/server/server.conf
    user nobody
    group nobody
  • Port and protocol:

    /etc/openvpn/server/server.conf
    port 1194
    proto udp
  • Subnet:

    /etc/openvpn/server/server.conf
    server 10.8.0.0 255.255.255.0
  • Encryption settings:

    /etc/openvpn/server/server.conf
    cipher AES-256-GCM
    auth SHA512
    tls-version-min 1.3
  • Compression:

    /etc/openvpn/server/server.conf
    compress lz4-v2a
    push "compress lz4-v2"
  • Routing all traffic through VPN:

    /etc/openvpn/server/server.conf
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 1.1.1.1"

Starting and Enabling OpenVPN Service
#

Terminal
sudo systemctl start [email protected]
sudo systemctl enable [email protected]

Firewall Configuration
#

Allow UDP port 1194:

Terminal
iptables -A INPUT -p udp --dport 1194 -j ACCEPT

Allow traffic from VPN clients:

Terminal
iptables -A INPUT -p tcp -s 10.8.0.0/24 --dport 22 -j ACCEPT
iptables -t nat -A POSTROUTING -o ens192 -s 10.8.0.0/24 -j MASQUERADE
iptables -I FORWARD -o ens192 -s 10.8.0.0/24 -j ACCEPT

For further details, refer to: iptables Configuration.

Creating OpenVPN Client Profiles
#

Installing ovpngen
#

Terminal
# Arch Linux
yay -S ovpngen

If not installed yay, refer to Installing yay on Arch Linux to install it.。

Generating Client Profile
#

Terminal
ovpngen vpn.example.com /etc/openvpn/server/ca.crt \
  /etc/easy-rsa/pki/issued/client1.crt \
  /etc/easy-rsa/pki/private/client1.key \
  /etc/openvpn/server/ta.key > client.ovpn

Updating client.ovpn
#

Ensure the cipher and authentication settings match the server:

client.ovpn
cipher AES-256-GCM
auth SHA512

Connecting from a Client
#

Transfer client.ovpn to the client device and import it into an OpenVPN client application.

OS Software
macOS Tunnelblick
iOS OpenVPN Connect

Related

Setting Up an Web Server with Nginx
··2 mins
Linux Nginx
Samba-based Time Machine Backup
··2 mins
Linux Macos Time-Machine Samba
Setting Up an Incremental Backup System with Borg
··3 mins
Backup Linux Borg