Skip to main content

COMMUNITY KNOWLEDGE FORUM Independent Hosting Community • Not affiliated with netcup GmbH.

NETCUP GUIDE
FORUM · LIVE VOUCHER POOL
Tutorials LEVEL: Intermediate TIME: 35 minutes // 17 MIN READ • VERIFIED:

How to Build a Dual-Stack (IPv4 + IPv6) WireGuard VPN Server with Unbound DNS on Netcup

Because every Netcup VPS and Root Server uses hardware-assisted KVM virtualization with a native kernel, up to 2.5 Gbit/s network interfaces, a routed /64 IPv6 subnet, and generous fair-use traffic across Nuremberg, Vienna, Amsterdam, Manassas, and Singapore, even a 1 GB RAM entry-level KVM instance easily handles hundreds of megabits of encrypted tunnel traffic. This systems engineering guide builds a hardened, dual-stack (IPv4 + IPv6) WireGuard VPN gateway complete with MTU 1420 encapsulation tuning, TCP MSS clamping to prevent Path MTU blackholes, a local recursive Unbound DNS resolver for zero-leak privacy, and an automated peer provisioning script using post-quantum-resistant PresharedKey secrets.

THREAD OP // AUTHOR Elena Rostova Senior Network & Storage Verification Editor
MOD VERIFIED // CO-MAINTAINER Marcus Vance Principal Systems Architect
THREAD STATUS // UPDATED Community Standards →
MODERATOR NOTE // TEST ENVIRONMENT & TRANSPARENCY Verified against in-tree Linux 6.8+ WireGuard kernel module, wireguard-tools, and unbound 1.19 on a Netcup KVM instance in Nuremberg (AS197540) with dual-stack IPv4 /32 and IPv6 /64 routing.

PREREQUISITES // ENVIRONMENT REQUIREMENTS

CHECKLIST
  • ✓ Any Netcup KVM VPS (even a 1 GB RAM VPS pico G11.5s or 2 GB RAM VPS nano G11.5s) or Root Server running Ubuntu 24.04 LTS or Debian 12
  • ✓ Inbound UDP port 51820 allowed in UFW and the Netcup SCP Firewall
  • ✓ Root or sudo SSH access

Key Takeaways

EXECUTIVE BRIEFING
  • 01 WireGuard executes directly inside the Linux 6.8+ kernel on Netcup KVM servers using ChaCha20-Poly1305 SIMD acceleration, delivering 800+ Mbps even on a 2-vCore VPS.
  • 02 Calculate and set MTU = 1420 explicitly on both server and client interfaces to accommodate IPv6 (40 bytes) + UDP (8 bytes) + WireGuard header/tag (32 bytes) overhead across standard 1500-byte virtio-net frames.
  • 03 Configure TCP MSS clamping (--clamp-mss-to-pmtu) in PostUp so TLS handshakes over cellular 5G or PPPoE links never stall due to ICMP fragmentation drops.
  • 04 Always tunnel both IPv4 (0.0.0.0/0) and IPv6 (::/0) in client profiles; omitting IPv6 causes dual-stack mobile and Wi-Fi networks to bypass the VPN tunnel entirely.
  • 05 Run a local Unbound recursive DNS resolver bound strictly to the wg0 interface (10.66.66.1, fd42:66:66::1) with DNSSEC validation and QNAME minimization.
📑 Quick Jump Table of Contents (5 Sections) ▼
§ 01

Step 1: Understand Netcup virtio-net MTU Encapsulation & Enable Kernel Forwarding

The most frequent cause of sluggish or hanging connections on self-hosted WireGuard servers is improper Maximum Transmission Unit (MTU) sizing and missing TCP Maximum Segment Size (MSS) clamping. On Netcup KVM instances, the primary virtual NIC (eth0 or ens3 backed by virtio_net) operates at a standard Ethernet MTU of 1500 bytes.

When a client connects to your Netcup WireGuard endpoint over IPv6 (or IPv4), every tunnel packet wraps the inner payload inside outer headers: a 40-byte IPv6 header (or 20-byte IPv4 header), an 8-byte UDP header, a 16-byte WireGuard message header and nonce counter, and a 16-byte Poly1305 cryptographic authentication tag. That adds exactly 80 bytes of encapsulation overhead on IPv6 transport (60 bytes on IPv4). If the inner WireGuard interface (wg0) is not reduced by at least 80 bytes (1500 - 80 = 1420), encapsulated packets exceed 1500 bytes and trigger continuous packet fragmentation or Path MTU Discovery (PMTUD) blackholes.

