Run a Minecraft server on your own PC and let friends join — even when port forwarding won't work. Your friends just install the modpack. No VPN app, no account, nothing to configure.
Players only need the mod — pick the loader your modpack uses (1.21.1):
Mod for Fabric·Mod for NeoForge
Hosting a server? Home agent (public mode — no VPS):
macOS (Apple Silicon)·macOS (Intel)·Linux
Relay installer (optional, self-hosted mode)·checksums
If you're reading this, you probably already did everything right: you set up a server, it runs fine on your own computer, friends on the same Wi-Fi can join — but friends over the internet can't, and the "port forwarding" step from the tutorial just doesn't work. This is almost never your fault.
A 60-second recap of how joining is supposed to work. Your home has one address on the internet, your public IP (like a street address). Your server waits behind a numbered "door" called a port (25565). The tutorial had you set up port forwarding on your router — "send connections on port 25565 to my PC" — and give friends your IP. Their game connects to your-IP:25565, and that's it.
Why it fails today: the internet ran out of the old address type (IPv4), so most home ISPs stopped giving each customer their own. Instead they put you behind CGNAT — hundreds of homes share one public IP, inside the ISP's equipment you can't touch. So forwarding a port on your router does nothing: the address the world sees isn't yours. You can follow every tutorial perfectly and it still won't work, because the problem is upstream at your ISP.
How to confirm: check your router's "WAN" IP. If it starts with 100.64.–100.127., that's a shared CGNAT address. Or if an "open port check" site never sees your server, same conclusion.
A dynamic IP just changes now and then — a free DDNS service follows it, no problem. The blocker is having no public IPv4 of your own at all, which is what CGNAT means. Static vs dynamic doesn't matter here.
IPv6 is the new, effectively unlimited kind of address, and many ISPs that CGNAT your IPv4 still give you a real, public IPv6.
Two catches: a friend who only has IPv4 cannot reach an IPv6-only server (still common), and some ISPs rotate your IPv6 prefix. If IPv6 doesn't cover everyone, read on.
Two established approaches get around the address problem. Both work; each has a cost.
You run a small program that opens a tunnel to the provider; they give you a public address and relay all traffic through their servers to your PC.
A "VPN" here means a private virtual network. You install their app on each machine; they form a little network so your friend's PC and your server act like one LAN.
| playit.gg | Tailscale / ZeroTier | Selfhosted Linkage | |
|---|---|---|---|
| Works behind CGNAT | yes | yes | yes |
| Direct (low-latency) | no — always relayed | yes | yes |
| Account / login | required | required | none |
| Extra app to install | a client | a VPN client | none — it's in the modpack |
| Scope | one port | a whole network | one port |
Every peer-to-peer option here — Tailscale, ZeroTier, and ours — works the same way underneath, and it decides whether you ever spend money.
The catch: the free public relays are shared and rate-limited — equally true of Tailscale's relays and the free relays our public mode uses. A direct connection is fast; a relayed one over free infrastructure can feel laggy.
Selfhosted Linkage keeps the good part — Tailscale-class direct connections — and drops the friction. It uses iroh, peer-to-peer networking from the same family as Tailscale's, but built into the mod, not as a separate VPN.
For almost everyone, this is the whole thing: no server to rent, no account.
Skip this unless the rule above sent you here. The fix is to run your own relay near that friend. It costs a few dollars a month.
A VPS is a small computer you rent by the month, running in a datacenter, always on with its own public address — the thing your home connection lacks. You control it over a secure remote connection called SSH. For a relay it does one light job, so the cheapest one is plenty.
Any provider works — we don't endorse one. Two things matter:
The cheapest CPU/RAM tier is fine. Choose Ubuntu (22.04 or 24.04). You also need a name for it: point a subdomain from a cheap domain (any registrar) at the VPS's IP, or use a free DuckDNS subdomain — the HTTPS certificate is obtained automatically.
VPS IP 203.0.113.10, name relay.example.com pointed at it, home server on port 25565.
On the VPS (ssh root@203.0.113.10):
# 1. install Caddy (handles the HTTPS certificate automatically)
sudo apt update && sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy
# 2. run the one-line relay installer
curl -fsSL https://linkage.blopybox.net/dl/linkage-relay-install.sh -o install.sh
sudo bash install.sh relay.example.com
Then, in your VPS provider's firewall panel, allow inbound UDP 7842.
On your home server (from the host agent bundle):
sudo ./install.sh --relay-url https://relay.example.com --mc-addr 127.0.0.1:25565
It prints a ticket. Paste it once into the registry file the installer created on the VPS:
# /etc/iroh-relay/webroot/.well-known/selfhosted-linkage.json
{ "version": 1, "servers": { "25565": { "transport": "iroh",
"relay_url": "https://relay.example.com", "ticket": "PASTE-THE-TICKET-HERE" } } }
The key is saved, so the ticket stays the same across restarts. Friends then type relay.example.com as the address and 25565 as the port. Direct connections still happen automatically; when someone can't go direct, they bounce through your nearby relay.
Self-hosted mode is entirely yours to run — not a service we operate for anyone.
Everything is open source, and the networking is a thin wrapper over the stock iroh tools.