Home PC without opening ports: step by step with WireGuard
To access your home PC without opening ports you need two machines that both dial out to the Internet and find each other through a coordination point, instead of one waiting for inbound connections. That is what a private WireGuard mesh does: every machine gets a fixed 100.64.x.x address and they reach each other wherever they are.
Why opening port 22 or 3389 on the router is a risk
An open port on the router is a listening service for anyone scanning your public IP, and residential IPs are scanned continuously. SSH on 22 receives password attempts from the first minute; Windows remote desktop on 3389 has for years been one of the usual entry points for ransomware. Changing the port number only delays the scan. You also need a fixed public IP or dynamic DNS, and you have to keep the exposed service patched, because any flaw in it is exploitable from outside.
CGNAT: why port forwarding does not even work on many fibre lines
With CGNAT, your carrier shares one public IPv4 address among several subscribers and the address you see on your router sits inside 100.64.0.0/10, the RFC 6598 shared address space. An inbound packet addressed to that public IP does not know which subscriber to go to, so the port forward you configure on your router never receives anything. The way out is to reverse the direction: the home PC opens the connection outwards itself and keeps it alive. That is exactly what a mesh network node does, which is why it works the same with a fixed IP, a dynamic one or CGNAT.
Port forwarding, VPN on the router or mesh network: what each one exposes
| Option | What is exposed to the Internet | Works behind CGNAT? | What you maintain |
|---|---|---|---|
| Forwarding port 22 or 3389 | The service itself (SSH or RDP), to any scanner | No | A fixed IP or dynamic DNS, and patches for the exposed service |
| WireGuard server on the router | One UDP port, with no credentials to guess | No, without a public IP of your own | Each client's keys, the router and the dynamic DNS |
| Mesh network (prialo) | No inbound port at home | Yes, through STUN and relay | Nothing at home; the control plane, if you self-host it |
Step by step: joining the home PC and the laptop to a private prialo network
The whole route is five steps and none of them touches the router. Today it is done with the self-hosted package and the command-line client on Linux or macOS; the Mac and iPhone apps are in Apple's review queue and the Windows client is an early build, with no installer or signature. If you would rather not run a server, the hosted service will give the same result as soon as the apps are available.
- Control plane: on a Linux VPS with Docker, download the self-hosted prialo package, copy .env.example to .env with the three secrets and start it with docker compose up -d. Open 50051/tcp, 4430/tcp and 3478/udp on the firewall; never 8080.
- TLS pin: read the server's fingerprint with docker compose logs prialo-server | grep -oE 'sha256:[0-9a-f]{64}' | sort -u. Exactly one must come out; copy it over a channel that is already yours, never over the link you want to protect.
- Enrolment key: create a single-use key from inside the container against the admin API (POST /api/v1/auth/preauth-keys with reusable:false). One key per machine; keys expire and can be revoked.
- Home PC: install the node as a service with the command below. prialo status must say "Control: tls, pinned" and show an IP inside 100.64.0.0/10; prialo ip prints it on its own.
- Laptop or phone: repeat the installation with another enrolment key. From then on ssh [email protected] (the IP prialo ip gave you on the PC) works from any network, and an SSH client on your phone reaches it at the same address.
sudo PRIALO_AUTH_KEY='<enrolment key>' prialo install \
--server=control.example.com:50051 \
--relay=control.example.com:4430 \
--tls-pin=sha256:<fingerprint>
RDP, SSH and files over the private network: what changes and what does not
Inside the mesh, the home PC is used exactly as on the local network: ssh to its 100.64.x.x, remote desktop to 100.64.x.x:3389 or files over SMB, without touching each program's settings. What changes is that none of those services listens on the Internet any more: only the machines in your network reach them, and each one identifies itself with its WireGuard key, not a password. When the two machines manage to talk directly, latency is that of the shortest path; if the carrier prevents it, the relay on your server forwards the encrypted packets, and then an SSH session uses well under 1 MB per hour and a remote desktop session between 0.5 and 1 GB per hour.
Frequently asked questions
Can I access my home PC without opening ports if I am behind CGNAT?
Yes. Behind CGNAT port forwarding does not work because the public IP is shared with other subscribers, but a mesh network needs no inbound connections: the home PC dials out to the control plane itself and, when there is no direct path, the relay forwards the encrypted traffic.
Do I need a fixed IP or dynamic DNS for the private network?
No. The private network does not depend on your public IP: every machine gets a fixed 100.64.x.x address inside the mesh and keeps it when it changes wifi, carrier or country. The only DNS name required is the control plane's, which lives on the VPS.
Is remote desktop slower over the mesh network?
Remote desktop over the mesh network runs at the speed of the direct path between the two machines whenever WireGuard manages to open it, which is the usual case. If it goes through the relay, the limit is your server's bandwidth; one session uses between 0.5 and 1 GB per hour.
What happens if I lose the server's TLS pin?
The TLS pin is the identity of your control plane: every node rejects a server that does not present that key. That is why the control-tls.key file is copied off the host, encrypted, as soon as the server starts for the first time; without that copy, losing the server means enrolling every machine again.
Would you rather run your own server? Guide to the self-hosted prialo package