PMTUD blackholes are particularly common when roaming onto residential PPPoE fiber/DSL links (which already lose 8 bytes to PPPoE framing, dropping the outer MTU to 1492) or mobile LTE/5G carrier networks (which often run outer MTUs between 1380 and 1428 bytes). When an intermediate firewall drops ICMP Type 3 Code 4 (Fragmentation Needed) or ICMPv6 Type 2 (Packet Too Big) messages, small packets like ping and DNS queries succeed while large TLS ServerHello certificates silently vanish. Alongside setting MTU = 1420, we also set net.ipv4.conf.all.rp_filter = 2 (loose Reverse Path Filtering) and enable Google’s bbr congestion control algorithm so high-latency transcontinental VPN sessions maintain full throughput.

WireGuard Packet Encapsulation Overhead Breakdown on Netcup KVM (virtio-net 1500 MTU)
Protocol LayerIPv4 Outer TransportIPv6 Outer TransportByte Offset Notes
Physical / KVM virtio-net Link MTU1500 bytes1500 bytesVerify via ip -br link show on your Netcup VM
Outer IP Header-20 bytes (IPv4)-40 bytes (IPv6)IPv6 fixed header is 20 bytes larger than IPv4
Outer UDP Header (Port 51820)-8 bytes-8 bytesStandard 8-byte UDP datagram header
WireGuard Type + Key Index + Nonce-16 bytes-16 bytes4B type + 4B receiver index + 8B counter
Poly1305 Authentication Tag-16 bytes-16 bytes128-bit cryptographic MAC integrity tag
Maximum Safe wg0 Interface MTU1440 bytes1420 bytesUse 1420 universally (or 1412 for PPPoE DSL clients)
Detect Primary Network Interface & Enable Dual-Stack Kernel Forwarding
bash
# 1. Identify your primary Netcup network interface name (usually eth0 or ens3)
PRIMARY_IF=$(ip -4 route show default | awk '{print $5; exit}')
echo "Detected Primary Netcup Interface: ${PRIMARY_IF}"

# 2. Configure persistent dual-stack IP forwarding and BBR congestion control
sudo tee /etc/sysctl.d/99-wireguard-router.conf > /dev/null <<'EOF'
# Enable IPv4 and IPv6 packet forwarding across interfaces
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1

# Enable loose Reverse Path Filtering so asymmetric VPN return paths are not dropped
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2

# Enable BBR TCP congestion control for high-bandwidth VPN throughput
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sudo sysctl --system

Command Explanation: Automatically detects whether your Netcup VM uses eth0 or ens3 and enables persistent IPv4/IPv6 kernel forwarding alongside BBR congestion control.

EXPECTED OUTPUT
Detected Primary Netcup Interface: eth0
* Applying /etc/sysctl.d/99-wireguard-router.conf ...
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
§ 02

Step 2: Install wireguard-tools and Initialize Cryptographic Key Hierarchy

Since Linux kernel 5.6, the WireGuard data plane (wireguard.ko) is compiled directly into the mainline Ubuntu and Debian kernel. Unlike legacy OpenVPN or IPsec user-space daemons that copy every network packet back and forth between kernel space and user space over /dev/net/tun, WireGuard encrypts and routes packets entirely inside kernel softirq context using AVX2/AVX-512 SIMD instructions on Netcup’s AMD EPYC hosts. You only need to install the user-space configuration utilities (wireguard-tools), qrencode (for instant mobile onboarding), and unbound with its DNSSEC root trust anchors (dns-root-data).

Create a structured directory hierarchy under /etc/wireguard/{keys,clients} protected by chmod 0700 and generate the server’s Curve25519 keypair under an explicit umask 077 subshell. This guarantees that private key files are created atomically with 0600 (-rw-------) permissions from the very first inode write, so no unprivileged local process can ever read them.

Install WireGuard Packages & Generate Server Curve25519 Keypair
bash
sudo apt update
sudo apt install -y wireguard wireguard-tools qrencode iptables unbound dns-root-data

# Create locked-down key and client storage directories
sudo mkdir -p /etc/wireguard/{keys,clients}
sudo chmod -R 0700 /etc/wireguard

