If you’re running a home server behind a DSL connection that only supports DS-Lite – meaning you have a full IPv6 address, but no public IPv4. Your server is reachable over IPv6, but when you’re on the road using a coffee shop’s WiFi or a mobile hotspot that only provides IPv4, you’re locked out.
Note this guide is specifically targeted at a home-server setup like Nextcloud – for hosting a public website, just pay a shared hoster.
We also assume you’re using a FritzBox router, as it ships with the services we need. You can use a different router, but seriously – treat yourself and get one of these. They just work. The 7490, for instance, received a whopping 12 years of software support.
What we want to achieve:
- Public HTTP(S) access to your server over IPv6 connections
- Private WireGuard access for yourself when only IPv4 is available
- Zero running costs – all services have sufficient free tier
Table of Contents
- The Architecture
- Step 0: Public HTTP Access via IPv6
- Step 1: WireGuard via FritzBox
- Step 2: The IPv4-to-IPv6 Bridge
- Step 3: DNS Split-Horizon with dnsmasq
The Architecture

| Component | Role |
|---|---|
| myfritz.net | Free DynDNS for the server’s AAAA record (public web access) |
| ipv64.net | Free DynDNS + UDP portmapper (IPv4→IPv6 bridge for WireGuard) |
| FritzBox | Router with built-in WireGuard server (Fritz!OS 7.50+) |
| ddclient | Keeps the AAAA record at spdns.org updated with the server’s IPv6 |
| dnsmasq | Local DNS on the server for split-horizon name-resolution |
Step 0: Public HTTP Access via IPv6
I’ll assume this is already working, so we only cover it briefly for completeness.
With IPv6 there is no NAT, so your server must update its own public address – which differs from your FritzBox’s public address.
To do this, you’ll typically run ddclient, which is well documented online. Most DynDNS providers supply a ready-made config file for it.
Step 1: WireGuard via FritzBox
FritzBox (FritzOS 7.50+) has a built-in WireGuard server. Set it up under: Internet → Permits → VPN (WireGuard).
Choose “Add connection” → “Single device” → follow the wizard. The FritzBox will generate a wg_config.conf client config file.
This works great if your WireGuard client has IPv6 connectivity — it can reach the Fritz!Box directly. But from an IPv4-only network, you can’t connect.
Step 2: The IPv4-to-IPv6 Bridge
This is where ipv64.net comes in. Their free tier includes a UDP port mapper that forwards an IPv4 port to an IPv6 destination.
- Create an account at ipv64.net
- Register a domain (e.g.,
server.ipv64.net) - Set up FritzBox DynDNS to update the AAAA record at ipv64.net:
In the ipv64.net dashboard, create a reverse proxy with UDP port mapping:
- External:
<random-port>(assigned by ipv64.net) - Target: the port that is stated in your
wg_config.conf
Now edit the wg_config.conf and change the Endpoint to use the ipv64.net address and mapped port:
Endpoint = server.ipv64.net:<random-port>
Your WireGuard client can now connect via either IPv6 or IPv4 – ipv64.net bridges the connection to your FritzBox over IPv6.
Why not just proxy HTTP traffic directly? We could use the reverse proxy to redirect HTTP traffic and be done immediately. However, if you’re running a home server for sensitive data, ipv64.net would act as a man in the middle. By routing only end-to-end encrypted WireGuard traffic through the proxy, we avoid that entirely.
Step 3: DNS Split-Horizon with dnsmasq
There’s one final problem. When connected via WireGuard, you want to access your server at server.spdns.org. But that domain resolves to an IPv6 address (AAAA record), and FritzOS 7.x does not support IPv6 inside the WireGuard tunnel. Only IPv4 traffic passes through.
The solution: run dnsmasq on the server so that WireGuard clients resolve server.spdns.org to the server’s LAN IPv4 address instead.
If systemd-resolved is occupying port 53, disable it:
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
Edit /etc/dnsmasq.conf:
# Listen on LAN and localhost only
listen-address=192.168.178.<server-ip>,127.0.0.1
bind-interfaces
# Forward everything else to Fritz!Box
server=192.168.178.1
# The magic line: resolve server.spdns.org to LAN IP
address=/server.spdns.org/192.168.178.<server-ip>
sudo systemctl enable --now dnsmasq
Verify:
dig server.spdns.org @192.168.178.<server-ip>
# Should return 192.168.178.<server-ip>
Now update the client wg_config.conf one last time:
[Interface]
PrivateKey = <key>
Address = 192.168.178.201/24
DNS = 192.168.178.<server-ip>
when the tunnel is active, server.spdns.org resolves to the LAN IP → traffic flows through the WireGuard tunnel over IPv4. When the tunnel is off, normal DNS resolves the AAAA record → direct IPv6 access.