Linode + WireGuard = Every Device Gets a Static IPv6

A friendly, soup-to-nuts guide for Ubuntu 24.04 (but the logic is distro-agnostic). Follow along once and your laptop, phone, router—anything—will enjoy its own global IPv6 /128 while IPv4 keeps working through NAT.


🧰 Quick‑Reference Cheat Sheet

ThingPlaceholderWhy it matters
Your routed /64<YOUR_ROUTED_/64>Linode delegates this to your VPS for free.
Server’s IPv6<SERVER_IPV6>First address you’ll bind to wg0.
First peer IPv6<CLIENT1_IPV6>Hand this to laptop/phone. Increment for more peers.
Private IPv4 pool10.66.66.0/24Good old NAT for IPv4 stuff.
WireGuard port51820Any high UDP port works.

Throughout the doc, replace the placeholders with your real values.


1️⃣ Get Your /64 in Cloud Manager (30 sec)

  1. Networking → IPv6 → Add Routed Range → /64.
  2. Copy the block (this becomes <YOUR_ROUTED_/64>).
  3. Celebrate—18 quintillion public addresses are yours.

Why? A routed /64 means the Internet already knows to send every packet in that block to your VM IP.


2️⃣ Turn Off Linode “Auto-configure networking” (don’t skip!)

Select Linode Instance → Configuration -> Edit → (Filesystem/Boot Helpers) Auto-configure networking → Off → Reboot once.

Helper overwrites Netplan every boot. We need full control.


3️⃣ Patch & Prep the OS

sudo apt update && sudo apt -y upgrade       # security fixes
sudo apt -y install curl git iptables-persistent

(Optional) add fail2ban ufw unattended-upgrades if you love hardening.


4️⃣ Teach Ubuntu About the New /64 (Netplan)

Create /etc/netplan/60-wireguard.yaml:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: true
      dhcp6: true          # keep Linode SLAAC /128
      addresses:
        - <HOST_LINK_IPV6>/64   # optional pretty IPv6 for VPS
      routes:
        - to: <YOUR_ROUTED_/64> # ⭐ marks the subnet as on‑link
          scope: link

Activate + verify:

sudo netplan apply
ip -6 route | grep $(echo <YOUR_ROUTED_/64> | cut -d'/' -f1)

If you see the route via eth0, you’re set.


5️⃣ Enable IPv6 Forwarding

echo 'net.ipv6.conf.all.forwarding=1' | sudo tee /etc/sysctl.d/99-wg-forward.conf
sudo sysctl --system

6️⃣ Install WireGuard via angristan Script (5 min)

curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
chmod +x wireguard-install.sh
sudo ./wireguard-install.sh

Pick these options:

  • IP versions: IPv4 + IPv6
  • Public IPv6 address: accept SLAAC /128 detected
  • Interface IPv6 subnet: leave default (fd42:…/112)
  • Remaining prompts: defaults OK

Result: /etc/wireguard/wg0.conf (server) + /root/<peer>.conf (first client).


7️⃣ Replace Private IPv6 with Public /64

Edit wg0.conf

[Interface]
Address = 10.66.66.1/24, <SERVER_IPV6>/64

# keep IPv4 NAT, drop IPv6 NAT, add subnet route
PostUp   = iptables -t nat -A POSTROUTING -s 10.66.66.0/24 -o eth0 -j MASQUERADE
PostUp  += ip -6 route add <YOUR_ROUTED_/64> dev %i
PostDown = iptables -t nat -D POSTROUTING -s 10.66.66.0/24 -o eth0 -j MASQUERADE
PostDown+= ip -6 route del <YOUR_ROUTED_/64> dev %i

Delete any ip6tables -t nat lines referring to MASQUERADE.

Edit first client (/root/<peer>.conf)

Address = 10.66.66.2/24, <CLIENT1_IPV6>/128
DNS     = 2600:3c00::1   # or resolver of choice

8️⃣ Firewall + Start Tunnel

sudo iptables  -A INPUT -p udp --dport 51820 -j ACCEPT
sudo ip6tables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo netfilter-persistent save

