How to Build a Multi-Site Proxmox SDN with WireGuard Fabric in VE 9.2

Updated on Oct 6, 2026
Mila H
16 MINS READ
Table of Contents
Proxmox VE 9.2 WireGuard Fabric

Proxmox VE 9.2 adds WireGuard as a native SDN fabric type. This means you can now build an encrypted tunnel between your Proxmox nodes from the web UI, without writing wg0.conf files manually. In this guide, you will build a multi-site Proxmox SDN with WireGuard fabric, so VMs in different data centers can talk on one private network.

What You Will Build

This lab shows a multi-site Proxmox SDN with WireGuard fabric in practice: 

  • Three Proxmox nodes at three sites join one cluster.
  • WireGuard links them with a private encrypted network (10.255.0.0/24).
  • A VXLAN zone sends VM traffic through that network.
  • VMs at every site share one tenant network (10.10.10.0/24), and the internet sees only WireGuard packets.
Item Site A Site B Site C
Node name pve-a pve-b pve-c
Public IP (example) 203.0.113.11 198.51.100.12 192.0.2.13
WireGuard IP (wg0) 10.255.0.1/24 10.255.0.2/24 10.255.0.3/24

These public IPs are examples. Replace them with your real server IPs everywhere. The traffic takes this path:

Bash
VM (10.10.10.11, MTU 1370)  -> VNet "tenant1" (VXLAN, UDP 4789)    -> wg0 (WireGuard fabric, MTU 1420)      -> public NIC (UDP 51820, encrypted)        -> internet / provider network

Why Use a Multi-Site Proxmox SDN with WireGuard Fabric

VXLAN lets VMs on different hosts act like they are on the same switch. But VXLAN has no encryption. When you join sites with VXLAN, you should first build a secure link, such as a site-to-site VPN.

Before Proxmox 9.2, you had to build that VPN manually on every node. Now the WireGuard fabric does it for you. Proxmox creates the keys, writes the interface settings, and adds the routes. It stores each private key in /etc/pve/priv/wg-keys.cfg. Use this design when:

  • Your nodes are in different data centers or at different providers.
  • The network between nodes is not trusted.
  • You do not have a private VLAN or private link between sites.
  • You do not want to expose VXLAN (UDP 4789) to the internet.

Don't use it if all your nodes are in one rack on a network you trust. Plain VXLAN uses less CPU there. In one test, WireGuard cut speed by about 7 to 8 percent. CPU use jumped from 1.5% to 14%. Keep some CPU room for busy tenants.

Important Note: WireGuard itself does not do dynamic routing. It is only the encrypted transport. Pair it with OSPF or BGP if you need dynamic routes. The WireGuard fabric is also not a general VPN for phones and laptops. It is an underlay for overlay networks like VXLAN.

Requirements and Planning

Check these items before you start your multi-site Proxmox SDN with WireGuard fabric:

  • Three or two Proxmox VE 9.2 nodes, all updated.
  • Each node has a public IP, or at least an IP that the other nodes can reach.
  • UDP port 51820 is open between all nodes' public IPs.
  • A working Proxmox cluster. The fabric and SDN settings live in the cluster-wide /etc/pve/sdn folder, so the nodes must be in one cluster.
  • Root SSH access to all nodes.

About the cluster: Corosync needs a fast and stable network. A cluster spread over many sites can break if the delay is high. Before you do this in production, read our guide on Proxmox cluster quorum.

Then, plan your address ranges so they never overlap:

Purpose Range
WireGuard fabric (underlay) 10.255.0.0/24
Tenant network (overlay) 10.10.10.0/24
Real public networks Must not overlap with the two above

Names in this guide are short on purpose. Fabric names, interface names, and VNet IDs are limited to 8 characters in Proxmox.

Then, use the command below on every node to check your Proxmox version:

Bash
pveversion

You should see pve-manager/9.2.x. If not, you must update it:

Bash
apt updateapt full-upgrade -y

Reboot if a new kernel was installed, then check again. Next, use the command below to check the cluster on every node:

Bash
pvecm status

Look for Quorate: Yes and the number of nodes you expect. If you have no cluster yet, create it on the first node, and join the others:

Bash
pvecm create sitecluster# on pve-b and pve-c:pvecm add <IP-of-pve-a>

Step 1: Install the WireGuard Tools

The fabric needs the wireguard-tools package on every node. Run the commands below on all nodes and check that it works:

Bash
apt updateapt install wireguard-tools -ywg --version

Then, make sure SDN can write its network files. The docs require this line at the end of /etc/network/interfaces on all nodes. Check for it:

Bash
tail -n 5 /etc/network/interfaces

