Appearance
OpenVPN Cheatsheet
OpenVPN is a robust and highly flexible VPN daemon that provides secure point-to-point or site-to-site connections in routed or bridged configurations. It uses SSL/TLS for key exchange and can traverse NATs and firewalls. OpenVPN is widely used for creating secure remote access solutions and site-to-site VPN connections.
Installation
Linux Installation
bash
# Ubuntu/Debian
sudo apt update
sudo apt install openvpn easy-rsa
# CentOS/RHEL
sudo yum install epel-release
sudo yum install openvpn easy-rsa
# Fedora
sudo dnf install openvpn easy-rsa
# Arch Linux
sudo pacman -S openvpn easy-rsa
# From source
wget https://swupdate.openvpn.org/community/releases/openvpn-2.5.8.tar.gz
tar -xzf openvpn-2.5.8.tar.gz
cd openvpn-2.5.8
./configure
make
sudo make install
Windows Installation
powershell
# Download from official website
# https://openvpn.net/community-downloads/
# Using Chocolatey
choco install openvpn
# Using Scoop
scoop install openvpn
# Manual installation
# Run OpenVPN installer as administrator
# Install TAP-Windows adapter
macOS Installation
bash
# Using Homebrew
brew install openvpn
# Using MacPorts
sudo port install openvpn2
# Tunnelblick (GUI client)
# Download from https://tunnelblick.net/
Certificate Authority Setup
Easy-RSA Configuration
bash
# Initialize PKI
cd /etc/openvpn/easy-rsa/
sudo ./easyrsa init-pki
# Build CA
sudo ./easyrsa build-ca nopass
# Generate server certificate
sudo ./easyrsa gen-req server nopass
sudo ./easyrsa sign-req server server
# Generate client certificates
sudo ./easyrsa gen-req client1 nopass
sudo ./easyrsa sign-req client client1
# Generate Diffie-Hellman parameters
sudo ./easyrsa gen-dh
# Generate TLS-auth key
sudo openvpn --genkey --secret ta.key
# Copy certificates to OpenVPN directory
sudo cp pki/ca.crt /etc/openvpn/server/
sudo cp pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/private/server.key /etc/openvpn/server/
sudo cp pki/dh.pem /etc/openvpn/server/
sudo cp ta.key /etc/openvpn/server/
Manual Certificate Generation
bash
# Generate CA private key
openssl genrsa -out ca.key 4096
# Generate CA certificate
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
# Generate server private key
openssl genrsa -out server.key 4096
# Generate server certificate request
openssl req -new -key server.key -out server.csr
# Sign server certificate
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# Generate client private key
openssl genrsa -out client.key 4096
# Generate client certificate request
openssl req -new -key client.key -out client.csr
# Sign client certificate
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
Server Configuration
Basic Server Configuration
bash
# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.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 8.8.4.4"
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-CBC
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
Advanced Server Configuration
bash
# /etc/openvpn/server/server-advanced.conf
port 1194
proto udp
dev tun
topology subnet
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-auth ta.key 0
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
cipher AES-256-GCM
auth SHA256
ncp-ciphers AES-256-GCM:AES-128-GCM
server 10.8.0.0 255.255.255.0
max-clients 100
duplicate-cn
# Client-specific configurations
client-config-dir /etc/openvpn/ccd
ccd-exclusive
# Routing
push "route 192.168.1.0 255.255.255.0"
push "route 10.0.0.0 255.255.255.0"
route 192.168.1.0 255.255.255.0
# DNS and gateway
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 192.168.1.1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DOMAIN company.local"
# Security
remote-cert-tls client
tls-verify /etc/openvpn/verify-cn.sh
auth-user-pass-verify /etc/openvpn/auth-pam.pl via-env
username-as-common-name
# Logging and monitoring
keepalive 10 120
ping-timer-rem
persist-key
persist-tun
comp-lzo adaptive
fast-io
status /var/log/openvpn/status.log 10
log /var/log/openvpn/server.log
verb 4
mute 20
# Performance tuning
sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
Site-to-Site Configuration
bash
# Site A server configuration
# /etc/openvpn/site-to-site.conf
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
# Add routes to remote networks
route 192.168.2.0 255.255.255.0
# Site B server configuration
# /etc/openvpn/site-to-site.conf
remote site-a.company.com
dev tun
ifconfig 10.8.0.2 10.8.0.1
secret static.key
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
# Add routes to remote networks
route 192.168.1.0 255.255.255.0
Client Configuration
Basic Client Configuration
bash
# client.ovpn
client
dev tun
proto udp
remote vpn.company.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
tls-auth ta.key 1
cipher AES-256-CBC
auth SHA256
verb 3
Inline Client Configuration
bash
# client-inline.ovpn
client
dev tun
proto udp
remote vpn.company.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-CBC
auth SHA256
verb 3
<ca>
-----BEGIN CERTIFICATE-----
[CA certificate content]
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
[Client certificate content]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
[Client private key content]
-----END PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
[TLS-auth key content]
-----END OpenVPN Static key V1-----
</tls-auth>
key-direction 1
Client-Specific Configuration
bash
# /etc/openvpn/ccd/client1
ifconfig-push 10.8.0.10 10.8.0.11
push "route 192.168.10.0 255.255.255.0"
iroute 192.168.10.0 255.255.255.0
# /etc/openvpn/ccd/client2
ifconfig-push 10.8.0.20 10.8.0.21
push "route 192.168.20.0 255.255.255.0"
iroute 192.168.20.0 255.255.255.0
push "redirect-gateway def1"
Service Management
Systemd Service Control
bash
# Start OpenVPN server
sudo systemctl start openvpn-server@server
sudo systemctl enable openvpn-server@server
# Start OpenVPN client
sudo systemctl start openvpn-client@client
sudo systemctl enable openvpn-client@client
# Check service status
sudo systemctl status openvpn-server@server
sudo systemctl status openvpn-client@client
# View logs
sudo journalctl -u openvpn-server@server -f
sudo journalctl -u openvpn-client@client -f
# Restart services
sudo systemctl restart openvpn-server@server
sudo systemctl reload openvpn-server@server
Manual Service Control
bash
# Start server manually
sudo openvpn --config /etc/openvpn/server/server.conf --daemon
# Start client manually
sudo openvpn --config /etc/openvpn/client/client.conf --daemon
# Start with logging
sudo openvpn --config /etc/openvpn/server/server.conf --log /var/log/openvpn.log
# Kill OpenVPN processes
sudo pkill openvpn
sudo killall openvpn
Network Configuration
IP Forwarding and NAT
bash
# Enable IP forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Configure iptables NAT
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
sudo iptables -A INPUT -i tun+ -j ACCEPT
sudo iptables -A FORWARD -i tun+ -j ACCEPT
sudo iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
# Save iptables rules
sudo iptables-save > /etc/iptables/rules.v4
# UFW configuration
sudo ufw allow 1194/udp
sudo ufw allow in on tun0
sudo ufw allow out on tun0
Routing Configuration
bash
# Add static routes
sudo ip route add 192.168.2.0/24 via 10.8.0.2 dev tun0
# Persistent routes in /etc/network/interfaces
auto tun0
iface tun0 inet manual
up ip route add 192.168.2.0/24 via 10.8.0.2 dev tun0
down ip route del 192.168.2.0/24 via 10.8.0.2 dev tun0
# Route all traffic through VPN
sudo ip route add 0.0.0.0/1 via 10.8.0.1 dev tun0
sudo ip route add 128.0.0.0/1 via 10.8.0.1 dev tun0
DNS Configuration
bash
# Configure DNS for VPN clients
# In server.conf
push "dhcp-option DNS 192.168.1.1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DOMAIN company.local"
# Client-side DNS configuration
# /etc/systemd/resolved.conf
[Resolve]
DNS=192.168.1.1 8.8.8.8
Domains=company.local
# Manual DNS configuration
echo "nameserver 192.168.1.1" | sudo tee /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf
Security Configuration
Authentication Methods
bash
# Certificate-based authentication (default)
ca ca.crt
cert client.crt
key client.key
# Username/password authentication
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
username-as-common-name
script-security 3
# Two-factor authentication
auth-user-pass
auth-user-pass-verify /etc/openvpn/google-authenticator.sh via-env
# LDAP authentication
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login
Encryption and Security
bash
# Strong encryption settings
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384
cipher AES-256-GCM
auth SHA256
ncp-ciphers AES-256-GCM:AES-128-GCM
# Perfect Forward Secrecy
tls-auth ta.key 0
key-direction 0
# Certificate verification
remote-cert-tls server
remote-cert-eku "TLS Web Server Authentication"
verify-x509-name server_name name
# Additional security
auth-nocache
tls-verify /etc/openvpn/verify-cn.sh
Access Control
bash
# Client certificate revocation
crl-verify /etc/openvpn/crl.pem
# IP-based access control
# In client-specific config
ifconfig-push 10.8.0.100 10.8.0.101
iroute 192.168.100.0 255.255.255.0
# Time-based access control
# Custom script in auth-user-pass-verify
#!/bin/bash
current_hour=$(date +%H)
if [ $current_hour -ge 9 ] && [ $current_hour -le 17 ]; then
exit 0
else
exit 1
fi
Monitoring and Logging
Status Monitoring
bash
# Server status file
status /var/log/openvpn/status.log 10
# View current connections
cat /var/log/openvpn/status.log
# Management interface
management localhost 7505
management-client-auth
management-client-pf
# Connect to management interface
telnet localhost 7505
Logging Configuration
bash
# Logging levels
verb 0 # No output except fatal errors
verb 1 # Startup info + connection initiation
verb 2 # + connection handshake
verb 3 # + show options
verb 4 # + show parameters
verb 5 # + show 'R' and 'W' characters
verb 6 # + show TCP/UDP reads/writes
verb 9 # + show TLS debugging info
# Log files
log /var/log/openvpn/server.log
log-append /var/log/openvpn/server.log
# Syslog
syslog openvpn-server
# Custom logging script
learn-address /etc/openvpn/learn-address.sh
Performance Monitoring
bash
# Connection statistics
echo "status" | nc localhost 7505
# Bandwidth monitoring
vnstat -i tun0
iftop -i tun0
# System resource monitoring
top -p $(pgrep openvpn)
htop -p $(pgrep openvpn)
# Network latency
ping -I tun0 8.8.8.8
mtr -I tun0 8.8.8.8
Troubleshooting
Common Issues
bash
# Connection problems
# Check firewall rules
sudo iptables -L -n
sudo ufw status
# Check routing
ip route show
ip route show table all
# Check DNS resolution
nslookup vpn.company.com
dig vpn.company.com
# Test connectivity
ping -c 4 vpn.company.com
telnet vpn.company.com 1194
nc -u vpn.company.com 1194
# Certificate issues
openssl x509 -in client.crt -text -noout
openssl verify -CAfile ca.crt client.crt
Debug Commands
bash
# Verbose logging
openvpn --config client.conf --verb 9
# Test configuration
openvpn --config server.conf --test-crypto
# Check certificates
openvpn --show-certs --config client.conf
# Network debugging
tcpdump -i any port 1194
wireshark -i any -f "port 1194"
# Process debugging
strace -p $(pgrep openvpn)
lsof -p $(pgrep openvpn)
Log Analysis
bash
# Common log messages
grep "Initialization Sequence Completed" /var/log/openvpn/server.log
grep "TLS Error" /var/log/openvpn/server.log
grep "AUTH_FAILED" /var/log/openvpn/server.log
grep "VERIFY ERROR" /var/log/openvpn/server.log
# Connection analysis
awk '/CLIENT_LIST/ {print $2, $3, $4, $5}' /var/log/openvpn/status.log
# Error patterns
grep -E "(ERROR|FATAL|WARNING)" /var/log/openvpn/server.log
Advanced Configuration
Load Balancing
bash
# Multiple server instances
# /etc/openvpn/server1.conf
port 1194
dev tun1
server 10.8.1.0 255.255.255.0
# /etc/openvpn/server2.conf
port 1195
dev tun2
server 10.8.2.0 255.255.255.0
# Client configuration with multiple servers
remote vpn1.company.com 1194
remote vpn2.company.com 1195
remote-random
High Availability
bash
# Keepalived configuration for HA
# /etc/keepalived/keepalived.conf
vrrp_script chk_openvpn {
script "/bin/pgrep openvpn"
interval 2
weight 2
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass mypassword
}
virtual_ipaddress {
192.168.1.100
}
track_script {
chk_openvpn
}
}
Performance Tuning
bash
# Buffer sizes
sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
# Compression
comp-lzo adaptive
compress lz4-v2
push "compress lz4-v2"
# Fast I/O
fast-io
# TCP optimization
tcp-nodelay
socket-flags TCP_NODELAY
# Threading
nice -10
Scripting and Automation
bash
# Client connect script
client-connect /etc/openvpn/client-connect.sh
#!/bin/bash
# /etc/openvpn/client-connect.sh
echo "Client $common_name connected from $trusted_ip"
echo "$(date): $common_name connected" >> /var/log/openvpn/connections.log
# Client disconnect script
client-disconnect /etc/openvpn/client-disconnect.sh
#!/bin/bash
# /etc/openvpn/client-disconnect.sh
echo "Client $common_name disconnected"
echo "$(date): $common_name disconnected" >> /var/log/openvpn/connections.log
# Learn address script
learn-address /etc/openvpn/learn-address.sh
#!/bin/bash
# /etc/openvpn/learn-address.sh
case "$1" in
add|update)
echo "$(date): $1 $2 $3" >> /var/log/openvpn/addresses.log
;;
delete)
echo "$(date): $1 $2" >> /var/log/openvpn/addresses.log
;;
esac
Best Practices
Security Best Practices
bash
# Use strong encryption
cipher AES-256-GCM
auth SHA256
tls-version-min 1.2
# Certificate security
# Use 4096-bit RSA keys
# Implement certificate revocation
# Regular certificate rotation
# Network security
# Use non-standard ports
# Implement fail2ban
# Regular security audits
# Access control
# Implement least privilege
# Use client-specific configurations
# Monitor and log all connections
Operational Best Practices
bash
# Configuration management
# Version control configurations
# Test changes in staging
# Document all modifications
# Monitoring
# Implement comprehensive logging
# Set up alerting for failures
# Regular performance monitoring
# Backup and recovery
# Regular configuration backups
# Certificate backup procedures
# Disaster recovery planning
# Maintenance
# Regular updates and patches
# Certificate renewal procedures
# Performance optimization reviews
Deployment Considerations
bash
# Capacity planning
# Estimate concurrent users
# Plan for peak usage
# Monitor resource utilization
# Network design
# Plan IP address allocation
# Consider routing requirements
# Implement proper segmentation
# Scalability
# Design for horizontal scaling
# Implement load balancing
# Plan for geographic distribution
# Compliance
# Meet regulatory requirements
# Implement audit logging
# Document security controls