# Generate server private and public Curve25519 keys with strict umask 077
sudo sh -c 'umask 077; wg genkey | tee /etc/wireguard/keys/server_private.key | wg pubkey > /etc/wireguard/keys/server_public.key'

# Verify key permissions
sudo ls -la /etc/wireguard/keys/

Command Explanation: Installs WireGuard user-space tools, qrencode, and unbound, then generates the server Curve25519 keypair under /etc/wireguard/keys/ with 0600 (-rw-------) permissions.

EXPECTED OUTPUT
drwx------ 2 root root 4096 Oct 29 11:15 .
-rw------- 1 root root   45 Oct 29 11:15 server_private.key
-rw------- 1 root root   45 Oct 29 11:15 server_public.key
§ 03

Step 3: Configure a Zero-Leak Local Unbound Recursive DNS Resolver

Most basic WireGuard guides hardcode DNS = 1.1.1.1 or 8.8.8.8 inside client profiles, which forwards your entire browsing hostname timeline to an external public DNS provider. By configuring a local Unbound recursive resolver on your Netcup server listening directly on the WireGuard tunnel gateway (10.66.66.1 and fd42:66:66::1), every connected device resolves domain names directly against the 13 authoritative DNS root servers (/usr/share/dns/root.key) without relying on any third-party upstream forwarder.

Our Unbound configuration enables two critical privacy and integrity mechanisms: RFC 9156 QNAME Minimization (qname-minimisation: yes), which sends only the minimal required domain label to each intermediate authoritative nameserver (so .com root servers only learn that you are querying a .com domain, not internal-erp.corp.example.com), and strict DNSSEC validation (harden-dnssec-stripped: yes), which rejects spoofed DNS responses.

When binding Unbound to virtual tunnel addresses (10.66.66.1 and fd42:66:66::1), a classic systemd boot race condition occurs if unbound.service starts milliseconds before wg-quick@wg0.service creates the wg0 interface. Enabling ip-freebind: yes inside /etc/unbound/unbound.conf.d/wg-vpn.conf instructs the Linux kernel (IP_FREEBIND socket option) to allow Unbound to bind to the IPv4 and IPv6 tunnel addresses even before wg0 is brought up.

/etc/unbound/unbound.conf.d/wg-vpn.conf
text
server:
    num-threads: 2
    interface: 127.0.0.1
    interface: 10.66.66.1
    interface: fd42:66:66::1
    port: 53

    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes

    # Restrict recursive queries strictly to localhost and the WireGuard subnet
    access-control: 0.0.0.0/0 refuse
    access-control: ::0/0 refuse
    access-control: 127.0.0.0/8 allow
    access-control: 10.66.66.0/24 allow
    access-control: fd42:66:66::/64 allow

    # Privacy & Security Hardening
    hide-identity: yes
    hide-version: yes
    qname-minimisation: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes
    prefetch: yes

    # Memory Cache Sizing (Lightweight ~64MB total footprint)
    msg-cache-size: 16m
    rrset-cache-size: 32m
    neg-cache-size: 4m
    so-rcvbuf: 4m
    so-sndbuf: 4m

Command Explanation: Configures Unbound to listen on the WireGuard IPv4 (10.66.66.1) and IPv6 (fd42:66:66::1) gateway addresses while refusing unauthorized queries from the public internet (0.0.0.0/0 refuse).

SECURITY NOTE: Because Unbound binds to 10.66.66.1 and fd42:66:66::1, ensure wg-quick@wg0.service starts before unbound.service, or set ip-freebind: yes inside server: so Unbound can bind to the tunnel IP before wg0 comes up.

Enable ip-freebind: yes and Validate Unbound Configuration
bash
sudo sed -i '/port: 53/a \    ip-freebind: yes' /etc/unbound/unbound.conf.d/wg-vpn.conf
sudo unbound-checkconf
sudo systemctl enable --now unbound
dig @127.0.0.1 netcup.com +dnssec +short

Command Explanation: Adds ip-freebind: yes so Unbound starts cleanly at boot regardless of interface ordering, verifies syntax with unbound-checkconf, and tests local DNSSEC resolution.

EXPECTED OUTPUT
unbound-checkconf: no errors in /etc/unbound/unbound.conf
46.38.224.21
§ 04

