SSH Without a Public IP: Why VM Access Gateways Matter


SSH access is a basic requirement for any VM. How you configure it shapes both the attack surface and whether the login path survives a move between hosts.
In microsrv’s eBPF network architecture, the SSH gateway is an entry point alongside the HTTPS gateway. Below: why exposing guest port 22 publicly is a poor default, how a gateway differs from a conventional bastion, and why the connection address must stay stable on Spot capacity.
In short: an SSH gateway is one authenticated entry point to VMs in a private network, with no public IP on the guest. The <vm>@msrv.space address stays the same after migration.
1. Why open SSH to the internet is a bad default
Give every VM a public IP with port 22 listening, and a familiar script unfolds:
- instances are continuously scanned while someone probes for weak keys and passwords;
- attack surface scales with the number of machines, not the number of engineers;
- security groups and Fail2ban become an administrative burden on every VM;
- a public address ties the machine more tightly to the host’s network configuration and complicates migration.
Internal services, databases, and CI runners almost never need inbound SSH from the whole internet. What you need is a controlled channel for people and automation.
2. Bastion / jump host: the familiar compromise
The classic pattern is one (or a few) bastion hosts in a DMZ:
ssh -J user@bastion.example.com user@10.42.0.5
The advantages are clear: private VMs stay unexposed, and keys and ACLs are managed centrally on the jump host.
The downsides are systemic:
- the bastion itself becomes a critical asset: patching, monitoring, redundancy;
- as teams grow, shared keys, temporary access, and unclear ownership of the jump host turn into operational debt;
- the
10.42.0.5address or internal name can still change after the VM is re-created or fails over, if networking is not decoupled from compute; - with raw Spot capacity, reclaiming the target host drops the session even while the bastion itself is fine.
A bastion fixes perimeter exposure. It gives you nothing about stable VM identity.
3. SSH gateway: one entry point without a public IP on the VM
A gateway works differently from “yet another server everyone logs into”:
- clients always connect through a single external name;
- the gateway authenticates the user (SSH keys) and proxies the session to the target VM inside the VPC;
- guest port 22 is not published to the internet;
- the VM has no direct public IP for admin access.
On microsrv that looks like:
ssh -A <vm>@msrv.space
-A enables agent forwarding for when your keys are needed farther along the chain, for example with Git or peer hosts. Access still doesn’t require exposing the guest’s SSH port.
From the eBPF data plane perspective, the SSH address is part of the VM’s network identity, not an attribute of the current physical NIC.
4. A stable address after migration
Bind the SSH endpoint to the public IP of a specific Spot instance, and every migration or cold restart becomes a scavenger hunt: find the new address, update known_hosts, patch CI inventory.
When access goes through a gateway with a stable name <vm>@msrv.space:
- engineers and pipelines don’t rewrite inventory after a move;
- live migration preserves the familiar administrative path along with the processes;
- even a cold restart from a replicated volume restores the same entry point as soon as the VM is back online.
In a demo this looks like a detail. In production it’s critical: the answer to “how do I reach this machine?” must not depend on which Host-NN currently provides the Spot capacity.
5. Practical access rules
- Don’t open
:22on every VM “just in case.” - Separate human access from application publishing: the HTTPS gateway for HTTP/TCP exposure, the SSH gateway for administrative access.
- Keep keys centralized, rotate them, and don’t copy one key onto dozens of hosts without tracking.
- Make sure inventory and runbooks reference stable names, not ephemeral public IPs.
- On microsrv, a VPC, egress NAT without inbound IPs, and an SSH gateway give you a hardened default perimeter at about 25% savings versus standard cloud rates.
6. Bottom line
SSH without a public IP changes the remote-access model. Instead of making every VM its own internet entry point, you reach machines on a private network through one authenticated gateway. Combined with live migration and eBPF, it preserves both perimeter security and predictable day-to-day operations.
Sources and further reading
- OpenSSH —
ssh -J(ProxyJump) vs bastion and-Aagent forwarding - NIST — Guide to General Server Security, SP 800-123, hardening SSH and per-VM port 22 exposure
- microsrv eBPF networking — how the gateway fits the data plane (§3) and live migration (§4 stable address)
Field note: guest port 22 is not published. The gateway terminates client SSH, authenticates the key, and proxies into the VPC. The name
<vm>@msrv.spaceis the VM’s network identity, not the underlay host’s IP, so it survives both migration and cold restart.
FAQ
Bastion vs gateway? A bastion is a jump host you manage; a gateway is a platform-provided entry point with no public IP on the guest and stable naming across hosts.
Do I need agent forwarding? Only for Git/peer hops; the gateway can also proxy without -A for direct VM shell.
Run virtual machines in an affordable, developer-friendly cloud
microsrv automatically manages interruptible capacity by live-migrating VMs before a host is shut down while preserving volumes, IP addresses, and active connections.