Self-hosting behind CGNAT: how to reach your homelab anyway
The forwarding rule was probably never the problem. One comparison tells you whether your ISP gave you an address that inbound traffic can reach at all.
You built the thing. It runs, it works on the LAN, and now you want to reach it from outside. You forward the port, and nothing happens. You check the rule three times, reboot the router, try a different port, and it still does not work.
If that describes your evening, there is a good chance the rule was never the problem. Your ISP may simply not have given you an address that inbound connections can reach, and no router setting will change that. Here is how to confirm it in about a minute, and what the actual options are once you have.
Confirming you are behind CGNAT
One comparison settles it. Find two numbers and see whether they match.
-
Your actual public IP
Open Public IP and Geo/ASN. This is the address the internet sees when you make an outbound connection.
-
Your router's WAN address
From the router's status page, or without logging in at all: run a UPnP and NAT-PMP discovery, which asks the gateway what external address it believes it has.
If those two match, you have a routable address and port forwarding is possible. If they differ, something between your router and the internet is translating again, and that is the end of the matter as far as forwarding goes.
| Router WAN address | What it means |
|---|---|
100.64.0.0 to 100.127.255.255 | Carrier grade NAT. This range exists specifically for it, so this is conclusive. |
10.x.x.x | Private. Either CGNAT or another router in front of yours. |
192.168.x.x | Private. Usually an ISP modem still in router mode, so check for double NAT first. |
172.16.x.x to 172.31.x.x | Private. Same story. |
| Anything else, matching your public IP | You are fine. Your forwarding rule has a different problem, covered in port forwarding not working. |
A second confirmation, if you want one: a traceroute from your network will usually show a hop in the 100.64.0.0/10 range one or two steps out. That is your provider's translation layer.
Settle it in a minute
Public IP and Geo/ASN gives you the address the internet sees, UPnP discovery asks your gateway what it thinks its external address is, and External Port Check has a server on the internet try to connect back. Between them you know exactly what you are working with.
Why forwarding cannot work
IPv4 addresses ran out. Rather than give every customer a unique one, many providers now put hundreds or thousands of customers behind a single public address and translate on the way out. Outbound connections work perfectly, because the translation table remembers which internal connection each outbound flow belongs to.
Inbound is the problem. When a packet arrives at that shared public address on port 443, the provider's equipment has no entry telling it which of a thousand customers it belongs to, so it drops it. Your router never sees it. Your forwarding rule is correct and completely irrelevant.
This is worth internalising because it explains the shape of every workaround below: they all involve your server making an outbound connection first, so that a path exists for return traffic. You are not opening a door, you are reaching out and holding the line open.
The five options, compared
| Approach | Good for | Trade-off |
|---|---|---|
| Ask your ISP for a public IP | Everything. It removes the constraint entirely. | Sometimes free, sometimes a small monthly fee, sometimes only on a business plan. Always worth asking first. |
| Mesh VPN (Tailscale, Netbird, ZeroTier, plain WireGuard with a relay) | Private access for you and a few people. The default answer for most homelabs. | Every client needs the software. Not usable for a public website. |
| Outbound tunnel (Cloudflare Tunnel and similar) | Publishing a web service publicly with no open ports at all. | Your traffic passes through a third party. Non HTTP protocols may be restricted or unsupported. |
| IPv6 | Direct connections with no middleman, when both ends have it. | Only works when the client also has IPv6, which is unpredictable. |
| VPS reverse tunnel | Full control, any protocol, your own domain and certificates. | You now run a second machine and its security is your problem. |
Two notes before you pick. First, ask your ISP. It is the fastest fix and people routinely skip it assuming the answer is no. A static or public IPv4 address is a normal product and is often cheaper than expected.
Second, be honest about the requirement. "I want to reach my services from my phone" and "I want to host a public website" look similar and have completely different answers. If only you and a couple of other people need access, a mesh VPN is simpler, faster and more private than anything that involves publishing a service to the internet.
The IPv6 route, and its catch
IPv6 solves this cleanly in principle. There is no address shortage, so your provider can hand you a routable prefix, and every device on your network can have a globally reachable address. No NAT, no translation layer, nothing to forward.
Three practical caveats:
You still need a firewall rule. Reachable does not mean open. IPv6 firewalls block inbound by default, which is correct, and you allow the specific port to the specific host. The mental model is "allow", not "forward".
Your prefix may change. Many residential providers rotate the delegated prefix, so your server's address changes with it. Dynamic DNS with an AAAA record handles this, but it needs setting up.
The client has to have IPv6 too. This is the real catch. Mobile networks are mostly fine. Home connections vary enormously. Corporate and hotel networks are frequently IPv4 only, which means the one time you urgently need access is the time it does not work.
IPv6 is an excellent addition and a risky sole strategy. A useful test is simply to check whether a service resolves and connects over IPv6 from the networks you actually use, using a DNS lookup for the AAAA record and a TCP connect to the port.
The VPS reverse tunnel
The most flexible option, and the one worth understanding even if you choose something else, because it shows what the managed services are doing for you.
Rent the cheapest virtual server you can find. It has a real public IP. Your home server opens a WireGuard tunnel outbound to it and keeps it up. The VPS runs a reverse proxy that accepts public traffic and forwards it down the tunnel. Your domain's DNS points at the VPS.
From the internet's point of view the service lives on the VPS. From your point of view it runs at home. Nothing inbound ever touches your router.
What this buys you over a managed tunnel: any protocol, not just HTTP. Your own certificates. No third party terminating your TLS. A fixed public IP you control, which matters if anything you run needs a stable address for allowlisting.
What it costs you: a second machine that needs patching, a firewall that needs configuring, and a tunnel that needs monitoring. The VPS is now internet facing infrastructure you are responsible for. Budget a few pounds or dollars a month and an hour of setup.
A practical note: give the tunnel a keepalive. Home connections and NAT tables drop idle flows, and a tunnel that only reconnects when traffic arrives will appear broken exactly when you need it.
Verifying it actually works from outside
Whatever you choose, test it properly. Testing from inside your own network proves nothing: your traffic never leaves, so it never exercises the part you just built.
-
Turn Wi-Fi off and use cellular data
The simplest honest test. Different IP, different route, different provider.
-
Check whether the port is genuinely reachable
External Port Check asks a server on the internet to connect back to a port on your public IP. Use it to confirm what is exposed, and equally to confirm what is not. After setting up an outbound tunnel, every port on your public IP should be closed, and verifying that is the point.
-
Resolve the name from a public resolver
A DNS lookup against
1.1.1.1tells you what the world sees, which is frequently not what your local resolver returns if you also run internal DNS. -
Check the certificate and the status code
A TLS inspection confirms the certificate the public endpoint is serving, and an HTTP(S) Check shows the status and redirect chain. A tunnel that terminates TLS itself will present a different certificate than you expect, which is worth knowing before you debug it as a fault.
-
Save the sequence and re-run it
Chain those checks into one automation pointed at your own hostname. Tunnels go down, dynamic addresses move, certificates expire. Running the same four checks on a schedule means you find out before a friend tells you, and Run History keeps the results so you can see when it changed.
A word on exposing things
Getting past CGNAT is a networking problem. Deciding what to expose is a different one, and the answer is usually less than you think.
A mesh VPN keeps services entirely off the public internet while still letting you reach them from anywhere, and for a homelab that is the right default. Reserve public exposure for the things that genuinely need to be public, put authentication in front of them, and keep them patched. An admin panel with a weak password on a public address gets found within hours, because the scanning is continuous and automated.
The short version
Compare your public IP against your router's WAN address. If they differ, particularly if the WAN address is in 100.64.0.0/10, no forwarding rule will ever work and you need an approach where your server connects outbound instead. Ask your ISP for a public address first, use a mesh VPN if access is just for you, use an outbound tunnel or a VPS reverse tunnel if something must be public, and treat IPv6 as a useful addition rather than the whole plan. Then test from a network that is not yours.
Frequently asked questions
How do I know if I am behind CGNAT?
Compare your public IP with your router's WAN address. If they differ, something is translating again between you and the internet. A WAN address in the 100.64.0.0 to 100.127.255.255 range is conclusive, because that range exists specifically for carrier grade NAT.
Can I port forward if I am behind CGNAT?
No. Inbound packets arrive at a public address shared by many customers, and the provider's equipment has no way to know which one they belong to, so it drops them. Your router never sees the traffic and the rule is irrelevant.
What is the easiest way to reach a homelab behind CGNAT?
A mesh VPN such as Tailscale, Netbird, ZeroTier or plain WireGuard with a relay. It requires no open ports, works from anywhere, and keeps the services off the public internet entirely. For access that is just for you and a few people, it is the right default.
Does IPv6 solve CGNAT?
Partly. An IPv6 prefix gives your devices globally routable addresses with no translation, but you still need a firewall rule to allow inbound traffic, your prefix may rotate, and the client also needs IPv6. Corporate and hotel networks are often IPv4 only.
How does a VPS reverse tunnel work?
A cheap virtual server with a public IP runs a reverse proxy. Your home server opens a tunnel outbound to it and keeps it up, and public traffic arrives at the VPS and travels down the tunnel. Nothing inbound ever touches your router.
Should I just ask my ISP for a public IP address?
Yes, and do it first. A static or public IPv4 address is a normal product, sometimes free, often a small monthly fee, and it removes the constraint completely. People routinely skip asking because they assume the answer is no.
How do I verify my setup works from outside?
Test from a network that is not yours, such as a phone on cellular data. Use an external port check that connects back to your public IP to confirm what is and is not exposed, resolve the name against a public resolver, and check the certificate the public endpoint actually serves.
NetDebug Toolkit