vps-rescue: SSH back into your VPS when the network gives up
CLIENT
Self-initiated (open source)
ROLE
Open-source maintainer
DURATION
2026, one afternoon
TECH_STACK
PROJECT_URL
view_sitePublished
on npm
Day-one
Contributor PR
Node 20+22
CI green
MIT
License
CONTEXT
If you are on Indian wifi and your Hostinger VPS stops answering SSH from home but works fine from your phone hotspot, you have hit an ISP null-route. Some upstream carrier silently drops packets to a slice of budget-VPS IP space, you do not find out until your Monday is half over, and the standard fix (tunnel through a mesh like Tailscale) is just annoying enough that nobody automates it for themselves.
THE CHALLENGE
I wrote the workaround out as a Reddit comment one Monday after I had solved it for myself. The CLI version was the next obvious move, with one constraint: do not ship something that needs a defended trust model. No server. No held API keys. No SaaS dashboard. Client-side only, your token in your OS keychain, blast radius bounded to one five-minute auth window.
APPROACH
A small CLI that does the diagnose-and-tunnel dance, then gets out of the way. No web service, no daemon, no operator. Tailscale does the actual tunneling. The CLI just orchestrates the steps: probe the connection, mint a 5-minute auth key, render the install one-liner, poll until the new device joins the tailnet, drop an idempotent block into your ~/.ssh/config. A wrapper, not a fork. Designed to keep working as Tailscale's API evolves without much maintenance from me.
No operator infrastructure
Nothing to host, nothing to sign in to, no server holding your API tokens. The CLI is your client. Your API token lives in your OS keychain. The blast radius of any compromise is the ephemeral five-minute auth key you minted for one provisioning.
Diagnose first, decide second
Before tunneling, the CLI probes TCP, DNS, and traceroute, then classifies the failure into one of five buckets: reachable, isp_blocked, path_blocked, host_offline, dns_failure. If your VPS is actually down, no amount of Tailscale will fix it. The tool tells you that instead of pretending.
Pluggable Transport interface
Tailscale is the day-one transport, but the architecture treats it as one of several. cloudflared, AWS SSM, Tor: each can implement the same Transport interface. The plan is to add transports as users hit the gaps, not to predict them.
Round-trip-tested shell escaping
The provisioning step generates a bash one-liner with your auth key and SSH public key embedded. That string travels through your terminal, your clipboard, the provider's browser console, and back into bash on the VPS. The escape function has unit tests that round-trip through a real `bash -c` invocation, because string templating without proof of escaping is how production scripts get owned.
OUTCOMES
Shipped end-to-end in one afternoon. Published to npm as `vps-rescue`, tagged a v0.1.0 GitHub release, set up CI on Node 20 and 22 across Ubuntu and macOS, filed eight starter issues (three good-first-issues, five help-wanted), wrote SECURITY.md and CODE_OF_CONDUCT.md, and merged a contributor PR for a Linux clipboard edge case inside half an hour of going live. Download counts and stars are not the point of this note. This is about how it was built.
LEARNINGS
Built in an afternoon, paired with a coding agent in Cursor (Claude). The agent did the typing for the boring code (the bash escape function, the SSH config rewriter, the CI yaml, the issue templates) and caught two real bugs along the way: a Tailscale API validation issue and an off-by-one in the polling loop. The actual decisions stayed with me. Not putting it on a server. Overengineering the escape function so the generated bash one-liner actually survives a real shell. Shipping a wrapper instead of trying to fork Tailscale. Reviewing a stranger's PR inside half an hour and being willing to merge. Most useful tools in 2026 get built this way and pretending otherwise in a portfolio note did not feel right.
- The boring engineering (escape functions, SSH config blocks, idempotent device detection) is where rushed tools quietly break. Ninety minutes of round-trip tests on day one beats a weekend of debugging silent failures later.
- A small wrapper that ages well beats a bigger fork that does more. Tailscale will keep solving the hard problems; vps-rescue just needs to stay glue around them.
- Choosing no operator infrastructure changes the kinds of features you stop considering. A SaaS version would have grown an email list, an auth model, telemetry, and a maintenance horizon I did not want.
- A contributor PR inside the first hour is the cleanest signal that a project landed for the right audience. Reviewing it inside half an hour, with follow-up issues filed for the parts the PR did not touch, sets the contribution tempo for everything that comes after.