How To Set Up Proxmox With WireGuard as an IPv6 Tunnel Using a Linode VPS
Tricknowtech Team 12 min read
Goal
In this tutorial, you will set up a WireGuard tunnel between a Proxmox VE host and a VPS that has a routed IPv6 /64, so the Proxmox host — and optionally its VMs — gets working IPv6 connectivity regardless of what your local ISP provides.
Prerequisites
A VPS from a provider that allocates a routed IPv6 /64 per instance (this tutorial uses Linode as the example)
Root or sudo access on that VPS, running Ubuntu
A Proxmox VE host (Debian-based) with root/sudo access and outbound internet access
Basic familiarity with editing config files and using systemctl
No restrictive upstream firewall blocking outbound UDP from the Proxmox host to the VPS's public IP
Let an AI agent do this for you
Copy a ready-made prompt for an AI coding assistant with terminal access to your server (Claude Code, Cursor, or similar) — it can carry out the steps below for you. Review what it plans to run before it executes anything.
Many home internet connections — cellular, satellite, or budget fiber/cable plans — still don't offer native IPv6, or hand out only a CGNAT'd IPv4 address with no public IPv6 at all. If you run a Proxmox VE homelab behind one of these connections, you're stuck on IPv4-only: extra NAT hops to reach IPv6-only services, and no way to expose anything you host on a real public IPv6 address.
You don't need your ISP to cooperate to fix this. A small, inexpensive VPS from a provider that allocates a real routed IPv6 /64 to every instance — Linode does this by default — can act as a tunnel endpoint. You bring up a WireGuard tunnel between that VPS and your Proxmox host, route IPv6 traffic through it, and the Proxmox host (and, optionally, its VMs) gets working outbound and inbound IPv6 regardless of what your ISP supports.
This tunnel carries IPv6 only. Your Proxmox host's existing IPv4 connectivity — whatever your home connection provides — is left completely untouched.
Step 1 — Gather your VPS's IPv6 details and install WireGuard
In your VPS provider's dashboard, open the network tab for the instance and note two things: the SLAAC address the VPS already has, and the routed /64 block assigned to it. That /64 is the prefix you'll be extending to your Proxmox side of the tunnel, and later, optionally, to VMs.
“Your actual /64 will be shown in your provider's dashboard. This tutorial uses the documentation range 2001:db8::/64 as a placeholder throughout — it isn't routable on the real internet. Substitute your own real assigned prefix everywhere it appears below.”
On the VPS (Ubuntu), install WireGuard:
bash
apt update && apt install -y wireguard
Step 2 — Enable IPv6 forwarding on the VPS
By default Linux only processes IPv6 packets addressed to itself — it won't forward traffic arriving on one interface out another. The VPS needs to forward packets between its public interface and the WireGuard tunnel interface, or every packet from the Proxmox side gets silently dropped.
“vps_private.key is a secret. Never share it, paste it into chat, or commit it to version control. The chmod 600 above (backed by umask 077) keeps it readable only by root.”
Run cat vps_public.key and note the output — you'll paste it into the Proxmox host's config in Step 4. Then create /etc/wireguard/wg0.conf:
ini
[Interface]
PrivateKey = <contents of vps_private.key>
Address = 10.100.0.1/24, 2001:db8::1/64
ListenPort = 51820
[Peer]
PublicKey = <Proxmox host's public key — generated in Step 4>
AllowedIPs = 10.100.0.2/32, 2001:db8::2/128
The interface gets two addresses: a private IPv4 (10.100.0.1/24) used only inside the tunnel, and an address from your routed /64 (2001:db8::1/64) that the Proxmox side will route through. You don't have the Proxmox public key yet — leave that line as a placeholder for now and come back to fill it in after Step 4.
Step 4 — Install WireGuard and configure the tunnel on the Proxmox host
Proxmox VE is Debian-based, so the same package used on Debian/Ubuntu applies here:
bash
apt update && apt install -y wireguard-tools
Generate a key pair for the Proxmox side:
bash
cd /etc/wireguard
umask 077
wg genkey | tee proxmox_private.key | wg pubkey > proxmox_public.key
chmod 600 proxmox_private.key
“Same rule applies: proxmox_private.key never leaves this host, is never shared, and is never committed to version control.”
Create /etc/wireguard/wg0.conf on the Proxmox host:
Replace 203.0.113.20 with your VPS's actual public IPv4 address (or hostname). AllowedIPs = ::/0 routes all IPv6 traffic through the tunnel — deliberately IPv6 only. There's no 0.0.0.0/0 entry, so your existing IPv4 route (whatever your home connection provides) is left alone; this tunnel exists purely to supply IPv6. PersistentKeepalive = 25 sends a keepalive every 25 seconds so the tunnel survives NAT on the Proxmox side, which typically sits behind a home router while the VPS has a stable public address.
Step 5 — Complete the peer configuration and open the firewall
Go back and fill in the public keys on both sides: paste proxmox_public.key into the PublicKey line of the VPS's [Peer] section, and confirm vps_public.key is correctly set in the Proxmox host's [Peer] section.
On the VPS, open only the WireGuard port — don't disable the firewall to make this work:
bash
ufw allow 51820/udp
If your VPS provider also enforces a separate cloud firewall or security-group layer in front of the instance, add the equivalent rule there too: allow inbound UDP 51820 from any source, leave everything else denied.
Step 6 — Bring up the tunnel and verify the handshake
Run on both the VPS and the Proxmox host:
bash
systemctl enable --now wg-quick@wg0
Check the interface on either side:
bash
wg show
Look for a "latest handshake" line with a recent timestamp on both ends — that confirms both peers can reach each other on UDP 51820. Then, from the Proxmox host, ping the VPS's tunnel address:
bash
ping6 2001:db8::1
Successful replies confirm the tunnel is passing IPv6 traffic end to end.
Step 7 — Extend IPv6 to your VMs (optional)
The steps so far give the Proxmox host itself working IPv6. To give individual VMs real IPv6 addresses too, there are two documented approaches.
Option A: NAT66 (simplest)
Masquerade VMs' IPv6 traffic out through wg0, the same pattern as IPv4 NAT masquerading in a typical WireGuard router setup — an ip6tables MASQUERADE rule on the wg0 interface. VMs get working outbound IPv6, but they aren't individually addressable from outside the tunnel. This is fine if you just want VMs to reach IPv6-only services; it doesn't let you host a public IPv6 service on a VM.
Option B: Route a sub-block and NDP-proxy it (advanced)
Carve a smaller sub-block out of your routed /64, route it to Proxmox's Linux bridge (vmbr0 or vmbr1), and run the ndppd package on the VPS so it answers IPv6 neighbor discovery for that sub-block and forwards matching traffic down the tunnel. This gives VMs individually addressable public IPv6 addresses, but the NDP proxy configuration is fiddly and version-specific.
“Don't copy an ndppd config snippet from memory or a random blog post — consult ndppd's own documentation or GitHub repository for the exact syntax matching your installed version. A wrong NDP proxy config is a common source of silent failure: packets arrive at the VPS but nothing answers the neighbor solicitation, so the VM just looks unreachable with no error to point at.”
Step 8 — Confirm the tunnel persists across reboots
Because Step 6 used systemctl enable --now, wg-quick@wg0 is already registered to start on boot on both hosts — no further action is required. Confirm with:
bash
systemctl is-enabled wg-quick@wg0
This should print enabled on both machines.
Step 9 — Verify outbound IPv6 connectivity
The real end-to-end test is an outbound request from the Proxmox host itself:
bash
curl -6 https://ifconfig.co
This should return a public IPv6 address inside your routed /64 — not the literal documentation address used in this tutorial, but your real assigned prefix. That confirms outbound IPv6 traffic is leaving through the tunnel with a valid public source address.
Step 10 — Troubleshooting: handshake succeeds but IPv6 doesn't route
If wg show shows a recent handshake on both ends but ping6 or curl -6 still fail, check these two things first, in order:
IPv6 forwarding on the VPS (Step 2) — run sysctl net.ipv6.conf.all.forwarding; if it prints 0 instead of 1, the setting didn't take. Re-run sysctl -p and check for a typo in /etc/sysctl.conf.
A firewall in front of the VPS blocking UDP 51820 — a local ufw allow rule doesn't help if a separate cloud-level firewall or security group upstream is still dropping the port. Check that layer independently of the OS firewall.
These two account for the large majority of tunnels that establish a handshake but never actually pass traffic — the same class of issue you'd hit in a plain site-to-site WireGuard setup, just applied to IPv6 instead of IPv4.