Step 4: Build /etc/wireguard/wg0.conf with Dual-Stack NAT & TCP MSS Clamping

Understanding how Netcup routes your IPv6 /64 block is essential before configuring IPv6 on wg0. On Netcup’s AS197540 network, the hypervisor gateway (fe80::1) does not route your /64 prefix unconditionally to your server’s MAC address via DHCPv6 Prefix Delegation; instead, it performs Neighbor Discovery Protocol (NDP) lookups on eth0 for each individual IPv6 address. If you carve out a /80 sub-prefix from your public /64 and assign it to wg0, external packets returning to your VPN peers will be dropped by the upstream router unless you run an NDP proxy daemon (ndppd) on eth0.

For a clean, zero-maintenance VPN deployment that works identically across every Netcup VPS and Root Server, we assign an RFC 4193 Unique Local Address (ULA) subnet (fd42:66:66::/64) to wg0 alongside RFC 1918 IPv4 (10.66.66.0/24) and apply ip6tables NAT66 MASQUERADE on outbound traffic. This gives every connected laptop and smartphone full dual-stack IPv6 connectivity through your Netcup server’s primary IPv6 address without requiring ndppd daemons or exposing individual device interface identifiers.

In addition to dual-stack MASQUERADE rules, our PostUp hook injects --clamp-mss-to-pmtu in the mangle FORWARD chain for both IPv4 and IPv6. Whenever a VPN client initiates a TCP connection (SYN flag set), netfilter dynamically lowers the TCP Maximum Segment Size (MSS) header option to match the tunnel Path MTU (1380 bytes for IPv4 or 1360 bytes for IPv6). This prevents hanging TLS handshakes on servers behind broken enterprise firewalls that drop ICMP Packet Too Big notifications.

Generate /etc/wireguard/wg0.conf with Automatic Interface Detection
bash
PRIMARY_IF=$(ip -4 route show default | awk '{print $5; exit}')
SERVER_PRIVKEY=$(sudo cat /etc/wireguard/keys/server_private.key)

sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
Address = 10.66.66.1/24, fd42:66:66::1/64
ListenPort = 51820
PrivateKey = ${SERVER_PRIVKEY}
MTU = 1420
SaveConfig = false

# Enable forwarding, TCP MSS clamping, and dual-stack NAT Masquerade
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostUp = iptables -t mangle -A FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostUp = iptables -t mangle -A FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostUp = iptables -t nat -A POSTROUTING -s 10.66.66.0/24 -o ${PRIMARY_IF} -j MASQUERADE
PostUp = ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT
PostUp = ip6tables -t mangle -A FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostUp = ip6tables -t mangle -A FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostUp = ip6tables -t nat -A POSTROUTING -s fd42:66:66::/64 -o ${PRIMARY_IF} -j MASQUERADE

# Cleanly remove rules when wg0 stops
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
PostDown = iptables -t mangle -D FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -t mangle -D FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -t nat -D POSTROUTING -s 10.66.66.0/24 -o ${PRIMARY_IF} -j MASQUERADE
PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT
PostDown = ip6tables -t mangle -D FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = ip6tables -t mangle -D FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = ip6tables -t nat -D POSTROUTING -s fd42:66:66::/64 -o ${PRIMARY_IF} -j MASQUERADE
EOF

sudo chmod 0600 /etc/wireguard/wg0.conf
sudo ufw allow 51820/udp comment 'WireGuard VPN'
sudo systemctl enable --now wg-quick@wg0
sudo wg show wg0

Command Explanation: Creates /etc/wireguard/wg0.conf using the detected primary NIC, configures dual-stack NAT and MSS clamping, opens UDP 51820 in UFW, and activates wg-quick@wg0.

EXPECTED OUTPUT
interface: wg0
  public key: <SERVER_PUBLIC_KEY>
  private key: (hidden)
  listening port: 51820

SECURITY NOTE: Keep SaveConfig = false in /etc/wireguard/wg0.conf. Setting SaveConfig = true causes wg-quick to overwrite /etc/wireguard/wg0.conf on shutdown, stripping comments and breaking structured provisioning scripts.

§ 05

Step 5: Automated Peer Provisioning Script with PresharedKey & QR Generation

