All posts

Guide · 8 min read

How to access a server behind NAT

A server behind NAT can make outbound connections but not accept inbound ones. The four ways around that, what each one exposes, and how to set up the one that needs no open ports.

P

Peerlify team

Engineering

A server behind NAT, whether in an office, a home lab, a branch site or a 4G-connected cabinet, can reach the internet but can't be reached from it. The router only forwards inbound packets it has a mapping for, and nothing creates that mapping for a connection that starts outside.

There are four common ways around it. They differ in what you have to configure and in what ends up exposed to the internet.

Option 1: port forwarding

Configure the router to send inbound traffic on a port (say TCP 2222) to the server's private address and port (192.168.1.20:22).

  • Needs: admin access to the router, and a public IPv4 address on it. It doesn't work behind CGNAT, because the provider's NAT sits in front of your router. See what is CGNAT?.
  • Exposes: the service, to the entire internet. Anyone can find and probe the port. Moving SSH to a non-standard port reduces log noise; it doesn't reduce exposure.
  • Good for: services that are meant to be public.

Option 2: a reverse tunnel through a public server

The server keeps an outbound connection open to a machine you rent with a public address, for example with ssh -R, and you connect to that machine to get through.

  • Needs: a public VPS, and something to keep the tunnel up across reboots and network drops.
  • Exposes: the VPS, which is now a public entry point you have to patch, monitor and lock down.
  • Good for: a quick, single-service workaround.

Option 3: a VPN gateway on the server's network

Put a VPN server on the private network and connect clients to it.

  • Needs: a port forward to the VPN server (so the same CGNAT problem), or a gateway hosted elsewhere that the site connects out to.
  • Exposes: the gateway's port. Once connected, users typically reach whatever the gateway routes to, unless you add rules.
  • Good for: giving a group of people access to a whole site.

Option 4: a mesh VPN

Install a client on the server and on the devices that need to reach it. Each client connects outbound to a coordination service, then the clients connect to each other: directly with NAT traversal when the networks allow it, through a relay when they don't.

  • Needs: a client on each device that takes part.
  • Exposes: nothing on the server's network to the internet. There's no listening port to find.
  • Good for: reaching specific servers from specific people, wherever both are, including behind CGNAT.

How mesh VPNs work explains the architecture.

Step by step: reach a server behind NAT with Peerlify

Peerlify is a mesh VPN for Windows, macOS and Linux. These steps assume a Linux server with systemd and a laptop on any of the three.

1. Create an account

Sign in at https://login.peerlify.com with GitHub, Google, Microsoft or Apple. A network is created for you on the free Personal plan.

2. Install the client on the server

shell
curl -fsSL https://pkgs.peerlify.net/install.sh | sh

The script adds Peerlify's package repository (apt, dnf/yum or zypper, depending on the distribution) and installs the client as a systemd service. Other options are on the downloads page.

3. Sign the server in

For a server without a browser, create an auth key in the console under Settings → Keys, then:

shell
peerlify login --auth-key=<your-key>

On a machine where you can open a browser, peerlify login prints a sign-in link instead. Add servers with auth keys covers reusable, expiring and pre-tagged keys.

4. Install the client on your laptop and sign in

Download the installer for your OS from the downloads page, install it, and run peerlify login (or use Log in… in the Windows tray / Sign In… in the macOS menu bar).

5. Connect

On the laptop, list the devices it can reach:

shell
peerlify list peers

Then use the server's Peerlify address with whatever you normally use:

shell
ssh admin@100.100.0.12

On Windows and macOS you can use the server's name instead of its address. The first packets go through a Peerlify relay; if the two networks allow a direct path, the connection moves to it. peerlify list peers -s shows p2p for direct and ERPFServer for relayed.

6. Narrow the access

A new network allows all traffic between its devices. Before you add more people, write your first rule, for example to let only your admin group reach the server on port 22.

Which option should you choose?

Port forwardReverse tunnelVPN gatewayMesh VPN
Works behind CGNATNoYesOnly if hosted elsewhereYes
Public listening portYes, on the serviceYes, on the VPSYes, on the gatewayNo
Software on the serverNoTunnel clientNoClient
Per-person access rulesNoNoDependsYes

If the service should be public, port forwarding (behind a proper reverse proxy) is the honest answer. If it shouldn't be, avoid creating a public entry point at all. For SSH specifically, see SSH without port forwarding.