如何搭建支持多站点配对独立通信的中心式OpenVPN基础设施
Hey there! Let’s break this down for you—your core requirements make total sense, and there’s a solid OpenVPN-based setup that can check all your boxes. First, let’s validate your initial idea, then walk through exactly how to build this out.
Your proposed setup is completely feasible—OpenVPN is designed to handle exactly this kind of scenario: NAT traversal for mobile clients, site-specific access control, and peer-to-peer communication within isolated groups. The key pieces you’ve identified (site pairing, isolation, NAT-aware connectivity) align perfectly with OpenVPN’s capabilities, so you’re on the right track.
We’ll build a hub-and-spoke model with a central OpenVPN server, paired with subnet segmentation and firewall rules to enforce site isolation. Here’s the breakdown:
- Central Server Role: A Linux-based OpenVPN server with a public static IP (this is non-negotiable—mobile clients need a fixed endpoint to connect to through their carrier NAT). We’ll use UDP mode for better NAT traversal and performance.
- Site Isolation: Assign a unique VPN subnet to each site (e.g.,
10.8.1.0/24for Site A,10.8.2.0/24for Site B). All fixed and mobile clients for a site will live in this subnet. - NAT Traversal: Configure mobile clients to use
nobind(to avoid fixed port conflicts with carrier NAT) and persistence settings to maintain connections through network switches.
1. Central Server Setup (Linux)
Install Dependencies
# Debian/Ubuntu apt update && apt install openvpn easy-rsa -y # RHEL/CentOS/Rocky Linux yum install epel-release -y && yum install openvpn easy-rsa -y
Generate Certificates & Keys
We’ll use easy-rsa to create a CA, server cert, and client certs (one per client, grouped by site for clarity):
- Initialize the PKI:
make-cadir ~/openvpn-ca && cd ~/openvpn-ca ./easyrsa init-pki ./easyrsa build-ca nopass - Generate server cert/key:
./easyrsa gen-req server nopass ./easyrsa sign-req server server - Generate client certs (repeat for each client, e.g.,
siteA-fixed1,siteA-mobile1):./easyrsa gen-req siteA-fixed1 nopass ./easyrsa sign-req client siteA-fixed1 - Generate Diffie-Hellman parameters:
./easyrsa gen-dh - Copy all keys/certs to the OpenVPN directory:
mkdir -p /etc/openvpn/keys cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem /etc/openvpn/keys/ # Copy client certs/keys to respective clients via secure transfer (e.g., scp)
Server Configuration File
Create /etc/openvpn/server.conf with these settings:
port 1194 proto udp dev tun ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/server.crt key /etc/openvpn/keys/server.key dh /etc/openvpn/keys/dh.pem server 10.8.0.0 255.255.0.0 # Base subnet for all sites ifconfig-pool-persist ipp.txt push "route 10.8.0.0 255.255.0.0" client-config-dir /etc/openvpn/ccd # Per-client configs for site subnets keepalive 10 120 cipher AES-256-CBC user nobody group nogroup persist-key persist-tun status openvpn-status.log verb 3
Per-Site Client Configs (CCD)
Create a ccd directory to assign clients to their site subnets:
mkdir /etc/openvpn/ccd
For a Site A mobile client (siteA-mobile1), create /etc/openvpn/ccd/siteA-mobile1:
ifconfig-push 10.8.1.10 255.255.255.0 # Assign to Site A's subnet push "route 10.8.1.0 255.255.255.0"
For a Site A fixed client (siteA-fixed1), create /etc/openvpn/ccd/siteA-fixed1:
ifconfig-push 10.8.1.20 255.255.255.0 push "route 10.8.1.0 255.255.255.0"
Repeat this for all clients across all sites, assigning unique subnets (e.g., 10.8.2.0/24 for Site B).
Firewall Rules for Isolation
Enable IP forwarding first:
echo 1 > /proc/sys/net/ipv4/ip_forward # Make it permanent echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p
Add iptables rules to enforce site isolation (repeat for each site):
# Allow Site A clients to communicate with each other iptables -A FORWARD -s 10.8.1.0/24 -d 10.8.1.0/24 -j ACCEPT # Block Site A from communicating with other VPN sites iptables -A FORWARD -s 10.8.1.0/24 -d 10.8.0.0/16 -j DROP iptables -A FORWARD -s 10.8.0.0/16 -d 10.8.1.0/24 -j DROP # Allow VPN traffic in/out iptables -A FORWARD -i tun0 -j ACCEPT iptables -A FORWARD -o tun0 -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Save the rules to persist across reboots:
# Debian/Ubuntu iptables-save > /etc/iptables/rules.v4 # RHEL/CentOS service iptables save
Start the Server
systemctl start openvpn@server systemctl enable openvpn@server
2. Mobile Client Setup (Linux)
Install OpenVPN
Same as the server (use the appropriate package manager command).
Client Configuration File
Create /etc/openvpn/client/siteA-mobile.conf (replace placeholders with your server details):
client dev tun proto udp remote YOUR_SERVER_PUBLIC_IP 1194 resolv-retry infinite nobind # Critical for NAT traversal persist-key persist-tun # Maintain connection through network switches ca ca.crt cert siteA-mobile1.crt key siteA-mobile1.key cipher AES-256-CBC verb 3
Start the Client
systemctl start openvpn-client@siteA-mobile systemctl enable openvpn-client@siteA-mobile
3. Fixed Client Setup (Linux)
The setup is identical to mobile clients—just use the fixed client’s cert/key and ensure it’s assigned to the same site subnet via the CCD config on the server. If the fixed site has no public IP, it will connect to the central server the same way mobile clients do.
- Test intra-site communication: Ping a Site A fixed client from a Site A mobile client (and vice versa)—it should work.
- Test inter-site isolation: Try pinging a Site B client from a Site A client—it should fail.
- Test mobile network resilience: Switch mobile networks (e.g., 4G to Wi-Fi) and confirm the VPN reconnects automatically.
内容的提问来源于stack exchange,提问作者darkmattercoder

