Yes — you can reach a computer over the internet without opening a single inbound port. The tools that make this work all use outbound connections: a mesh VPN such as Tailscale joins your devices into one virtual network, an SSH tunnel routes traffic through a reachable intermediate host, and CLIAnywhere's daemon dials out so your phone can attach to its terminal sessions directly. Because the PC initiates the connection, the router never needs a port-forwarding rule, and no public IP is required — even behind carrier-grade NAT.
Short Answer
Port forwarding exists to let inbound traffic through NAT; anything that connects outbound does not need it. For whole-network access, a mesh VPN like Tailscale is the established answer. For terminal access specifically, CLIAnywhere needs no VPN layer: its daemon runs on your PC, connects out, and your iOS, Android or web client reaches it peer-to-peer over DTLS — with an encrypted relay as fallback when direct connections are not possible. Nothing listens on the public internet either way.
Why This Is Difficult
Home and small-office internet connections are built for browsing, not for being reached. Your router performs NAT: many devices share one public address, and the router only forwards inbound packets to a device if a rule explicitly says so. That rule is port forwarding — a manual, per-service entry in your router's config.
Internet
│
▼
┌─────────────────────┐
│ Router (NAT) │ inbound connections are dropped
│ │ unless a forwarding rule exists
└──────────┬──────────┘
│ rule: external 22 → 192.168.1.50:22
▼
┌─────────────────────┐
│ Your PC (sshd) │ now reachable by anyone
│ 192.168.1.50 │ who scans your address
└─────────────────────┘
This model has three problems. First, exposure: every forwarded port is an entrance from the entire internet to a service on your LAN, and automated scanners find exposed services within minutes of them appearing. Second, it often is not even possible: many ISPs put customers behind carrier-grade NAT, so there is no public address to forward to, and dynamic addresses change the target out from under you. Third, it is fragile — firmware updates reset rules, and moving the PC to another network means starting over.
The alternative is to flip the direction. Outbound connections pass through NAT without any configuration — that is how all your normal traffic works. Tools that have the PC dial out, and the client meet it there, need no ports opened at all.
Common Solutions
Option 1: Mesh VPN (Tailscale, WireGuard)
Tailscale and similar mesh VPNs install an agent on each device and join them into a virtual private network with private IP addresses, built on WireGuard. Once your PC and phone are both on the tailnet, every service on the PC — SSH, SMB, a dev server — is reachable as if you were at home, with traffic encrypted between devices.
The trade-offs: you install and sign in to the VPN on every device you want to connect from, all traffic may route through the VPN while it is active, and some corporate or public networks block the UDP flows the fast paths depend on. For teams and multi-service access it is a solid, well-established choice.
Best for: reaching many services on a whole networkOption 2: SSH Over a Tunnel
If you already run SSH, you can keep it and remove the port forward: put the PC behind a mesh VPN as above, or rent a small public server and use a reverse tunnel — ssh -R from the PC to the server, then SSH from your phone to the server. This is the classic setup and works anywhere.
The costs are setup and fragility: you are now maintaining a VPN, or a public server that itself must be kept patched, plus autossh to keep the tunnel alive. And plain SSH sessions still die with the mobile connection — the tunnel solves reachability, not session persistence, so tmux remains necessary.
Best for: people who already operate SSH infrastructureOption 3: CLIAnywhere
CLIAnywhere was designed for this constraint. Its open-source daemon runs on your PC and makes only outbound connections; your phone or browser client reaches it directly, peer-to-peer over DTLS when the network allows, and through an encrypted relay as fallback when it does not. No port forwarding, no UPnP, no public IP, no VPN to join.
Sessions are persistent — they keep running on the PC through disconnections — and traffic is end-to-end encrypted with keys negotiated via SPAKE2, so the relay only ever sees ciphertext. Beyond the terminal you get file browsing with download support and access to web pages on your PC's localhost or LAN.
Best for: terminal and localhost access with zero network configuration Your phone Your PC (daemon)
│ │
└──────── outbound only ─────────┘
1. peer-to-peer, DTLS ← preferred, direct
2. encrypted relay (WSS) ← fallback when NAT blocks P2P
no forwarded ports · no public IP · router untouched
Using CLIAnywhere
Run the Daemon on the PC
Download the daemon for Windows, macOS or Linux from GitHub Releases, or build it from source. Full tabbed build commands for every platform are in the setup guide. The daemon starts and dials out — you never touch your router's settings.
Install a Client on Your Phone
Android: install CLIAnywhere from Google Play. iOS: available on the App Store — see the download page. No install allowed on the machine you are sitting at? The Web App at webapp.clianywhere.com works in any browser and connects to the same PCs.
Link Once, Connect Anywhere
Pair the app with the daemon using an access key — paste it into the daemon or scan its QR code. The key stays on your devices and is used only for the local SPAKE2 key exchange. From then on the PC appears in your device list, and tapping it opens a live terminal whether you are on the sofa Wi-Fi or on cellular in another country.
| Port forwarding required | No |
|---|---|
| Public IP required | No (works behind NAT and carrier-grade NAT) |
| UPnP / router configuration | None |
| Connection mode | P2P direct (DTLS), encrypted relay (WSS) fallback |
| Encryption | SPAKE2 key exchange + AES-256-GCM |
| Windows / macOS / Linux host | Yes |
| iOS / Android / Web client | Yes — see the download page |
| Persistent sessions | Yes |
| Account model | One account, multiple PCs, per-PC local Security Code |
| Open-source daemon | Yes — github.com/CLIAnywhere/clianywhere_daemon |
Example: Restarting a Service From a Café
Your home PC runs a long job — a model training run writing to a log, or a dev box serving a project. Half an hour into a trip you get a message that something stopped. You are on café Wi-Fi, behind someone else's NAT, with no route to your home network.
You open the web app at webapp.clianywhere.com, pick your PC from the device list, and the terminal session is exactly where you left it — the daemon's outbound connection was never interrupted, because nothing about your location changed anything at home. You check the log with tail, find the crash, restart the service, watch it come up healthy, and close the laptop. Total time: two minutes; router configuration: none.
The same session is still alive when you get home; the desktop terminal shows every command you ran from the café.
Security
Not opening ports is itself a security decision: services that never accept inbound connections from the internet cannot be found by scans. CLIAnywhere adds end-to-end encryption on top — keys negotiated with SPAKE2, traffic encrypted with AES-256-GCM — so the relay in the fallback path only ever sees ciphertext, and each PC is protected by its own locally generated Security Code. See how CLIAnywhere handles security for the full model.