Manually calculating IP offsets and copying public keys between files is tedious and error-prone. Create /usr/local/sbin/wg-add-peer to automate onboarding laptops, workstations, and smartphones. For every peer, the script generates both a Curve25519 keypair and an independent 256-bit symmetric PresharedKey (wg genpsk). WireGuard mixes this pre-shared key into its Noise_IKpsk2 handshake via HKDF, providing post-quantum symmetric resistance even if an adversary records encrypted UDP traffic today for future cryptanalysis.

Equally important, the script applies new peer blocks to the live kernel interface using wg syncconf wg0 <(wg-quick strip wg0) rather than restarting wg-quick@wg0.service. This hot-reload mechanism diffs the desired peer list against the running kernel state and inserts or removes peers with zero packet loss for existing connected users.

/usr/local/sbin/wg-add-peer (Automated Peer Provisioning Script)
bash
sudo tee /usr/local/sbin/wg-add-peer > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -lt 2 ]]; then
  echo "Usage: sudo wg-add-peer <client-name> <octet-2-to-254>"
  echo "Example: sudo wg-add-peer macbook-pro 10"
  exit 1
fi

CLIENT_NAME="$1"
OCTET="$2"
SERVER_IP=$(ip -4 addr show "$(ip -4 route show default | awk '{print $5; exit}')" | awk '/inet / {split($2,a,"/"); print a[1]; exit}')
SERVER_PUBKEY=$(cat /etc/wireguard/keys/server_public.key)
CLIENT_DIR="/etc/wireguard/clients/${CLIENT_NAME}"

if [[ -d "${CLIENT_DIR}" ]]; then
  echo "Error: Peer ${CLIENT_NAME} already exists in ${CLIENT_DIR}"
  exit 1
fi

umask 077
mkdir -p "${CLIENT_DIR}"
wg genkey | tee "${CLIENT_DIR}/private.key" | wg pubkey > "${CLIENT_DIR}/public.key"
wg genpsk > "${CLIENT_DIR}/preshared.key"

CLIENT_PRIVKEY=$(cat "${CLIENT_DIR}/private.key")
CLIENT_PUBKEY=$(cat "${CLIENT_DIR}/public.key")
CLIENT_PSK=$(cat "${CLIENT_DIR}/preshared.key")

# 1. Append Peer block to /etc/wireguard/wg0.conf
cat >> /etc/wireguard/wg0.conf <<PEER_EOF

# Peer: ${CLIENT_NAME}
[Peer]
PublicKey = ${CLIENT_PUBKEY}
PresharedKey = ${CLIENT_PSK}
AllowedIPs = 10.66.66.${OCTET}/32, fd42:66:66::${OCTET}/128
PEER_EOF

# 2. Hot-reload wg0 configuration without dropping active VPN tunnels
wg syncconf wg0 <(wg-quick strip wg0)

# 3. Generate client .conf file
cat > "${CLIENT_DIR}/${CLIENT_NAME}.conf" <<CLIENT_EOF
[Interface]
PrivateKey = ${CLIENT_PRIVKEY}
Address = 10.66.66.${OCTET}/32, fd42:66:66::${OCTET}/128
DNS = 10.66.66.1, fd42:66:66::1
MTU = 1420

[Peer]
PublicKey = ${SERVER_PUBKEY}
PresharedKey = ${CLIENT_PSK}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
CLIENT_EOF

echo "==> Created peer profile: ${CLIENT_DIR}/${CLIENT_NAME}.conf"
echo "==> Scan QR code below with the official WireGuard iOS/Android app:"
qrencode -t ansiutf8 < "${CLIENT_DIR}/${CLIENT_NAME}.conf"
EOF

sudo chmod 0700 /usr/local/sbin/wg-add-peer
sudo /usr/local/sbin/wg-add-peer iphone-16 10

Command Explanation: Creates /usr/local/sbin/wg-add-peer, generates keys + PresharedKey, hot-reloads wg0 using wg syncconf (zero tunnel interruption for other connected peers), writes the client .conf, and prints an ANSI UTF-8 QR code to the terminal.

Zero-Downtime Peer Changes with wg syncconf

Never run systemctl restart wg-quick@wg0 just to add or revoke a peer—restarting the interface tears down active SSH or VoIP sessions for all connected users. Using sudo wg syncconf wg0 <(sudo wg-quick strip wg0) applies peer additions and removals atomically in the kernel.

Common Troubleshooting Scenarios

DIAGNOSTIC RUNBOOK

