OnepilotDownload
Onepilot mascot

How to SSH Into a Machine Behind NAT Without Port Forwarding

Four ways to reach a machine behind NAT from outside your network: port forwarding, a mesh VPN, a reverse SSH tunnel, or an outbound relay. What each costs in setup, and which ones survive CGNAT.

sofiane8910

by sofiane8910 · July 25, 2026 · 9 min read

Onepilot runs these agents from your iPhone, download it on the App Store.

You want to reach a machine at home from somewhere else. A Raspberry Pi, a Mac mini in a closet, a NAS, a work laptop. Every guide tells you to forward a port on your router, and plenty of people cannot, either because they do not control the router or because their ISP put them behind CGNAT and the port never opens no matter what they configure. Port forwarding is one answer to this problem. It is not the only one, and on a modern connection it is often not the best one.

Can you SSH without port forwarding?

Yes. There are four practical ways to reach a machine behind NAT, and only the first one needs an inbound port. The other three work by having the host make an outbound connection and holding it open, then riding that connection backwards when you want in.

That distinction is the whole trick. Almost every home and office network blocks unsolicited inbound connections and allows outbound ones. Anything built on an outbound connection therefore works in places where port forwarding is impossible, including behind CGNAT, on a corporate guest network, and on a phone hotspot.

Why can't you reach a machine behind NAT from outside?

Because the machine does not have an address the internet can route to. Your Pi has something like 192.168.1.50, which is a private address that exists only inside your network. Millions of other networks use the same range. The only publicly routable address in your house belongs to the router.

When your Pi opens a connection outwards, the router rewrites the packet to come from its own public address and writes down a mapping so it knows where to send the replies. That mapping is what makes the return traffic work. When a connection arrives from outside unprompted, no such mapping exists, the router has no idea which of your devices it is for, and it drops the packet. Port forwarding is simply a permanent, hand-written mapping that says "anything arriving on port 22 goes to 192.168.1.50."

Does port forwarding still work if your ISP uses CGNAT?

No, and this is the single most common reason people find themselves searching for an alternative. Under carrier-grade NAT your router does not get a public address at all. It gets another private address from the ISP, and the ISP runs its own NAT layer in front of hundreds or thousands of customers who share a pool of real addresses.

You can forward port 22 on your own router perfectly and it will still be unreachable, because the packet never gets as far as your router. The ISP's NAT drops it first, and you have no way to add a rule there. To check, compare the WAN address shown in your router's admin page against what curl ifconfig.me reports from inside the network. If they differ, you are behind CGNAT. If the router's WAN address starts with 100.64. through 100.127., that is the reserved CGNAT range and the answer is definitive.

Some ISPs will move you off CGNAT or sell you a static address if you ask. Many will not. Everything below works either way.

How do you access your home server from anywhere?

Option 1: forward a port on your router

The classic approach. Log into the router, map an external port to your machine's internal address and port 22, reserve that internal address in DHCP so it does not move, and point a dynamic DNS hostname at your home address so you can find it when the ISP rotates your IP.

It works, it is free, and nothing sits between you and your host. The costs are that you need control of the router, it breaks under CGNAT, and you have now published an SSH port to the entire internet. Within hours it will be found by scanners. That is survivable with key-only authentication, a non-default port, and fail2ban, but it is a running security obligation rather than a one-time setup.

Option 2: put both machines on a mesh VPN

Install something like Tailscale, WireGuard, ZeroTier, or NetBird on the host and on whatever you connect from. Both devices join a private overlay network and get stable addresses on it, and you SSH to the overlay address as if the two machines were on the same LAN.

This is the most popular modern answer and it deserves the reputation. It handles CGNAT, it needs no router access, traffic is encrypted independently of SSH, and once it is running you stop thinking about it. The cost is that every device you connect from also needs the VPN installed and logged in, which is fine for two laptops and more friction when you want to reach a box from a borrowed machine or a locked-down phone. You are also trusting the coordination service that hands out keys, unless you self-host the control plane.

Option 3: hold a reverse SSH tunnel to a server you own

If you already rent a small VPS with a public address, the host can dial out to it and expose its own SSH port there:

ssh -N -R 2222:localhost:22 user@your-vps.example.com

That tells the VPS to listen on port 2222 and forward anything arriving there back down the tunnel to port 22 on the machine that dialled out. From anywhere else you then SSH to the VPS on port 2222 and land on the home machine.

Two things make the difference between a demo and something you can rely on. First, the tunnel dies whenever the network hiccups, so supervise it with autossh or a systemd unit with Restart=always rather than running it by hand. Second, by default the forwarded port binds to localhost on the VPS, which means you have to SSH into the VPS first and hop from there. Setting GatewayPorts yes in the VPS sshd config makes it reachable directly, and also makes it reachable by everyone else who can reach that VPS, so leave it bound to localhost unless you have a specific reason and a firewall in front of it.

