Build a production-ready OpenVPN high availability cluster using keepalived for automatic failover and HAProxy for load balancing across multiple OpenVPN servers.
Prerequisites
- At least 4 servers with sudo access
- Basic networking knowledge
- SSH key authentication between servers
- Domain name or static IP addresses
What this solves
A single OpenVPN server creates a point of failure that can disrupt remote access for your entire organization. This tutorial creates a highly available OpenVPN cluster with automatic failover using keepalived and load balancing through HAProxy, ensuring continuous VPN connectivity even when individual servers fail.
Step-by-step installation
Update system packages on all nodes
Start by updating packages on all three servers that will form your OpenVPN cluster.
sudo apt update && sudo apt upgrade -y
Install OpenVPN and Easy-RSA on all OpenVPN nodes
Install OpenVPN server and certificate management tools on your two OpenVPN backend servers (203.0.113.10 and 203.0.113.11).
sudo apt install -y openvpn easy-rsa
sudo mkdir -p /etc/openvpn/easy-rsa
Set up Certificate Authority on primary node
Initialize the PKI infrastructure on your primary OpenVPN server (203.0.113.10). This creates shared certificates for the cluster.
cd /etc/openvpn/easy-rsa
sudo /usr/share/easy-rsa/easyrsa init-pki
sudo /usr/share/easy-rsa/easyrsa build-ca nopass
Generate the server certificate and Diffie-Hellman parameters.
sudo /usr/share/easy-rsa/easyrsa gen-req server nopass
sudo /usr/share/easy-rsa/easyrsa sign-req server server
sudo /usr/share/easy-rsa/easyrsa gen-dh
sudo openvpn --genkey secret ta.key
Configure shared certificate storage
Create a shared directory for certificates and copy them to both OpenVPN servers. We'll use rsync over SSH for synchronization.
sudo mkdir -p /etc/openvpn/certs
sudo cp pki/ca.crt /etc/openvpn/certs/
sudo cp pki/issued/server.crt /etc/openvpn/certs/
sudo cp pki/private/server.key /etc/openvpn/certs/
sudo cp pki/dh.pem /etc/openvpn/certs/
sudo cp ta.key /etc/openvpn/certs/
Copy certificates to the secondary OpenVPN server.
sudo rsync -av /etc/openvpn/certs/ root@203.0.113.11:/etc/openvpn/certs/
Configure OpenVPN server on primary node
Create the OpenVPN server configuration that will work with load balancing. Both servers use identical configs.
port 1194
proto udp
dev tun
ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/server.crt
key /etc/openvpn/certs/server.key
dh /etc/openvpn/certs/dh.pem
tls-auth /etc/openvpn/certs/ta.key 0
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
cipher AES-256-CBC
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
management 127.0.0.1 7505
Configure OpenVPN server on secondary node
Copy the same configuration to the secondary server, but change the server pool to avoid IP conflicts.
sudo scp /etc/openvpn/server.conf root@203.0.113.11:/etc/openvpn/
Modify the server pool on the secondary node to use a different subnet.
server 10.8.1.0 255.255.255.0
Create OpenVPN log directories
Create logging directories on both OpenVPN servers.
sudo mkdir -p /var/log/openvpn
sudo chown nobody:nogroup /var/log/openvpn
sudo chmod 755 /var/log/openvpn
Enable IP forwarding on OpenVPN nodes
Enable packet forwarding to allow VPN traffic to route properly.
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Configure firewall rules for OpenVPN
Set up iptables rules to allow OpenVPN traffic and NAT for client connections.
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
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o eth0 -j MASQUERADE
sudo iptables -A INPUT -i tun+ -j ACCEPT
sudo iptables -A INPUT -p udp --dport 1194 -j ACCEPT
Save the firewall rules.
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
Start and enable OpenVPN services
Enable OpenVPN to start automatically and start the service on both servers.
sudo systemctl enable openvpn@server
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server
Install HAProxy and keepalived on load balancer node
Install the load balancing and high availability components on your third server (203.0.113.12).
sudo apt install -y haproxy keepalived
Configure HAProxy for UDP load balancing
Configure HAProxy to balance OpenVPN UDP traffic across your OpenVPN servers.
global
log stdout local0
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
option tcplog
option dontlognull
retries 3
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen stats
bind *:8080
stats enable
stats uri /stats
stats refresh 5s
stats admin if TRUE
frontend openvpn_frontend
bind *:1194
mode tcp
default_backend openvpn_backend
backend openvpn_backend
mode tcp
balance roundrobin
option tcp-check
tcp-check connect port 1194
server ovpn1 203.0.113.10:1194 check inter 5000 fall 2 rise 2
server ovpn2 203.0.113.11:1194 check inter 5000 fall 2 rise 2
Configure keepalived for automatic failover
Set up keepalived to provide a virtual IP that automatically fails over between HAProxy instances.
vrrp_script chk_haproxy {
script "/bin/curl -f http://localhost:8080/stats || exit 1"
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 SecurePass123!
}
virtual_ipaddress {
203.0.113.100/24
}
track_script {
chk_haproxy
}
notify_master "/usr/local/bin/notify.sh MASTER"
notify_backup "/usr/local/bin/notify.sh BACKUP"
notify_fault "/usr/local/bin/notify.sh FAULT"
}
Create notification script for keepalived events
Create a script to log keepalived state changes and optionally send notifications.
#!/bin/bash
DATE=$(date '+%Y-%m-%d %H:%M:%S')
HOST=$(hostname)
STATE=$1
echo "$DATE: $HOST changed to $STATE state" >> /var/log/keepalived-notify.log
case $STATE in
"MASTER") echo "$DATE: $HOST became MASTER" | logger -t keepalived
# Optional: send email or webhook notification
;;
"BACKUP") echo "$DATE: $HOST became BACKUP" | logger -t keepalived
;;
"FAULT") echo "$DATE: $HOST entered FAULT state" | logger -t keepalived
;;
*) echo "$DATE: $HOST entered unknown state: $STATE" | logger -t keepalived
;;
esac
Make the script executable.
sudo chmod 755 /usr/local/bin/notify.sh
sudo chown root:root /usr/local/bin/notify.sh
Set up secondary HAProxy node for redundancy
Install HAProxy and keepalived on a fourth server (203.0.113.13) for load balancer redundancy.
sudo scp /etc/haproxy/haproxy.cfg root@203.0.113.13:/etc/haproxy/
sudo scp /etc/keepalived/keepalived.conf root@203.0.113.13:/etc/keepalived/
sudo scp /usr/local/bin/notify.sh root@203.0.113.13:/usr/local/bin/
Modify the keepalived configuration on the secondary node to be a backup.
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
# ... rest identical to master config
}
Configure firewall rules for HAProxy nodes
Allow OpenVPN traffic and HAProxy management traffic.
sudo iptables -A INPUT -p tcp --dport 1194 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 1194 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8080 -s 203.0.113.0/24 -j ACCEPT
sudo iptables -A INPUT -p vrrp -j ACCEPT
sudo iptables -A OUTPUT -p vrrp -j ACCEPT
Start and enable services on HAProxy nodes
Enable and start HAProxy and keepalived on both load balancer nodes.
sudo systemctl enable haproxy keepalived
sudo systemctl start haproxy keepalived
sudo systemctl status haproxy keepalived
Create client certificate automation script
Create a script to generate client certificates that work with the cluster.
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 "
exit 1
fi
CLIENT="$1"
EASY_RSA="/etc/openvpn/easy-rsa"
cd $EASY_RSA
Generate client certificate
sudo /usr/share/easy-rsa/easyrsa gen-req "$CLIENT" nopass
sudo /usr/share/easy-rsa/easyrsa sign-req client "$CLIENT"
Create client config
cat > "/tmp/${CLIENT}.ovpn" << EOF
client
dev tun
proto udp
remote 203.0.113.100 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3
key-direction 1
$(sudo cat /etc/openvpn/certs/ca.crt)
$(sudo cat pki/issued/${CLIENT}.crt)
$(sudo cat pki/private/${CLIENT}.key)
$(sudo cat /etc/openvpn/certs/ta.key)
EOF
echo "Client configuration created: /tmp/${CLIENT}.ovpn"
echo "Copy this file to your client device."
Make the script executable.
sudo chmod 755 /usr/local/bin/create-ovpn-client.sh
Set up health monitoring scripts
Create monitoring scripts to check cluster health and log performance metrics.
#!/bin/bash
LOG_FILE="/var/log/ovpn-cluster-health.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
Check virtual IP status
VIP_STATUS=$(ip addr show | grep 203.0.113.100 && echo "VIP Active" || echo "VIP Inactive")
Check HAProxy status
HAPROXY_STATUS=$(systemctl is-active haproxy)
Check OpenVPN backend connectivity
OVPN1_CHECK=$(nc -uz 203.0.113.10 1194 && echo "UP" || echo "DOWN")
OVPN2_CHECK=$(nc -uz 203.0.113.11 1194 && echo "UP" || echo "DOWN")
Get connected client count from HAProxy stats
CLIENT_COUNT=$(curl -s http://localhost:8080/stats | grep -c "ESTABLISHED" || echo "0")
echo "$DATE: VIP=$VIP_STATUS HAProxy=$HAPROXY_STATUS OVPN1=$OVPN1_CHECK OVPN2=$OVPN2_CHECK Clients=$CLIENT_COUNT" >> $LOG_FILE
Make executable and set up cron job.
sudo chmod 755 /usr/local/bin/monitor-ovpn-cluster.sh
echo "/5 * /usr/local/bin/monitor-ovpn-cluster.sh" | sudo crontab -
Configure shared certificate synchronization
Set up automated certificate sync
Create a systemd service to automatically synchronize certificates between OpenVPN nodes.
[Unit]
Description=OpenVPN Certificate Synchronization
After=network.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/bin/rsync -av --delete /etc/openvpn/certs/ 203.0.113.11:/etc/openvpn/certs/
ExecStart=/usr/bin/rsync -av --delete /etc/openvpn/easy-rsa/pki/ 203.0.113.11:/etc/openvpn/easy-rsa/pki/
Create a timer to run the sync every hour.
[Unit]
Description=Run certificate sync every hour
Requires=ovpn-cert-sync.service
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
Enable the sync timer.
sudo systemctl daemon-reload
sudo systemctl enable ovpn-cert-sync.timer
sudo systemctl start ovpn-cert-sync.timer
Verify your setup
Test each component of your high availability OpenVPN cluster.
# Check OpenVPN services on both nodes
sudo systemctl status openvpn@server
Verify HAProxy is balancing traffic
curl -s http://203.0.113.100:8080/stats
Check keepalived status and virtual IP
sudo systemctl status keepalived
ip addr show | grep 203.0.113.100
Test OpenVPN connectivity through load balancer
sudo /usr/local/bin/create-ovpn-client.sh testuser
Monitor cluster health
tail -f /var/log/ovpn-cluster-health.log
Check certificate synchronization
sudo systemctl status ovpn-cert-sync.timer
Configure cluster monitoring and alerting
Install monitoring components
For comprehensive cluster monitoring, consider integrating with Prometheus and Grafana or setting up Nagios monitoring.
#!/bin/bash
ALERT_EMAIL="admin@example.com"
SMTP_SERVER="mail.example.com"
Check if both OpenVPN servers are down
OVPN1_DOWN=$(! nc -uz 203.0.113.10 1194)
OVPN2_DOWN=$(! nc -uz 203.0.113.11 1194)
if [ "$OVPN1_DOWN" = "true" ] && [ "$OVPN2_DOWN" = "true" ]; then
echo "CRITICAL: All OpenVPN servers are down!" | mail -s "OpenVPN Cluster Alert" -S smtp=$SMTP_SERVER $ALERT_EMAIL
fi
Check keepalived failover
VIP_COUNT=$(ip addr show | grep -c 203.0.113.100)
if [ "$VIP_COUNT" -eq 0 ]; then
echo "CRITICAL: No server holds the virtual IP!" | mail -s "Keepalived Alert" -S smtp=$SMTP_SERVER $ALERT_EMAIL
fi
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Clients can't connect to VIP | Keepalived not running or misconfigured | sudo systemctl status keepalived and check logs |
| Certificate mismatch errors | Certificates not synchronized between nodes | Run sudo systemctl start ovpn-cert-sync.service |
| HAProxy shows backends as down | OpenVPN management interface not accessible | Check management 127.0.0.1 7505 in OpenVPN config |
| Failover not working | VRRP packets blocked by firewall | Allow VRRP protocol: iptables -A INPUT -p vrrp -j ACCEPT |
| Split brain scenario | Network partition between keepalived nodes | Check network connectivity and increase advert_int |
| Load balancing uneven | Different connection handling on OpenVPN nodes | Verify identical configs and check server performance |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Script configuration
SCRIPT_NAME="openvpn-ha-cluster-setup"
OPENVPN_PORT=1194
VPN_SUBNET_PRIMARY="10.8.0.0"
VPN_SUBNET_SECONDARY="10.8.1.0"
VPN_NETMASK="255.255.255.0"
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_step() {
echo -e "${BLUE}[$1]${NC} $2"
}
# Usage function
usage() {
echo "Usage: $0 <node-type> [secondary-ip]"
echo " node-type: 'primary', 'secondary', or 'loadbalancer'"
echo " secondary-ip: IP of secondary node (required for primary setup)"
echo ""
echo "Examples:"
echo " $0 primary 203.0.113.11"
echo " $0 secondary"
echo " $0 loadbalancer"
exit 1
}
# Cleanup function
cleanup() {
print_error "Script failed. Cleaning up..."
systemctl stop openvpn-server@server 2>/dev/null || true
systemctl stop keepalived 2>/dev/null || true
systemctl stop haproxy 2>/dev/null || true
}
# Set trap for cleanup on error
trap cleanup ERR
# Check arguments
if [ $# -lt 1 ]; then
usage
fi
NODE_TYPE="$1"
SECONDARY_IP="${2:-}"
if [ "$NODE_TYPE" = "primary" ] && [ -z "$SECONDARY_IP" ]; then
print_error "Secondary IP is required for primary node setup"
usage
fi
if [[ ! "$NODE_TYPE" =~ ^(primary|secondary|loadbalancer)$ ]]; then
print_error "Invalid node type. Must be 'primary', 'secondary', or 'loadbalancer'"
usage
fi
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
exit 1
fi
# Auto-detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
NOBODY_GROUP="nogroup"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
NOBODY_GROUP="nobody"
# Enable EPEL for older versions
if command -v dnf &> /dev/null; then
dnf install -y epel-release 2>/dev/null || true
fi
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
NOBODY_GROUP="nobody"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
else
print_error "Cannot detect distribution. /etc/os-release not found."
exit 1
fi
print_status "Detected distribution: $ID"
print_status "Setting up OpenVPN HA cluster node type: $NODE_TYPE"
# Step 1: Update system packages
print_step "1/8" "Updating system packages..."
eval "$PKG_UPDATE"
# Step 2: Install required packages based on node type
print_step "2/8" "Installing required packages..."
if [ "$NODE_TYPE" = "loadbalancer" ]; then
$PKG_INSTALL haproxy keepalived rsync
else
$PKG_INSTALL openvpn easy-rsa iptables-persistent rsync
# Create easy-rsa directory
mkdir -p /etc/openvpn/easy-rsa
fi
# Step 3: Configure OpenVPN nodes (primary and secondary only)
if [ "$NODE_TYPE" != "loadbalancer" ]; then
print_step "3/8" "Configuring OpenVPN..."
if [ "$NODE_TYPE" = "primary" ]; then
# Set up Certificate Authority on primary node
cd /etc/openvpn/easy-rsa
# Initialize PKI
/usr/share/easy-rsa/easyrsa init-pki
# Build CA (non-interactive)
echo "ca" | /usr/share/easy-rsa/easyrsa build-ca nopass
# Generate server certificate
echo "server" | /usr/share/easy-rsa/easyrsa gen-req server nopass
echo "yes" | /usr/share/easy-rsa/easyrsa sign-req server server
# Generate DH parameters
/usr/share/easy-rsa/easyrsa gen-dh
# Generate TLS auth key
openvpn --genkey secret ta.key
# Create shared certificate storage
mkdir -p /etc/openvpn/certs
cp pki/ca.crt /etc/openvpn/certs/
cp pki/issued/server.crt /etc/openvpn/certs/
cp pki/private/server.key /etc/openvpn/certs/
cp pki/dh.pem /etc/openvpn/certs/
cp ta.key /etc/openvpn/certs/
# Set proper permissions
chmod 644 /etc/openvpn/certs/*.crt /etc/openvpn/certs/*.pem
chmod 600 /etc/openvpn/certs/server.key /etc/openvpn/certs/ta.key
chown -R root:root /etc/openvpn/certs/
# Copy certificates to secondary server
print_status "Copying certificates to secondary server ($SECONDARY_IP)..."
rsync -av /etc/openvpn/certs/ root@"$SECONDARY_IP":/etc/openvpn/certs/
fi
# Step 4: Create OpenVPN server configuration
print_step "4/8" "Creating OpenVPN server configuration..."
VPN_SUBNET="$VPN_SUBNET_PRIMARY"
if [ "$NODE_TYPE" = "secondary" ]; then
VPN_SUBNET="$VPN_SUBNET_SECONDARY"
fi
cat > /etc/openvpn/server.conf << EOF
port $OPENVPN_PORT
proto udp
dev tun
ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/server.crt
key /etc/openvpn/certs/server.key
dh /etc/openvpn/certs/dh.pem
tls-auth /etc/openvpn/certs/ta.key 0
server $VPN_SUBNET $VPN_NETMASK
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
cipher AES-256-CBC
user nobody
group $NOBODY_GROUP
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
management 127.0.0.1 7505
EOF
# Step 5: Create log directories and set permissions
print_step "5/8" "Setting up logging directories..."
mkdir -p /var/log/openvpn
chown nobody:$NOBODY_GROUP /var/log/openvpn
chmod 755 /var/log/openvpn
# Step 6: Enable IP forwarding
print_step "6/8" "Enabling IP forwarding..."
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
# Step 7: Configure firewall rules
print_step "7/8" "Configuring firewall rules..."
# Configure iptables rules
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o eth0 -j MASQUERADE
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A INPUT -p udp --dport $OPENVPN_PORT -j ACCEPT
# Save iptables rules
if [ "$PKG_MGR" = "apt" ]; then
iptables-save > /etc/iptables/rules.v4
else
# For RHEL-based systems
if command -v firewall-cmd &> /dev/null; then
firewall-cmd --permanent --add-port=$OPENVPN_PORT/udp
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload
fi
fi
# Step 8: Enable and start OpenVPN service
print_step "8/8" "Starting OpenVPN service..."
systemctl enable openvpn-server@server
systemctl start openvpn-server@server
else
# Load balancer configuration
print_step "3/8" "Configuring HAProxy..."
cat > /etc/haproxy/haproxy.cfg << EOF
global
daemon
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
user haproxy
group haproxy
defaults
mode tcp
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen openvpn_cluster
bind *:$OPENVPN_PORT
mode tcp
balance roundrobin
server openvpn1 203.0.113.10:$OPENVPN_PORT check
server openvpn2 203.0.113.11:$OPENVPN_PORT check
EOF
print_step "4/8" "Configuring Keepalived..."
cat > /etc/keepalived/keepalived.conf << EOF
vrrp_script chk_haproxy {
script "/bin/kill -0 \`cat /var/run/haproxy.pid\`"
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 $(openssl rand -base64 8)
}
virtual_ipaddress {
203.0.113.100/24
}
track_script {
chk_haproxy
}
}
EOF
print_step "5/8" "Starting HAProxy and Keepalived..."
systemctl enable haproxy keepalived
systemctl start haproxy keepalived
print_step "6/8" "Configuring firewall for load balancer..."
iptables -A INPUT -p udp --dport $OPENVPN_PORT -j ACCEPT
iptables -A INPUT -p vrrp -j ACCEPT
if [ "$PKG_MGR" = "apt" ]; then
iptables-save > /etc/iptables/rules.v4
else
if command -v firewall-cmd &> /dev/null; then
firewall-cmd --permanent --add-port=$OPENVPN_PORT/udp
firewall-cmd --permanent --add-protocol=vrrp
firewall-cmd --reload
fi
fi
print_step "7/8" "Load balancer configuration complete"
print_step "8/8" "Verifying services..."
fi
# Verification
print_status "Verifying installation..."
if [ "$NODE_TYPE" != "loadbalancer" ]; then
if systemctl is-active --quiet openvpn-server@server; then
print_status "✓ OpenVPN service is running"
else
print_error "✗ OpenVPN service failed to start"
exit 1
fi
if [ -f /etc/openvpn/certs/ca.crt ]; then
print_status "✓ Certificate files are present"
else
print_error "✗ Certificate files missing"
exit 1
fi
else
if systemctl is-active --quiet haproxy; then
print_status "✓ HAProxy service is running"
else
print_error "✗ HAProxy service failed to start"
exit 1
fi
if systemctl is-active --quiet keepalived; then
print_status "✓ Keepalived service is running"
else
print_error "✗ Keepalived service failed to start"
exit 1
fi
fi
print_status "OpenVPN HA cluster $NODE_TYPE node setup completed successfully!"
if [ "$NODE_TYPE" = "primary" ]; then
print_warning "Remember to run this script on the secondary node with: $0 secondary"
print_warning "Client certificates can be generated with: /usr/share/easy-rsa/easyrsa gen-req client nopass"
fi
Review the script before running. Execute with: bash install.sh