// concept

Port forwarding — what it is, why home routers default to off

Updated 2026-05-10

What's actually happening

Your home router gives every device on the LAN a private IP — 192.168.1.42, 10.0.0.5, things in those reserved blocks. None of those addresses are reachable from the public internet; the entire LAN sits behind one shared public IP that the router holds.

When your laptop opens a connection out (to lrok.io, to GitHub), the router NATs the connection — it remembers "laptop:54231 → lrok.io:443" and rewrites the source IP/port so the response comes back to the right device.

NAT works outbound. It does not work inbound. If a random server on the internet wants to send a packet to your laptop, the router has no entry in its NAT table for that connection and drops it.

Port forwarding is the manual override: "for incoming TCP on port 25565, ignore NAT, send it to 192.168.1.42:25565." Now Minecraft players can connect.

Setting it up

Every router has a "Port Forwarding" or "Virtual Server" page. You specify:

  1. The external port (what the public IP receives on, e.g. 25565)
  2. The internal IP (which LAN device, e.g. 192.168.1.42)
  3. The internal port (what port on that device, often the same)
  4. The protocol (TCP, UDP, or both)

Once you save, traffic to your-public-ip:25565 lands on your laptop's port 25565.

Why this stopped working

Two reasons:

Carrier-grade NAT (CGNAT). Most residential ISPs in 2026 — and almost every mobile carrier — put hundreds or thousands of customers behind one shared public IPv4. The "public" IP your modem reports is itself a private IP; there's another layer of NAT at the ISP. Port forwarding on your router doesn't help because your router's WAN side is also private. You can't punch a hole through a NAT you don't control.

T-Mobile home internet, Verizon 5G home, Starlink, Comcast in some markets — all CGNAT by default. The fix is "static IP" service (often $10-20/mo extra) which puts you back on a real public IPv4.

IPv4 exhaustion. ISPs are out of v4 addresses; they don't hand out more unless you pay. IPv6 works (no NAT, every device gets a real address) but only when both endpoints support it — which most public services in 2026 still do, but inconsistently.

Why a reverse tunnel solves the same problem differently

A reverse tunnel inverts the direction. Instead of accepting incoming connections (which you can't if you're behind CGNAT), your machine opens an outbound connection to a relay, and the relay forwards traffic back through that pipe.

[player on internet] -> [tunnel relay] -> [open conn] -> [your Minecraft server]

The relay has a real public IP. It's the relay's port forwarding, not yours. You don't need router access, you don't need a static IP, you don't need to fight CGNAT. The cost is one outbound connection from your machine to the relay (which CGNAT lets through happily — that's what NAT is built for).

This is what services like lrok do. lrok tcp 25565 opens an outbound multiplexed connection from your laptop, registers a public TCP endpoint, and forwards traffic in. Players connect to tcp.lrok.io:31420, the bytes traverse the relay, your Minecraft server sees a normal localhost connection.

When port forwarding still wins

If you control the router, your ISP gives you a real IPv4, and you don't mind exposing your home IP to the world — port forwarding is free, has no extra latency, and doesn't depend on a third party. Self-hosted home servers behind business-class internet (or a fiber connection that includes a static IP) work fine.

If any of those conditions fail, a tunnel is the simpler answer.

Local concerns either way

Whatever method you use, the moment your service is on the public internet, scanners will hit it within hours. A 30-day-old IPv4 with no firewall sees 100k probes per day on common ports (22, 80, 3389, 3306). Treat any tunnel-exposed or port-forwarded service as if it were on the open internet — because it is.

For dev work, prefer named subdomains with reasonable security (basic-auth on lrok, OAuth proxies, signed-URL expiry) over public ports for everything. The Discord-bot guide and the stripe-webhook guide both walk through that pattern.

// shipping?

lrok gives your localhost a public HTTPS URL with a reserved subdomain on the free plan. $9/mo flat for unlimited.

Related