Installation Process¶
The installOpenVPN() function is the core of the script (~800 lines). It performs the full server setup in 13 phases.
Phase 1: Package Installation¶
The script first installs the OpenVPN repository to get the latest stable release, then installs packages based on the distribution:
After installation, the script verifies:
- ChaCha20-Poly1305 requires OpenVPN 2.5+
- Checks DCO availability (OpenVPN 2.6+ and kernel 6.16+)
Phase 2: User and Group¶
OpenVPN runs as an unprivileged user:
| Distribution | User | Group |
|---|---|---|
| Fedora, RHEL, CentOS, Rocky, Alma, Oracle, Amazon | openvpn | openvpn |
| Arch | openvpn | network |
| Debian, Ubuntu, openSUSE | nobody | nogroup |
The script also checks if the systemd service already handles privilege dropping to avoid a "double drop" error.
Phase 3: Easy-RSA and PKI¶
Downloads Easy-RSA 3.2.6 (if not already present), verifies SHA256 checksum, and extracts to /etc/openvpn/server/easy-rsa/.
Configures the vars file:
# ECDSA mode
set_var EASYRSA_ALGO ec
set_var EASYRSA_CURVE prime256v1
# RSA mode
set_var EASYRSA_KEY_SIZE 2048
PKI Mode¶
./easyrsa init-pki
./easyrsa --batch build-ca nopass # 10-year CA
./easyrsa --batch build-server-full <name> nopass # Server cert
./easyrsa gen-crl # Certificate Revocation List
Fingerprint Mode¶
./easyrsa --batch self-sign-server <name> nopass
# Extract and store server fingerprint
openssl x509 -in cert.crt -fingerprint -sha256 -noout
TLS Key Generation¶
| Mode | Command |
|---|---|
| tls-crypt-v2 | openvpn --genkey tls-crypt-v2-server tls-crypt-v2.key |
| tls-crypt | openvpn --genkey secret tls-crypt.key |
| tls-auth | openvpn --genkey secret tls-auth.key |
Phase 4: Server Configuration¶
Generates /etc/openvpn/server/server.conf with all the configured options.
Key sections of the generated config:
Network¶
port 1194
proto udp # or tcp, udp6, tcp6
dev tun
topology subnet
server 10.8.0.0 255.255.255.0 # Always present (even IPv6-only, for leak prevention)
server-ipv6 fd42:42:42:42::/112 # If IPv6 enabled
DNS Push¶
Depending on the selected provider, the script adds push "dhcp-option DNS ..." lines. For Unbound, it points to the VPN gateway IP.
Gateway and Leak Prevention¶
# IPv4 clients
push "redirect-gateway def1 bypass-dhcp"
# IPv6 clients
push "redirect-gateway ipv6"
push "route-ipv6 2000::/3"
# IPv4-only: block IPv6 to prevent leaks
push "block-ipv6"
Encryption¶
dh none
tls-groups X25519:prime256v1:secp384r1:secp521r1
tls-crypt-v2 /etc/openvpn/server/easy-rsa/tls-crypt-v2.key
auth SHA256
cipher AES-128-GCM
data-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
Management¶
The management socket enables real-time client monitoring and disconnection.
Phase 5: Sysctl¶
Creates /etc/sysctl.d/99-openvpn.conf:
Applied immediately with sysctl --system.
Phase 6: SELinux¶
If SELinux is enforcing and a non-standard port is used:
Phase 7: Systemd Service¶
- Finds the package-provided
openvpn-server@.service - Copies it to
/etc/systemd/system/(to avoid modifying package files) - Patches the service:
- Removes
LimitNPROC(causes issues on OpenVZ) - Fixes paths for openSUSE
- Ensures
RuntimeDirectoryis set
- Removes
- On Ubuntu 25.04+: configures AppArmor to allow the management socket
Phase 8: Firewall¶
See Firewall for details. The script auto-detects and configures firewalld, nftables, or iptables.
Phase 9: Client Template¶
Creates /etc/openvpn/server/client-template.txt — the base for all .ovpn files. Contains:
- Connection settings (remote, port, protocol)
- Encryption settings (cipher, auth, TLS)
- Platform-specific options (
block-outside-dnsfor Windows) - Placeholder markers for inline certificates and keys
Phase 10: Service Start and First Client¶
- Starts
openvpn-server@serverservice - In fingerprint mode: delays start until first client is added (server needs client fingerprint)
- Generates the first client
.ovpnfile by callingnewClient()