How the safety net works
Three modules can cut you off from your own server: user.admin (the admin user), ssh.server (the SSH server config) and firewall.inbound (the firewall). When an apply includes any of them, the safety net is on. vps-ready keeps the changes only after a new SSH login proves they work. If that proof never comes, it puts everything back on its own.
The short version
Section titled “The short version”applyarms a safety timer before it changes anything.- It makes the changes, then prints an
sshcommand for you to run from a new terminal. - That new login runs
sudo vps-ready confirm. The timer stops and the changes stay. - If no new login confirms in time (5 minutes by default), the timer rolls back every change. The same happens if the server reboots first.
Why a new login, not your open terminal
Section titled “Why a new login, not your open terminal”Your open terminal proves nothing. When the SSH server reloads its config, sessions that are already open keep running, and the firewall lets connections that are already established through. So a change that blocks every new login can look perfectly fine from the terminal you ran apply in. The only real test is the thing you will do tomorrow: open a new connection and log in.
That one login also checks everything at once: the admin user exists, your key works, sudo works, the SSH server accepts the new config and the firewall lets you in.
Step by step
Section titled “Step by step”-
The timer is armed first. Before the first change,
applyhands a timer to systemd, so it runs even ifapply, your terminal or your SSH connection disappears. It also turns on a small boot hook for the reboot case. Ifapplyis cut off part way, the timer still rolls back what it did. -
The changes are made and checked. Each file is validated before it is written (
sshd -t,nft -c,visudo -c), the SSH server is reloaded rather than restarted, and the result is verified. Any failure here rolls back at once, before you are asked to confirm. -
The confirm window starts once the changes are live.
applyprints the command to run, with your admin user, the server address and the SSH port filled in:Changes are live. To keep them, open a NEW terminal on your computer and runthis to show you can still log in:ssh -t -o ControlPath=none -p 22 admin@203.0.113.10 sudo vps-ready confirmIf no new session confirms by 14:07:30 UTC (5:00 left), every change is rolled back.More time: sudo vps-ready confirm --extendDo not edit files vps-ready manages until you confirm: an unconfirmed change reverts them.Ctrl-C stops waiting here, not the timer.Then it counts down:
Waiting for a confirm: 4:12 left. -
You confirm from a new terminal. On success the new terminal prints:
Confirmed transaction 20261025T120000Z from a new SSH login (admin from 198.51.100.7). The changes stay; undo them with `sudo vps-ready rollback --last`.and the first terminal ends with
Confirmed: the changes of transaction ... stay., an audit of what was fixed, and exit code 0.
What counts as a new login
Section titled “What counts as a new login”confirm looks at the SSH connection it runs in. It accepts it only when all of these hold:
| Check | Why |
|---|---|
It is a different SSH session from the one that ran apply |
The old one survives the change, so it proves nothing |
| It started after the changes went live | A second terminal opened earlier also survived the reload |
| It came in on a port the SSH server listens on | A login through another SSH server proves nothing about this one |
| It is logged in as the admin user of the plan | That is the account you will use from now on |
| It does not come from loopback | The firewall accepts loopback whatever its rules, so ssh localhost on the server proves nothing |
These do not count as new: tmux, screen and mosh sessions, the provider’s web console, and ssh connections shared through ControlMaster. The printed command sets -o ControlPath=none so your ssh opens a fresh connection even if your config shares them. A login through a jump host does count.
When confirm refuses, it says why and prints the command to run again, for example:
error: this SSH session started before the changes went live. This is not a new SSH login: tmux, screen and mosh sessions, the console, and ssh connections shared through ControlMaster all count as old. Open a new terminal and run: `ssh -t -o ControlPath=none -p 22 admin@203.0.113.10 sudo vps-ready confirm`Need more time
Section titled “Need more time”sudo vps-ready confirm --extend # 5 more minutes from nowsudo vps-ready confirm --extend 15m # or any time from 1m to 30m--extend does not confirm anything, so it works from any session, including the old one. It moves the deadline to that long from now, at most 30 minutes ahead and at most 2 hours after the changes went live. To start with a longer window, pass it to apply:
sudo vps-ready apply --profile minimal --deadman 10m # from 1m to 30m, default 5mIf nobody confirms
Section titled “If nobody confirms”When the deadline passes, the timer runs the rollback. It works even when apply and your terminal are long gone. The SSH server config and the firewall are always restored, even if you edited those files during the window; your edit is kept next to the journal so it is not lost. The first terminal, if it is still open, ends with:
error: no new SSH login confirmed the changes, so every change was restored; transaction 20261025T120000Z is rolled-back (deadman-timeout).and apply exits 1. Your old login (for example as root, or with a password) works again.
If the server reboots
Section titled “If the server reboots”A reboot during the window counts as “not confirmed”, since you may have rebooted because you were locked out. The boot hook runs before the SSH server starts, rolls the transaction back, and the SSH server comes up with the old config. You can log in the way you did before apply.
What the safety net does not cover
Section titled “What the safety net does not cover”- It needs systemd. On other init systems the three guarded modules are not offered.
- Only one change can wait for a confirm at a time;
applyrefuses to start another until it is confirmed or rolled back. - The other modules (
ssh.bruteforce,kernel.sysctl,updates.auto) cannot lock you out, so they apply without a confirm. You can still undo them withrollback. - A firewall at your cloud provider is outside the server; vps-ready cannot see or change it.
Related: Undo changes and recover from a lockout.
Feedback
Questions, ideas or problems with vps-ready.