[SYMPTOM] WireGuard Handshake Succeeds (latest handshake: 5 seconds ago), But Some HTTPS Websites Hang Forever on Load

Root Cause: Path MTU Discovery (PMTUD) blackhole. Either the client profile is missing MTU = 1420, or the client is on a PPPoE DSL / cellular carrier link with an outer MTU smaller than 1500 bytes.

Resolution: Verify the TCPMSS --clamp-mss-to-pmtu rules are present in sudo iptables -t mangle -S FORWARD and sudo ip6tables -t mangle -S FORWARD, and lower the client’s [Interface] MTU to 1380 or 1280 (the minimum IPv6 link MTU).

[SYMPTOM] Client Connects and Can Ping 10.66.66.1, But Cannot Browse Any External IPv4/IPv6 Websites

Root Cause: Either UFW’s default forward policy (DEFAULT_FORWARD_POLICY="DROP" in /etc/default/ufw) is blocking routed packets after wg0 PostUp rules, or the MASQUERADE rule references the wrong interface name (eth0 vs ens3).

Resolution: Check ip -4 route show default to confirm the interface name in /etc/wireguard/wg0.conf, and either set DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw or ensure wg-quick@wg0 inserts -I FORWARD 1 at the top of the FORWARD chain (sudo iptables -I FORWARD 1 -i wg0 -j ACCEPT).

[SYMPTOM] IPv6 Leak Test Shows Client’s Real ISP IPv6 Address While Connected to WireGuard

Root Cause: The client profile’s [Peer] AllowedIPs only includes 0.0.0.0/0 without ::/0, causing the client OS to route IPv6 traffic directly outside the VPN tunnel.

Resolution: Always set AllowedIPs = 0.0.0.0/0, ::/0 in every full-tunnel client configuration and assign a dual-stack tunnel address (10.66.66.X/32, fd42:66:66::X/128).

[SYMPTOM] Clients Cannot Resolve Domains via 10.66.66.1 (DNS_PROBE_FINISHED_NO_INTERNET)

Root Cause: UFW on the Netcup server is blocking incoming UDP/TCP port 53 requests arriving on the wg0 tunnel interface.

Resolution: Allow DNS queries arriving strictly on the wg0 interface: sudo ufw allow in on wg0 to any port 53 and verify with dig @10.66.66.1 netcup.com from a connected client.

Frequently Asked Questions

VERIFIED Q&A

Does running a WireGuard VPN violate Netcup’s Acceptable Use Policy or Fair-Use Traffic rules?

Running a private WireGuard VPN for your personal devices, remote work, or corporate team is 100% permitted on Netcup VPS and Root Servers. Only public open proxies, commercial VPN reselling, or anonymous Tor exit relays that generate copyright/abuse complaints violate Netcup’s Terms of Service.

How do I configure a Split-Tunnel WireGuard profile so only internal Netcup Docker subnets route through the VPN?

In your client .conf file, change AllowedIPs = 0.0.0.0/0, ::/0 to list only your internal WireGuard subnet and private Docker subnets—for example, AllowedIPs = 10.66.66.0/24, fd42:66:66::/64, 172.28.0.0/16—and remove the DNS = 10.66.66.1 line (or restrict it to split-horizon domains).

Why did we use Unique Local Addresses (fd42:66:66::/64) with IPv6 NAT66 instead of routing a slice of Netcup’s public /64?

Netcup routes your public IPv6 /64 directly to your server’s MAC/link address rather than via DHCPv6-PD prefix delegation, meaning carving out a /80 for wg0 requires running an ndppd (NDP Proxy Daemon) responder unless an extra routed subnet is ordered. Using ULA (fd42:66:66::/64) with ip6tables MASQUERADE works deterministically across every Netcup VPS and Root Server out of the box while masking client interface identifiers.

How do I revoke a lost laptop or phone immediately?

Delete the peer’s [Peer] block from /etc/wireguard/wg0.conf, remove /etc/wireguard/clients/<name>, and execute sudo wg syncconf wg0 <(sudo wg-quick strip wg0) (or sudo wg set wg0 peer <PUBLIC_KEY> remove). The kernel drops the peer’s cryptographic session instantaneously.

REFERENCES // VERIFIED TECHNICAL SOURCES

FURTHER READING // ARCHITECTURE AUDITS & GUIDES

Active Coupons →