OpenVPN is the veteran of self-hosted VPNs: mature, audited, supported by clients on every platform, and able to run over TCP port 443 when restrictive networks block everything else. WireGuard is simpler and faster for most uses (see WireGuard on a VPS and OpenVPN vs WireGuard), but OpenVPN remains the right tool when you need its flexibility or compatibility.

This guide sets up a server by hand on Ubuntu 22.04+/Debian 12+ so you understand each part. (Community installer scripts automate the same steps if you prefer.)

1. Install packages

sudo apt update
sudo apt install -y openvpn easy-rsa

2. Create a certificate authority with Easy-RSA

OpenVPN authenticates server and clients with certificates.

make-cadir ~/easy-rsa
cd ~/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass          # CA; use a passphrase in production
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh                   # Diffie-Hellman parameters (or use ECDH, below)
openvpn --genkey secret ta.key     # TLS-crypt key for extra protection

Copy what the server needs:

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

Keep the CA private key (pki/private/ca.key) safe — ideally on a different machine.

3. Server configuration

/etc/openvpn/server/server.conf:

port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-crypt ta.key

server 10.8.0.0 255.255.255.0
topology subnet
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 9.9.9.9"

keepalive 10 120
cipher AES-256-GCM
data-ciphers AES-256-GCM:CHACHA20-POLY1305
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
verb 3
explicit-exit-notify 1
  • redirect-gateway routes all client traffic through the VPN (full tunnel). Remove it and push specific routes for a split tunnel.
  • For networks that block UDP, a second instance with proto tcp and port 443 helps (drop explicit-exit-notify, which is UDP-only).

4. Forwarding and NAT

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl --system

With UFW, add NAT to /etc/ufw/before.rules before the *filter section (replace eth0 with your public interface from ip route | grep default):

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

Set DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw, then:

sudo ufw allow 1194/udp
sudo ufw reload

5. Start the server

sudo mkdir -p /var/log/openvpn
sudo systemctl enable --now openvpn-server@server
sudo systemctl status openvpn-server@server --no-pager
ip addr show tun0

6. Create a client

cd ~/easy-rsa
./easyrsa gen-req alice nopass
./easyrsa sign-req client alice

Build a single .ovpn file with everything inline:

cat > alice.ovpn <<EOF
client
dev tun
proto udp
remote 203.0.113.10 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
$(cat pki/ca.crt)
</ca>
<cert>
$(sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' pki/issued/alice.crt)
</cert>
<key>
$(cat pki/private/alice.key)
</key>
<tls-crypt>
$(cat ta.key)
</tls-crypt>
EOF
chmod 600 alice.ovpn

Transfer it securely (scp, not email) and import it into OpenVPN Connect (Windows, macOS, iOS, Android) or use sudo openvpn --config alice.ovpn on Linux.

7. Revoke a client

cd ~/easy-rsa
./easyrsa revoke alice
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/
echo "crl-verify crl.pem" | sudo tee -a /etc/openvpn/server/server.conf
sudo systemctl restart openvpn-server@server

The CRL has an expiry date; regenerate it periodically (./easyrsa gen-crl) or revoked clients may become valid again when it expires — set a reminder.

Troubleshooting

  • Client connects but no internet — forwarding or NAT missing; check sysctl net.ipv4.ip_forward and iptables -t nat -L -n -v.
  • TLS key negotiation failed — UDP port blocked somewhere; test TCP 443.
  • Connected, DNS doesn’t resolve — Linux clients need a helper (openvpn-systemd-resolved or update-resolv-conf) to apply pushed DNS.
  • Read the logs: journalctl -u openvpn-server@server -f.

Choosing the location

The VPN exit is where your VPS is. Pick a location near you for speed: our USA, Hong Kong and Tokyo data centers cover the Americas and Asia. More options in VPN on a VPS.

  • OpenVPN
  • VPN
  • Networking