Skip to Content

OpenVPN / WireGuard VPN

A VPN (Virtual Private Network) provides an encrypted tunnel for remote access and site-to-site connectivity. This article covers deploying two mainstream VPN solutions on Ubuntu 26.04.

WireGuard

WireGuard is a modern, high-performance VPN protocol integrated into the Linux kernel. It is simple to configure and delivers excellent performance.

Install WireGuard

sudo apt update sudo apt install wireguard -y # Verify the kernel module sudo modprobe wireguard lsmod | grep wireguard

Server Configuration

# /etc/wireguard is writable only by root, so the commands below require root. # It is recommended to run sudo -i to switch to root first, or add sudo to each command. # Generate server key pair wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key sudo chmod 600 /etc/wireguard/server_private.key # Generate client key pair wg genkey | sudo tee /etc/wireguard/client1_private.key | wg pubkey | sudo tee /etc/wireguard/client1_public.key # Read key contents SERVER_PRIVKEY=$(sudo cat /etc/wireguard/server_private.key) SERVER_PUBKEY=$(sudo cat /etc/wireguard/server_public.key) CLIENT1_PRIVKEY=$(sudo cat /etc/wireguard/client1_private.key) CLIENT1_PUBKEY=$(sudo cat /etc/wireguard/client1_public.key)
# Create server configuration sudo tee /etc/wireguard/wg0.conf << EOF [Interface] Address = 10.0.0.1/24 ListenPort = 51820 PrivateKey = ${SERVER_PRIVKEY} # Enable IP forwarding and NAT (for client internet access) PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE # Client 1 [Peer] PublicKey = ${CLIENT1_PUBKEY} AllowedIPs = 10.0.0.2/32 EOF sudo chmod 600 /etc/wireguard/wg0.conf
# Enable IP forwarding echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-wireguard.conf sudo sysctl -p /etc/sysctl.d/99-wireguard.conf # Start WireGuard sudo systemctl enable --now wg-quick@wg0 # Check status sudo wg show # Firewall sudo ufw allow 51820/udp

Client Configuration

# Client configuration file sudo tee /etc/wireguard/client1.conf << EOF [Interface] Address = 10.0.0.2/24 PrivateKey = ${CLIENT1_PRIVKEY} DNS = 8.8.8.8, 1.1.1.1 [Peer] PublicKey = ${SERVER_PUBKEY} Endpoint = your-server-ip:51820 AllowedIPs = 0.0.0.0/0 # Route all traffic through VPN # AllowedIPs = 10.0.0.0/24 # Only route VPN subnet through VPN (split tunneling) PersistentKeepalive = 25 EOF sudo chmod 600 /etc/wireguard/client1.conf # Start the connection (the interface name is taken from the config file name client1) sudo wg-quick up client1 # Disconnect sudo wg-quick down client1

Add a New Client

# Generate new client keys on the server wg genkey | tee /etc/wireguard/client2_private.key | wg pubkey > /etc/wireguard/client2_public.key CLIENT2_PUBKEY=$(cat /etc/wireguard/client2_public.key) # Hot-add a peer (no service restart needed) sudo wg set wg0 peer ${CLIENT2_PUBKEY} allowed-ips 10.0.0.3/32 # Or edit the configuration file and reload sudo systemctl restart wg-quick@wg0

Generate a Client QR Code (For Mobile)

sudo apt install qrencode -y # Generate a QR code from the config sudo qrencode -t ansiutf8 < /etc/wireguard/client1.conf

OpenVPN

OpenVPN is a mature, stable VPN solution with broader compatibility and support for more complex network topologies.

Install OpenVPN

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

Configure PKI (Certificate Infrastructure)

# Initialize Easy-RSA mkdir -p ~/easy-rsa ln -s /usr/share/easy-rsa/* ~/easy-rsa/ cd ~/easy-rsa # Configure variables tee vars << 'EOF' set_var EASYRSA_ALGO ec set_var EASYRSA_DIGEST sha512 set_var EASYRSA_CURVE secp384r1 set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "California" set_var EASYRSA_REQ_CITY "San Francisco" set_var EASYRSA_REQ_ORG "MyOrg" set_var EASYRSA_REQ_EMAIL "admin@example.com" set_var EASYRSA_CA_EXPIRE 3650 set_var EASYRSA_CERT_EXPIRE 365 EOF # Initialize PKI ./easyrsa init-pki # Create CA (Certificate Authority) ./easyrsa build-ca nopass # Generate server certificate ./easyrsa gen-req server nopass ./easyrsa sign-req server server # Generate client certificate ./easyrsa gen-req client1 nopass ./easyrsa sign-req client client1 # Generate TLS authentication key openvpn --genkey secret /etc/openvpn/ta.key # Generate DH parameters (can be skipped when using EC) # ./easyrsa gen-dh

