RunOS Team ·

Zero Inbound Ports: Reaching Servers Behind NAT

Most infrastructure platforms have the same unstated requirement: they need to reach into your servers. An SSH port, an API endpoint, a public IP, something. If your machine sits behind NAT in your office or your basement, you’re suddenly deep in port forwarding and dynamic DNS territory.

RunOS turns the arrow around. Your servers connect out. The platform never connects in.

Agents dial out

When a node joins a cluster, a small agent on the machine opens a long-lived, mutually authenticated TLS connection out to the RunOS control plane and holds it. Instructions flow down that stream. Status flows back up.

That one design choice removes a whole category of setup:

  • No public IP required. Outbound connections work from anywhere that can reach the internet.
  • No port forwarding. There’s nothing to forward to, because nothing connects in.
  • No firewall holes. Your existing rules can stay exactly as strict as they are.

The control plane cannot open a connection into your cluster. It can only answer the connection your cluster already made. Behind NAT, behind a corporate firewall, on a home connection: it all looks the same to RunOS.

Joining a node is one command

Because there’s nothing to reach in and configure, adding a machine is just telling that machine to call home. Ask the console or CLI for a join command, paste it into a shell on the new server, and the agent registers, authenticates with mTLS, and starts holding its stream.

runos nodes join-command --cid <cluster>
# paste the printed command on the new machine

The token inside it is single-use and short-lived, so it’s safe to move around. Cloud node or bare metal, the flow is identical.

What about traffic between nodes?

Nodes in a cluster talk to each other over an encrypted WireGuard mesh that RunOS sets up for you. Mixed fleets work fine: a Hetzner VM, a DigitalOcean droplet, and the box under your desk can be one cluster, meshed together, with no manual VPN configuration.

Ingress runs on your nodes too. Traefik listens directly on them, so there’s no cloud load balancer to rent, and the setup is the same on a $5 VPS as on bare metal.

What stays in your hands

The dial-out model is about reachability, not control. It’s still your cluster: standard Kubernetes, your kubeconfig, full kubectl access. Two defaults worth knowing: apps you deploy get a public HTTPS address unless you turn that off per port, and service dashboards like Grafana are the opposite, VPN-gated rather than public.

If you disconnect RunOS, the agent stops getting instructions and your cluster keeps running whatever it was running.

Got a machine gathering dust?

Start free and point it at any Ubuntu server, wherever it lives. The clusters and nodes docs have the details.