Skip to content
Bytearium

No ads or affiliate links active

Networking

Game server behind CGNAT or DS-Lite: 5 ways

A game server behind CGNAT or DS-Lite is unreachable over IPv4. Five ways in, from IPv6 to a VPS relay, with UDP limits and a test for each.

Your friends type in your address, and the game answers with a polite nothing. Chances are your internet line shares one IPv4 address with half the neighbourhood. Here is how to get everyone in anyway.

The short answer

A game server behind CGNAT or DS-Lite cannot be reached over IPv4 from the internet, because your router never receives a public IPv4 address of its own. A port forward in the router then leads nowhere [1][2]. Five ways around it are realistic: ask your provider for a public IPv4 address, use IPv6, share the server through Tailscale, relay the traffic through a rented VPS with WireGuard, or use a game relay service such as playit.gg. Which one fits depends on whether your friends will install something and on whether your game talks UDP. Cloudflare Tunnel is not on the list, because its documented service types contain no UDP [27].

The five ways at a glance

WayFriends install something?UDP game portsMain limit
1. Public IPv4 from your providerNoYes, one rule per protocolProvider must offer it, may cost extra
2. IPv6NoYes, one rule per protocolPlayers and game need IPv6
3. Tailscale device sharingYes, client and accountCarried by the tunnel, test your gameEvery player needs the client
4. VPS relay with WireGuardNoYes, one forward per portYou rent and maintain a VPS
5. Relay service (playit.gg)NoYes, UDP tunnels listedA third party carries the traffic

How it works

  1. Why the port forward fails. CGNAT (carrier-grade NAT) means your provider puts many customers behind one public IPv4 address. The block 100.64.0.0/10 is reserved for the links between the provider's NAT and its customers' routers [6]. DS-Lite (Dual-Stack Lite) reaches the same result differently: the FRITZ!Box wraps your IPv4 traffic in IPv6 and sends it to a provider device called AFTR, which shares IPv4 addresses among customers [7]. AVM states the consequence plainly: servers in the home network cannot be reached from the internet over IPv4 [2]. Your forward is correct. It just sits behind a second door that is not yours.
  2. Check which line you have. In the FRITZ!Box open Internet, Online Monitor, Connection Details, and read the lines "Internet, IPv4" and "Internet, IPv6". If no IPv4 address is shown, or one from 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.0.0.0/29 (DS-Lite tunnel) or 192.168.0.0/16, the box has no public IPv4 address. Any other IPv4 address means it has one [1]. If the Port Sharing page says that your provider makes certain ports available, the provider supports PCP (Port Control Protocol), and IPv4 works only on exactly those ports [1][2].
  3. TCP and UDP behave differently in a test. Minecraft Java Edition listens on TCP port 25565 by default, Bedrock Edition on UDP port 19132 [8]. A TCP port answers a connection attempt, so a check can tell open from closed and filtered [9]. A UDP port often stays silent, so a scanner can only report "open|filtered" [9]. The reliable UDP test is the real game client on a connection outside your home. Every way below ends with such a test.
  4. Test from outside, always. Use a phone on mobile data with Wi-Fi switched off, or a friend's connection. A test from inside your own network does not reliably prove a port sharing [12]. If you test over IPv6, open test-ipv6.com on the testing device first: not every mobile network or hotspot has IPv6 [1][2].

Way 1: ask your provider for a public IPv4 address

This is the cleanest fix. The classic port forward works again, and nobody has to install anything. You need a line with real dual stack: IPv4 and IPv6 side by side, with a public IPv4 address at the router. Whether your provider offers that, and for how much, differs by provider and tariff. One tutorial says it often costs a small monthly surcharge or is tied to a higher tariff [24]. A forum thread from 22 May 2025 reports a customer service agent adding a public IPv4 address for free [23]. We name no provider and no price, because we have no current source for either (unverified, as of 25 Oct 2026). After the switch, read the Online Monitor again and compare it with the ranges above [1]. Then create the rule: Internet, Permit Access, Port Sharing, Add Device for Sharing, New Sharing, "Other application", pick TCP or UDP and enter the port. A game that uses both gets one rule per protocol [3]. If the server has its own firewall, open the port there too [3]. A MyFRITZ! address keeps the box findable when the IPv4 address changes [3]. UDP is no problem on this way. Test: a TCP port from a host outside your network with nc -zv <your-IPv4> 25565 [11], a UDP port with the real client.

Way 2: use IPv6