Copy Certificate Files

sudo cp ~/easy-rsa/pki/ca.crt /etc/openvpn/server/ sudo cp ~/easy-rsa/pki/issued/server.crt /etc/openvpn/server/ sudo cp ~/easy-rsa/pki/private/server.key /etc/openvpn/server/ sudo cp ~/easy-rsa/ta.key /etc/openvpn/server/ 2>/dev/null || sudo cp /etc/openvpn/ta.key /etc/openvpn/server/

Server Configuration

sudo tee /etc/openvpn/server/server.conf << 'EOF' # Listening port and protocol port 1194 proto udp dev tun # Certificate files ca /etc/openvpn/server/ca.crt cert /etc/openvpn/server/server.crt key /etc/openvpn/server/server.key tls-auth /etc/openvpn/server/ta.key 0 # Encryption settings cipher AES-256-GCM auth SHA256 tls-version-min 1.2 # Network settings server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /var/log/openvpn/ipp.txt # Push routes and DNS to clients push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 1.1.1.1" # Allow client-to-client communication client-to-client # Keepalive keepalive 10 120 # Security user nobody group nogroup persist-key persist-tun # Logging status /var/log/openvpn/openvpn-status.log log-append /var/log/openvpn/openvpn.log verb 3 mute 20 # Maximum clients max-clients 50 EOF
# Create the log directory sudo mkdir -p /var/log/openvpn # Enable IP forwarding echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-openvpn.conf sudo sysctl -p /etc/sysctl.d/99-openvpn.conf # Configure NAT sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE # Persist iptables rules sudo apt install iptables-persistent -y sudo netfilter-persistent save # Start OpenVPN sudo systemctl enable --now openvpn-server@server # Firewall sudo ufw allow 1194/udp

Client Configuration

# Create the client .ovpn configuration file cat << 'EOF' > ~/client1.ovpn client dev tun proto udp remote your-server-ip 1194 resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server cipher AES-256-GCM auth SHA256 key-direction 1 verb 3 EOF # Embed certificates (generate a single-file config) echo "<ca>" >> ~/client1.ovpn cat ~/easy-rsa/pki/ca.crt >> ~/client1.ovpn echo "</ca>" >> ~/client1.ovpn echo "<cert>" >> ~/client1.ovpn cat ~/easy-rsa/pki/issued/client1.crt >> ~/client1.ovpn echo "</cert>" >> ~/client1.ovpn echo "<key>" >> ~/client1.ovpn cat ~/easy-rsa/pki/private/client1.key >> ~/client1.ovpn echo "</key>" >> ~/client1.ovpn echo "<tls-auth>" >> ~/client1.ovpn cat /etc/openvpn/server/ta.key >> ~/client1.ovpn echo "</tls-auth>" >> ~/client1.ovpn

Securely transfer client1.ovpn to the client to use.

WireGuard vs OpenVPN Comparison

FeatureWireGuardOpenVPN
Codebase size~4,000 lines~100,000 lines
EncryptionChaCha20, Curve25519OpenSSL (multiple options)
PerformanceVery high (kernel-space)High (user-space)
ProtocolUDPUDP / TCP
Firewall traversalUDP onlyTCP 443 can mimic HTTPS
Configuration complexitySimpleMore complex
Dynamic IP clientsSupportedSupported
PKI certificate systemNone (key pairs)Full CA infrastructure
Client platformsCross-platformCross-platform
Audit loggingBasicDetailed

Recommendations

  • WireGuard: Personal use, small teams, simplicity and high efficiency
  • OpenVPN: Enterprise environments, detailed audit logging required, TCP firewall traversal needed

Management and Monitoring

# WireGuard status sudo wg show sudo wg show wg0 latest-handshakes sudo wg show wg0 transfer # OpenVPN status sudo cat /var/log/openvpn/openvpn-status.log sudo journalctl -u openvpn-server@server -f # View connected clients # WireGuard sudo wg show wg0 peers # OpenVPN sudo cat /var/log/openvpn/openvpn-status.log | grep "CLIENT_LIST"

Troubleshooting

# Check IP forwarding sysctl net.ipv4.ip_forward # Check NAT rules sudo iptables -t nat -L -n -v # Check listening ports ss -ulnp | grep -E "(51820|1194)" # Test connectivity ping 10.0.0.1 # WireGuard server ping 10.8.0.1 # OpenVPN server # WireGuard debugging sudo wg show wg0 # If there is no handshake time, check the firewall and port # OpenVPN debugging sudo tail -f /var/log/openvpn/openvpn.log # Client connection test curl ifconfig.me # Check if the exit IP is the VPN server
Last updated on