The real cost here is that you are now running and patching a second server whose only job is to be a meeting point.

Option 4: let the host dial out to a relay

The same shape as a reverse tunnel, without you operating the meeting point. The host holds an outbound connection to a relay run by someone else, and your client connects through the relay, which splices the two together. Cloudflare Tunnel works this way, as do the connection layers built into several remote access products.

Setup is usually one command on the host and nothing on the network. It works behind CGNAT. The trade is that a third party operates the middle, so the question becomes what that middle can actually see, which is worth answering before you pick one.

Which option should you pick?

ApproachWorks behind CGNATNeeds router accessClient-side setupYou operate
Port forwardingNoYesNoneYour router, plus an exposed port
Mesh VPNYesNoVPN on every clientNothing, unless self-hosting the control plane
Reverse SSH tunnelYesNoNoneA VPS, plus tunnel supervision
Outbound relayYesNoNoneNothing

Rules of thumb. If you control the router, are not behind CGNAT, and are comfortable hardening an exposed SSH port, forwarding is the simplest thing that works and nothing sits in the middle. If you connect from a small, fixed set of your own devices, a mesh VPN is the best general answer available today. If you already run a VPS, a reverse tunnel costs you nothing extra. If you want to reach a host from a device you cannot install a VPN on, a relay is the only option that asks nothing of the client.

What does each option cost you in trust?

Worth separating two questions that get blurred together: who can reach your SSH port, and who can read your session.

Reading is the easier one. SSH encrypts end to end between your client and the host, and it authenticates the host with a key you can verify. A relay, a reverse tunnel, or a VPN carries that traffic as ciphertext and cannot decrypt it, assuming you checked the host key the first time you connected. If the encryption held, the middle sees bytes.

Reachability is where the options genuinely differ. Port forwarding exposes your port to everyone. A mesh VPN exposes it to devices on your overlay network, and the coordination service decides which devices those are. A relay exposes it to whoever the relay says is authorised. In each case you are trusting some system to decide who gets to knock. That is the question to ask of any of these products: not "can they read my traffic," which SSH already answers, but "what exactly grants a device permission to reach my host, and can I see and revoke that list."

The short version

Port forwarding is not a requirement, it is one option among four, and it is the only one that fails under CGNAT. Everything else works by making the host dial out. Pick based on what you are willing to operate: a router rule and an exposed port, a VPN on every client, a VPS you keep patched, or a relay somebody else runs.

If the device you connect from is a phone, the calculus shifts again, because installing and maintaining a VPN client on a phone that keeps switching between wifi and cellular is its own small chore. Onepilot is an iPhone app that pairs a server by scanning a code, provisions a relay for hosts that need one, and keeps the shell running on the host so a dropped connection does not take your work with it. Once you can reach the host, the failures worth knowing are connection refused, Permission denied (publickey), and sessions that drop after connecting. For what actually gets installed on a host, see the pairing docs.

FAQ

Can you SSH without port forwarding?

Yes. Port forwarding is only one way to solve the problem, and it is the only one that requires an inbound connection. The alternatives all work by having the host make an outbound connection instead: a mesh VPN such as Tailscale or WireGuard, a reverse SSH tunnel to a server you already own, a tunnel service such as Cloudflare Tunnel, or a managed relay built into a client. Outbound connections are allowed by default on almost every home and office network, which is why these work where port forwarding cannot.

Why can't you SSH into a machine behind NAT?

A machine behind NAT has a private address such as 192.168.1.50 that means nothing on the public internet. Your router owns the single public address, and when a connection arrives from outside, the router has no rule telling it which internal machine the traffic belongs to, so it drops it. Outbound connections work because the router creates that mapping itself when your machine initiates the connection.

Does port forwarding work if your ISP uses CGNAT?

No. Under carrier-grade NAT your router does not have a public address of its own; it shares one with many other customers behind the ISP's own NAT layer. You can forward a port on your own router and it will still be unreachable, because the ISP's NAT has no rule for it either and you cannot add one. CGNAT is common on mobile broadband and increasingly on fibre, and it is the usual explanation when port forwarding is configured correctly but still does not work.

Is a reverse SSH tunnel secure?

The tunnel itself carries normal SSH traffic, so it is encrypted end to end between your client and your host. The risks are operational rather than cryptographic: the relay point is a server you have to keep patched, the tunnel dies silently when the network hiccups unless you supervise it with autossh or a systemd unit, and binding the forwarded port to all interfaces with GatewayPorts exposes it to anyone who can reach that server. Bind to localhost and reach it through a second SSH hop unless you have a reason not to.

Related reading

Run your AI agents from your iPhone

Download Onepilot on the App Store.

See also: the three-layer agent overview, run Hermes on iPhone, or all articles.