A DS-Lite line always has IPv6, because the IPv4 tunnel runs over it [7]. A CGNAT line does not have to; AVM lists a line with IPv6 and IPv4 via CGNAT as reachable over IPv6 [1]. Every device gets its own globally valid address. The FRITZ!Box firewall blocks incoming connections until you open a port for a device [4][12]. Check IPv6 with test-ipv6.com on a device at home [1]. On the server, read the permanent global address with ip -6 addr show scope global -temporary, which hides the changing privacy addresses [13]. Then open Internet, Permit Access, Port Sharing, add the server, and create a sharing with IPv6 access, protocol and port. Check that the interface ID in the rule matches the server's real address [12]. Do not use the exposed host option: it opens the whole device, and AVM says to use it for testing only [5]. Two limits matter. First, AVM says an IPv6 connection to your home needs IPv6 on both sides, and that is not the case in every mobile network or hotspot [2]. Second, the game must listen on IPv6 and the client must use it. Bedrock servers have a separate setting for the IPv6 port, 19133 by default [14]. For other games, check the documentation; provider forums report services that only speak IPv4 [23]. Your provider can also change the IPv6 prefix, so use a dynamic DNS name with an AAAA record [12]. Test: from an IPv6-capable connection outside, nc -6 -zv <IPv6-address> 25565 for TCP, the real client for UDP.

Way 3: share the server through Tailscale

Tailscale builds an encrypted tunnel between devices. Your server connects outwards, so CGNAT does not matter. With node sharing you invite a friend to this one machine only, without exposing it to the public internet [10]. Shared machines are quarantined: they can answer connections but cannot start their own [10]. Sharing is available on all plans and does not increase your user count [10][15]. Each friend needs a Tailscale account and the client, then connects to the server's Tailscale address or name. Connections start through relay servers and then try to upgrade to a direct UDP connection; relayed ones are slower, and tailscale status and tailscale ping show which one you got [16]. The free Personal plan covers up to 6 users and is meant for non-commercial use (pricing page, 25 Oct 2026) [17]. Tailscale's access rules work per address and port [10]; whether your specific game's UDP ports pass is something to test, because we found no game list in the documentation. The limit is the client: some platforms, consoles in particular, may not let you install one, and we found no source that lists them. Unused invite links expire after 30 days [10]. Funnel is no substitute: it serves TLS-encrypted connections on ports 443, 8443 and 10000 only [18]. Test: the friend runs tailscale ping <server-name>, then joins.

Way 4: relay through a VPS with WireGuard

You rent a small VPS with a public IPv4 address. Your home server dials a WireGuard tunnel to it, and the VPS forwards the game ports into the tunnel. Outgoing connections work behind CGNAT [24], and WireGuard's persistent keepalive keeps the NAT mapping open [19]. Friends install nothing and connect to the VPS address. TCP and UDP both work (our assessment: destination NAT rules exist for both protocols [20]). The costs are a monthly VPS bill (no prices here, unverified), an extra network hop, and maintenance. Two side effects: with masquerading in the tunnel, the game server sees the VPS tunnel address instead of each player's address, so per-IP bans and limits stop working (our assessment); and if the VPS has a provider firewall, it must allow the game port and the WireGuard port, because such firewalls block inbound traffic by default [21][22]. A complete configuration follows in the example below. Test: sudo wg show wg0 latest-handshakes on both ends shows a handshake time [32], a TCP check from outside as in Way 1, and the real client for UDP.

Way 5: use a game relay service such as playit.gg

playit.gg runs an agent on the machine with your server. The agent connects outwards, players connect to an address on playit's servers, and the traffic runs down the agent's connection to your server [25]. The free tier lists Minecraft Java and Bedrock, Palworld, Valheim and custom UDP tunnels [25]. Free tunnels use global anycast routing, and the provider notes that a player in North America can be routed through Singapore; regional tunnels are a premium feature, as is raising the port count from 4 to 16 [26]. Premium costs $3 per month according to the site on 25 Oct 2026 [25]. The catch is trust and dependence: a third party carries every packet, and your group depends on its service. We have not tested other relay services and take no commission from any of them. Test: join with a game client from outside your network.

What does not work for UDP

Cloudflare Tunnel publishes hostnames for HTTP, HTTPS, Unix sockets, TCP, SSH, RDP and SMB; UDP is not among the documented service types, and non-HTTP services need cloudflared on every client [27]. Cloudflare's product for TCP and UDP is Spectrum. According to its plan table it is not available on the Free plan and is a paid add-on on Pro and Business, UDP applications are a paid add-on on Enterprise only, and a single Minecraft application is allowed from Pro upwards [28]. Spectrum combined with Tunnel works only for HTTP and HTTPS applications, and Bedrock is not supported [29]. So none of this solves a Bedrock server behind CGNAT.

A homelab example

We have not recorded which line type the Bytearium homelab uses (as of 25 Oct 2026), so this is a generic example for your own setup, not a report from ours. Take a Minecraft server with Java on TCP 25565 and Bedrock on UDP 19132 [8], and Way 4. First create a key pair on both machines [19]:

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

On the VPS, enable packet forwarding [30]:

sudo sysctl -w net.ipv4.ip_forward=1