If the line source /etc/network/interfaces.d/* is missing, make a backup and add it:

Bash
cp /etc/network/interfaces /etc/network/interfaces.bakecho 'source /etc/network/interfaces.d/*' >> /etc/network/interfaces

On a fresh Proxmox VE install, this line is already there.

Step 2: Open the Firewall Ports

Firewall rules for a multi-site Proxmox SDN with WireGuard fabric are short. Two things must be allowed:

  1. UDP 51820 on the public side, between node public IPs. This carries the encrypted WireGuard packets.
  2. UDP 4789 on the wg0 interface only. This is VXLAN, and it travels inside the tunnel.

Also, you should check your provider's network firewall or security group, and open UDP 51820 there too.

If you use the Proxmox firewall, open the cluster rules file:

Bash
nano /etc/pve/firewall/cluster.fw

Add these lines under the [RULES] section; you can create the section if it does not exist. Replace the IPs with your real public IPs:

Bash
[RULES]IN ACCEPT -source 203.0.113.11,198.51.100.12,192.0.2.13 -p udp -dport 51820 -log nolog # WireGuard fabricIN ACCEPT -i wg0 -p udp -dport 4789 -log nolog # VXLAN inside the tunnel

Save the file. Because /etc/pve is shared, the rules reach all nodes. The Proxmox firewall is off by default. If you turn it on later, do it carefully so that you do not lock yourself out of SSH and port 8006.

Do not open UDP 4789 on the public interface. Only wg0 needs it.

Step 3: Create the WireGuard Fabric

This is the core of the multi-site Proxmox SDN with WireGuard fabric. Do it in the web UI on any one node. The settings are saved cluster-wide. 

Create the Fabric

  1. Go to Datacenter > SDN > Fabrics.
  2. Click Add Fabric and choose WireGuard.
  3. Set Name to wgsites.
  4. Set Persistent Keepalive to 25. This sends a small packet every 25 seconds. It helps when a stateful firewall or NAT sits between the sites.
  5. Click Create.

Add the Nodes

Add each node to the fabric with the + button. For a WireGuard fabric, choose the internal node type because these are Proxmox nodes. Fill in:

Field pve-a pve-b pve-c
Endpoint 203.0.113.11 198.51.100.12 192.0.2.13
Allowed IPs 10.255.0.1/32 10.255.0.2/32 10.255.0.3/32
  • Endpoint is the IP or hostname that the other nodes use to reach this node. Proxmox combines it with the Listen Port from the interface, such as 203.0.113.11:51820.
  • Allowed IPs is a list of networks. Other nodes use it as the AllowedIPs setting for this peer. It works as a filter for incoming packets and as the route for outgoing packets.

We use only the single /32 address of each node. That keeps the tunnel tight; a node can only send traffic for its own WireGuard address.

Add the WireGuard Interface on Each Node

For each node in the fabric, you should add an interface:

Field pve-a pve-b pve-c
Name wg0 wg0 wg0
IP 10.255.0.1/24 10.255.0.2/24 10.255.0.3/24
Listen Port 51820 51820 51820
Peers pve-b, pve-c pve-a, pve-c pve-a, pve-b

When you save the interface, Proxmox creates a private key for it and stores it in /etc/pve/priv/wg-keys.cfg. The public key is stored in the fabric config and shown in the UI. You never copy keys manually.

The fabric also creates routes. For every peer's Allowed IPs, it adds a route through the WireGuard interface. For a Proxmox peer, it also adds the peer interface IP as a host route.

Apply the Changes and Verify Tunnel

Changes stay in a pending state until you apply them. Go to Datacenter > SDN and click Apply. Then, on each node, run:

Bash
wg show

For each peer, you should see the latest handshake line with a recent time and transfer counters. If a handshake is missing, you must send a ping first, because WireGuard only connects when traffic flows:

Bash
ping -c 3 10.255.0.2ping -c 3 10.255.0.3

Check the routes with the commands below:

Bash
ip route | grep wg0ip -br addr show wg0

You should see routes for the other nodes through wg0, and your own 10.255.0.x/24 address on the interface.

Step 4: Fix the MTU on wg0

This step is important. MTU is the number one problem in a multi-site Proxmox SDN with WireGuard fabric, so do not skip it.

MTU is the biggest packet size an interface can send without splitting it. Every tunnel layer adds bytes, so the inside network needs a smaller MTU:

Layer MTU Why
Public NIC 1500 Normal Ethernet
wg0 (WireGuard) 1420 WireGuard adds up to 80 bytes
VXLAN zone and VM NICs 1370 VXLAN adds 50 bytes

The math: 1500 - 80 = 1420, and 1420 - 50 = 1370.

First, check the current value on each node:

Bash
ip link show wg0

If it says mtu 1500, set it in the main network file:

Bash
nano /etc/network/interfaces

Add this block above the source /etc/network/interfaces.d/* line:

Bash
iface wg0 inet manual    mtu 1420

Apply it and check with the following commands:

Bash
ifreload -aip link show wg0

You should now see mtu 1420. Do this on all nodes. After every future SDN Apply, check ip link show wg0 again. If the value goes back to 1500, check that the block is still in /etc/network/interfaces.

For a quick one-time fix, you can also run the command below:

Bash
ip link set dev wg0 mtu 1420

Now test the tunnel with a "do not split" ping. 1392 bytes of data plus 28 bytes of headers equals 1420:

Bash
ping -M do -s 1392 -c 3 10.255.0.2

If this works, the tunnel MTU is correct. If you get "message too long", the MTU on wg0 is too high or too low somewhere; recheck the table above.

Step 5: Create the VXLAN Zone, VNet, and Subnet

Now you must build the tenant network on top of the encrypted tunnel. The overlay of your multi-site Proxmox SDN with WireGuard fabric uses VXLAN.

  • A zone is a separate network area and defines the technology (here: VXLAN).
  • A VNet is a virtual network inside a zone. On each node, it shows up as a Linux bridge.
  • A subnet is an IP range inside a VNet.

Option A: Use the web UI

Use this option if you prefer a GUI option. You build the zone, VNet, and subnet in the Proxmox web UI. It takes a few minutes and is easy to check.

  1. Go to Datacenter > SDN > Zones > Add > VXLAN.
  2. ID: mszone
  3. Nodes: select pve-a, pve-b, pve-c
  4. Peers Address List: 10.255.0.1,10.255.0.2,10.255.0.3
  5. MTU: 1370
  6. Click Create.

The peer list must use the WireGuard addresses, not the public IPs. This pushes all VXLAN traffic into the tunnel. Include every node in the list, also the local one.

Proxmox also lets a VXLAN zone take its peers from an SDN fabric instead of a manual list. The manual list is shown here because it is easy to check and has been tested by others over WireGuard. Then, you must create the VNet:

  • Go to Datacenter > SDN > VNets > Create.
  • Name: tenant1
  • Zone: mszone
  • Tag: 100010 (the VXLAN network ID)
  • Click Create.

Next, add the subnet: select tenant1, click Create in the Subnets panel, and set Subnet to 10.10.10.0/24.

Option B: Use the command line

Use this option if you prefer the terminal. It builds the same zone, VNet, and subnet with pvesh commands. Run them on one node only. Proxmox shares the settings with the whole cluster.

Bash
pvesh create /cluster/sdn/zones \  --zone mszone --type vxlan \  --peers 10.255.0.1,10.255.0.2,10.255.0.3 \  --mtu 1370 --nodes pve-a,pve-b,pve-c pvesh create /cluster/sdn/vnets --vnet tenant1 --zone mszone --tag 100010 pvesh create /cluster/sdn/vnets/tenant1/subnets \  --subnet 10.10.10.0/24 --type subnet

Apply the SDN Changes and Verify

In the UI, go to Datacenter > SDN and click Apply. Or use the CLI:

Bash
pvesh set /cluster/sdn

To verify the changes, run the commands below on every node:

Bash
ip -br link show tenant1ip -d link show type vxlan

You should see the tenant1 bridge and a VXLAN device with the MTU you set. The files behind the config are in the shared folder:

Bash
ls /etc/pve/sdncat /etc/pve/sdn/zones.cfg

Step 6: Create Test Guests

Create one container on pve-a and one on pve-b, both on the tenant1 bridge. First, download a template; you should run it once per node that needs it:

Bash
pveam updatepveam available --section system | grep debian

Pick a Debian template name from that list and download it:

Bash
pveam download local <template-name>

Create the container on pve-a, change the storage names if yours differ:

Bash
pct create 201 local:vztmpl/<template-name> \  --hostname t1-a --memory 512 --rootfs local-lvm:4 \  --net0 name=eth0,bridge=tenant1,ip=10.10.10.11/24,mtu=1370 \  --unprivileged 1 --password 'ChangeMe-Now1' --start 1

Also, create the second one on pve-b with the command below:

Bash
pct create 202 local:vztmpl/<template-name> \  --hostname t1-b --memory 512 --rootfs local-lvm:4 \  --net0 name=eth0,bridge=tenant1,ip=10.10.10.12/24,mtu=1370 \  --unprivileged 1 --password 'ChangeMe-Now1' --start 1

Use a strong password, or add an SSH key instead, in a real setup.

If you use VMs instead, set the NIC bridge to tenant1, then set the MTU inside the guest to 1370:

Bash
ip link set dev eth0 mtu 1370

For a permanent setting, put the MTU in the guest's network file, for example, mtu 1370 in /etc/network/interfaces on Debian.

Step 7: Test Reachability and MTU

In this step, you should check that VMs at different sites can reach each other through the tunnel.

You also need to test the MTU so that large packets pass without problems, and confirm that the internet sees only encrypted WireGuard traffic. From container 201, on pve-a, run:

Bash
pct exec 201 -- ping -c 3 10.10.10.12

Now test the full MTU. 1342 bytes of data plus 28 bytes of headers equals 1370:

Bash
pct exec 201 -- ping -M do -s 1342 -c 3 10.10.10.12pct exec 201 -- ping -M do -s 1343 -c 2 10.10.10.12

The first ping must work. The second should fail with "message too long". That proves the real limit is exactly 1370.

Now you must prove that the internet sees only WireGuard. On pve-a, replace vmbr0 with your public interface name and start a capture, then ping from the container in another terminal:

Bash
tcpdump -ni vmbr0 'udp port 4789'

This should show no packets. Now check the WireGuard port:

Bash
tcpdump -ni vmbr0 'udp port 51820'

You should see UDP packets to and from the other sites. Plain VXLAN packets on UDP 4789 never leave the node, so the underlay is protected.

Also, check bandwidth with iperf3. Install it in both containers with apt install -y iperf3, then run:

Bash
pct exec 202 -- iperf3 -spct exec 201 -- iperf3 -c 10.10.10.12

While the test runs, watch CPU on the host with top. Encryption uses CPU, so this tells you how much room you have.

Step 8: Route the Tenant Networks

In this step, you learn how traffic moves between your sites and tenant networks. We look at the routes Proxmox adds for you, how VMs talk across sites, and how to give them internet access or a gateway.

Underlay routes (done for you). The fabric adds routes for the WireGuard addresses automatically. Check with ip route | grep wg0. If you want to add your own routes, turn on Skip Route Generation on the peer, then add static routes yourself. 

Tenant network (L2 stretch). A VXLAN zone stretches one layer 2 network across all sites, so 10.10.10.11 and 10.10.10.12 talk directly. No router is needed between them. Note that a VXLAN zone does not put a gateway on the VNet. Only the layer 3 zone types (Simple and EVPN) deploy the subnet gateway on the VNet.

Internet access and other networks. You have two simple choices:

  1. Run a small gateway VM, for example OPNsense, pfSense, or a Linux router, on the VNet. Give it the 10.10.10.1 address, and let all tenant VMs use it as their default gateway.
  2. Use an EVPN zone for a true routed design with anycast gateways and several tenants. EVPN needs the FRR packages (apt install frr frr-pythontools and systemctl enable frr), an EVPN controller, and the same MTU rule (1370). The WireGuard addresses can be used as the controller peers. This is a bigger project, so test it in a lab first.

To keep two tenants apart, make a second VNet in the same zone with a different tag, for example, tenant2 with tag 100020 and subnet 10.10.20.0/24. Different VXLAN IDs are separate layer 2 networks, so they do not mix.

Firewall Rules for Proxmox SDN with WireGuard

Firewall rules for this setup are short. You open one port for WireGuard on the public side, and one for VXLAN inside the tunnel. This section shows what to allow, where to allow it, and how to keep your tenant networks safe.

What Where Rule
WireGuard Public NIC, all nodes Allow UDP 51820 only from the other node IPs
VXLAN wg0 only Allow UDP 4789 from 10.255.0.0/24
Corosync (cluster) Cluster network Keep it working; do not block it
Provider firewall Cloud or data center panel Open UDP 51820 there too
Tenant isolation VNet / VM firewall Default DROP, then allow only what is needed
  • Proxmox builds IP sets for each VNet on its own, like vnet-all and vnet-gateway. Use them in your rules.
  • Port isolation works only on the local host. To isolate across nodes, use the VNet firewall with a default DROP policy.
  • WireGuard ignores unknown senders. A scan of UDP 51820 shows nothing useful.
  • Protect /etc/pve/priv. It holds the WireGuard private keys. Give SDN admin rights to as few users as possible.

Conclusion

At this point, you have a working multi-site Proxmox SDN with WireGuard fabric. The fabric links your nodes with a private encrypted network. The VXLAN zone carries your VM traffic over it. The MTU and firewall steps keep it stable and safe. Remember the key rule, which is WireGuard 1420, VXLAN, and guests 1370.

Before production, test failover and watch CPU on busy nodes. Keep Corosync low-latency and separate.

You can connect PerLod dedicated servers across locations with encrypted Proxmox SDN overlays, and give your VMs one private network at every site. Start by choosing your locations on the PerLod dedicated server hosting page.

We hope you enjoy this guide. For the full option list, you can read the official Proxmox VE SDN documentation.