This episode covers horizontal scaling: multiple OpenVPN instances for segmentation and capacity, learn-address scripting for address synchronization, and high availability with keepalived and HAProxy in front of many servers.

Episode 11 introduced ways to grow capacity: multiple instances and round-robin DNS. Episode 17 matures this into a multi-server and cluster architecture worthy of production — with real failover, not just load spreading.
You will learn to run multiple OpenVPN instances for segmentation and capacity, use learn-address scripting to keep address tables synchronized across servers, and place keepalived and HAProxy in front of many servers for high availability with automatic failover.
This is the episode where OpenVPN turns from a single service into infrastructure. After this episode, you can build a VPN that stays online even when one server dies.
Running multiple OpenVPN instances isn't just about capacity — it's about segmentation. A common example: one instance for employees, one for external partners, and one dedicated to site-to-site. Each instance has its own port, protocol, or subnet:
systemctl enable openvpn-server@staff
systemctl enable openvpn-server@partner
systemctl enable openvpn-server@s2s
systemctl start openvpn-server@staff
systemctl start openvpn-server@partner
systemctl start openvpn-server@s2sEach instance has its own configuration in /etc/openvpn/server/, its own CA or policy, and its own separate VPN subnet. If one instance is attacked or breaks, the others are unaffected.
To distribute clients among instances, combine the management interface and scripting. Each instance can invoke a script when a new client comes in and direct it to the least-loaded instance. This pattern mimics the connection broker discussed in episode 11, now realized in practice.
When many servers share one virtual VPN subnet, conflicts can happen: two servers allocate the same address, or a server doesn't know that a subnet is routed through another server. learn-address answers this by invoking a script every time an address changes.
learn-address /etc/openvpn/scripts/learn-address.sh
script-security 2learn-address /etc/openvpn/scripts/learn-address.sh invokes the script on every add, update, or delete operation against an address known to the server. This information can be used to prevent address duplication or spread the table to other nodes.
The learn-address.sh script can write to a central directory — for example Redis or a shared NFS file — so all servers read the same information. When one server adds an address, the others know immediately. This is the foundation of a truly address-aware cluster.
Keepalived provides a virtual IP (VIP) that can move automatically between servers when one dies. Clients keep using the same address; only the infrastructure behind it changes:
vrrp_instance VPN {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
virtual_ipaddress {
203.0.113.10
}
}virtual_router_id 51 and priority 100 determine the master and backup order. The server with the highest priority holds the VIP; when it dies, the backup takes over within seconds. Clients don't need to know anything about this transition.
VPN is different from web services: client sessions are bound to a specific server through connection state. To ease failover, limit session validity and make clients reconnect automatically — OpenVPN does this by default with --connect-retry.
Make sure the firewall moves too: iptables rules must be applied on the server that becomes master, or run through a script triggered by the VRRP transition. Keepalived can run notify scripts on state transitions.
HAProxy is famous for HTTP, but modern versions support UDP proxying — exactly what OpenVPN needs. HAProxy receives connections on one frontend and distributes them to many backend servers:
frontend openvpn-udp
bind :::1194
mode tcp
use_backend vpn_servers
backend vpn_servers
balance leastconn
server vpn1 10.0.0.11:1194 check
server vpn2 10.0.0.12:1194 checkbalance leastconn directs new connections to the server with the fewest connections. Automatic health checks remove a downed server from the pool, and reconnecting clients move to a healthy server.
UDP proxying in HAProxy works at layer 4: it forwards packets without opening their contents. This is perfect for OpenVPN, but it means there's no session affinity — every reconnect can land on a different server. For normal use with automatic reconnect, this isn't a big deal.
A complete production architecture stacks layer upon layer: HAProxy as the entry point to distribute load, keepalived giving a VIP to HAProxy itself, and behind it many OpenVPN instances sharing a central address directory via learn-address.
Each layer has a single responsibility and can scale on its own. A failure in one layer doesn't collapse the whole — this is the real value of a cluster architecture.
Key takeaways:
learn-address synchronizes address tables across servers.In the next episode, episode 18, we will discuss performance tuning and benchmarking — optimizing buffers with sndbuf and rcvbuf, adjusting MTU with tun-mtu, fragment, and mssfix, and measuring throughput and latency with iperf3. After this episode, you can prove your VPN server's performance numbers.