The setting is lost at reboot. To keep it, put the line net.ipv4.ip_forward=1 into a file under /etc/sysctl.d/, for example /etc/sysctl.d/99-forward.conf, which is read at boot [33]. Then write /etc/wireguard/wg0.conf on the VPS. Replace eth0 with the name of the VPS's public interface (shown by ip route show default):

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <VPS private key>
PostUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 10.8.0.2:25565
PostUp = iptables -t nat -A PREROUTING -i eth0 -p udp --dport 19132 -j DNAT --to-destination 10.8.0.2:19132
PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE
PostUp = iptables -A FORWARD -i eth0 -o %i -d 10.8.0.2 -j ACCEPT
PostUp = iptables -A FORWARD -i %i -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 10.8.0.2:25565
PostDown = iptables -t nat -D PREROUTING -i eth0 -p udp --dport 19132 -j DNAT --to-destination 10.8.0.2:19132
PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -o %i -d 10.8.0.2 -j ACCEPT
PostDown = iptables -D FORWARD -i %i -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

[Peer]
PublicKey = <home server public key>
AllowedIPs = 10.8.0.2/32

The PostUp and PostDown fields run commands when the interface goes up and down [31]. The DNAT and masquerade rules follow the destination NAT pattern of the nftables documentation, written here in iptables syntax [20]. On the home server, /etc/wireguard/wg0.conf looks like this. The keepalive of 25 seconds is the value WireGuard names as sensible for a wide variety of firewalls [19]:

[Interface]
Address = 10.8.0.2/24
PrivateKey = <home server private key>

[Peer]
PublicKey = <VPS public key>
Endpoint = <VPS public IP>:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25

Bring the tunnel up on both machines with sudo wg-quick up wg0 [31] and set up start at boot as your distribution documents it. Allow UDP 51820, TCP 25565 and UDP 19132 in the VPS firewall. Then test from a phone on mobile data: join the Java server at the VPS address, and the Bedrock server with the VPS address and port 19132.

Checklist

  • Read the Online Monitor and write down whether you have a public IPv4 address, an IPv6 address, or neither.
  • Ask your provider what a public IPv4 address costs before you build anything else.
  • Check test-ipv6.com on the testing device before you rely on IPv6.
  • Create one port sharing per protocol and port, and never use the exposed host option for a game.
  • Test every setup from outside your home network, and test UDP ports with the real game client.
  • Decide whether your friends will install a client before you choose Tailscale.
  • Allow the game port and the WireGuard port in the VPS firewall, and keep everything else closed.
  • Watch the server log: after masquerading, every player shows up with the tunnel address.
  • Read the terms of your VPS and relay provider before you route a public game server through them.

Primary sources

These sources are the basis of this page. That does not mean every claim was checked individually; whether a review record exists is shown above under “Status”. The interpretation and checklist are our own work.

There is no documented review record for this version yet. The text relies on the sources listed.

How this page was made: Bytearium creates these pages with the help of AI and is responsible for publishing them. AI can be wrong, so we show our sources and review status openly.

  1. FRITZ!Checking accessibility of the FRITZ!Box in the internet
  2. FRITZ!What is DS-Lite and how does it work?
  3. FRITZ!Configuring static port sharing in the FRITZ!Box
  4. AVMFRITZ!Box Hilfe: IPv6-Freigaben
  5. FRITZ!Setting up an exposed host in the FRITZ!Box
  6. J. Weil et al.RFC 6598: IANA-Reserved IPv4 Prefix for Shared Address Space
  7. A. Durand et al.RFC 6333: Dual-Stack Lite Broadband Deployments Following IPv4 Exhaustion
  8. Minecraft WikiServer
  9. Nmap projectPort Scanning Basics
  10. TailscaleShare your machines with other users
  11. MicrosoftTroubleshoot connectivity issues by using Uncomplicated Firewall (UFW) in Azure Ubuntu VMs
  12. Fiber Network WUGFRITZ!Box Anleitung – Portfreigabe über IPv6
  13. Linux man-pagesip-address(8)
  14. Minecraft Wikiserver.properties
  15. TailscaleInviting users vs sharing a device
  16. TailscaleConnection types
  17. TailscalePricing
  18. TailscaleTailscale Funnel
  19. WireGuard projectQuick Start
  20. nftables wikiPerforming Network Address Translation (NAT)
  21. ContaboFirewall
  22. HetznerFirewalls FAQ
  23. ComputerBase forumPortfreigabe bei Fritzbox 6660 Cable (DS-Lite) (Vodafone)
  24. router-tipps.deCGNAT verhindert Portfreigabe: umgehen
  25. playit.ggMake your game server public
  26. playit.ggPlayit Premium
  27. CloudflareTunnel routing, supported protocols
  28. CloudflareSpectrum, Protocols per plan
  29. CloudflareSpectrum, Limitations
  30. Linux kernel documentationIP Sysctl
  31. Linux man-pageswg-quick(8)
  32. Linux man-pageswg(8)
  33. Linux man-pagessysctl.d(5)

This page has no ads and no affiliate links.