sudo systemctl enable --now wg-quick@wg0

9️⃣ Smoke Test

VPS

wg show
ip -6 addr show dev wg0  # expect <SERVER_IPV6>

Peer device

ping6 -c3 google.com
curl -6 ifconfig.co      # should print <CLIENT1_IPV6>

🔄 Add / Remove Peers

sudo ./wireguard-install.sh   # rerun script
# choose "Add a peer" or "Remove a peer"

If adding, edit new client file → change IPv6 to next free /128.


🛡️ Hardening & Housekeeping

  • SSH keys only, consider changing SSH port.
  • fail2ban, ufw/Cloud Firewall for brute‑force blocking.
  • unattended-upgrades or Livepatch for CVE peace of mind.
  • Back up /etc/wireguard + keys off‑server.
  • Monitoring: netdata, Prometheus exporter → Grafana.
  • Rotate keys yearly: edit files, then wg syncconf wg0 <(wg-quick strip wg0).

🖥️ Manual Server Installation Commands (by distro)

DistroCommand
Ubuntu / Debiansudo apt update && sudo apt -y install wireguard wireguard-tools
Alma / Rocky / CentOS 8+sudo dnf -y install epel-release && sudo dnf -y install wireguard-tools
Fedora (35+)sudo dnf -y install wireguard-tools
Arch / Manjarosudo pacman -Syu wireguard-tools
OpenSUSEsudo zypper in wireguard-tools
Alpineapk add wireguard-tools

After manual install: sudo systemctl enable --now wg-quick@wg0 when wg0.conf is ready.


📲 Client Installation Cheats

PlatformInstall stepsHow to import
Windows 10/11Download MSI from wireguard.com → install“Add Tunnel → Import from file” or scan QR.
macOS (Intel / Apple Silicon)Mac App Store → WireGuardOpen → Import Tunnel or scan QR.
Linux desktopsudo apt install wireguard-tools (or pacman/dnf)wg-quick up my.conf or use NetworkManager plugin.
AndroidPlay Store → WireGuard (or F‑Droid)“+” → Scan QR or Import.
iOS / iPadOSApp Store → WireGuard“+” → Scan / Import.
OpenWrtopkg update && opkg install wireguard-toolsLuCI → Network → Interfaces → Add WireGuard; paste peer section.

Pro tip: On mobile, enable Always‑on VPN so traffic auto‑routes.


📎 Copy‑Paste Appendix

# /etc/netplan/60-wireguard.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: true
      dhcp6: true
      addresses:
        - <HOST_LINK_IPV6>/64
      routes:
        - to: <YOUR_ROUTED_/64>
          scope: link
[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address    = 10.66.66.1/24, <SERVER_IPV6>/64
ListenPort = 51820
PostUp   = iptables -t nat -A POSTROUTING -s 10.66.66.0/24 -o eth0 -j MASQUERADE
PostUp  += ip -6 route add <YOUR_ROUTED_/64> dev %i
PostDown = iptables -t nat -D POSTROUTING -s 10.66.66.0/24 -o eth0 -j MASQUERADE
PostDown+= ip -6 route del <YOUR_ROUTED_/64> dev %i

[Peer]
PublicKey  = <CLIENT1_PUBKEY>
AllowedIPs = 10.66.66.2/32, <CLIENT1_IPV6>/128
[Interface]
PrivateKey = <CLIENT1_PRIVKEY>
Address    = 10.66.66.2/24, <CLIENT1_IPV6>/128
DNS        = 2600:3c00::1

[Peer]
PublicKey  = <SERVER_PUBKEY>
Endpoint   = <VPS_IP_OR_DNS>:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

💸 Grab $100 Linode Credit (Referral)

Launching a fresh Linode for this VPN? Use my link to snag $100 of free credit (valid 60 days):

▶️ linode.com/lp/refer/?r=261425189477b64a425764bbadeda860fd0d1794

It costs you nothing and helps keep guides like this updated—win-win! ❤️


🎉 Done!

You now own a slice of the IPv6 Internet—no NAT, no headaches. Happy tunneling, and ping me anytime for tweaks or troubleshooting!