How to Rotate SSH Keys on a VPS: The Safe Beginner's Checklist
CodexFuse Team · 2026-11-03T16:48:31.561Z · 11 min read min read
How to Rotate SSH Keys on a VPS: The Safe Beginner's Checklist
Learning how to rotate SSH keys on a VPS is one of those skills that feels optional until the day it becomes urgent. You can replace the keys your servers trust in a few minutes, without downtime and without locking yourself out — but only if you follow the right order: add the new key first, verify it works, and only then retire the old one. This ssh key rotation checklist walks you through that exact arc, plus the safety rails, the common mistakes, and the special case of rotating after a breach.
Before you start, you need a fresh key pair to rotate to. Generating one takes about ten seconds with OpenSSH, and if you'd rather not type the command yourself, CodexFuse's SSH key generator produces a ready-to-use Ed25519 or RSA pair in your browser. (If you're new to the idea of a virtual private server itself, our what is VPS hosting guide explains the whole concept first.)
What does "rotating an SSH key" actually mean?
Rotating an SSH key means replacing the public key your server trusts with a brand-new one, and making the old one stop working. The server side of this is the ~/.ssh/authorized_keys file: OpenSSH's sshd man page specifies that each line of the file contains one key, and every key listed there is accepted. That line-per-key design is the whole game — it means you can install the new key alongside the old one first, and the old key keeps working right up until you delete its line. There is no other revocation path for key files: rotation is a file edit, not a server setting.
On Ubuntu and Debian servers (and RHEL-family systems like AlmaLinux and Rocky, per HostMyCode's 2026 tutorial), the procedure is identical — the steps below show how to rotate ssh keys on Ubuntu-style systems, and they work on both. The two situations that call for rotation look different, so here is how they compare:
| Routine rotation (maintenance) | Post-breach rotation (incident) | |
|---|---|---|
| When | Scheduled — every 90–180 days for small teams (HostMyCode), or annually per vendor policy | Immediately — e.g., the 29 October 2026 backdoored Claude Code extension incident |
| Key generation | On your normal admin workstation | On a clean machine that never ran the tampered software — never copy the old private key onto it |
| Old key handling | Remove its line from authorized_keys after verifying the new key | Remove the attacker's key from every user's authorized_keys — root and all accounts, not just your own |
| Session state | Keep one working session open until done | Rotate credentials and sessions "from a trusted system" (Cursor's remediation wording) |
| Speed | Deliberate and unhurried — planned | Urgent, but still add-first-verify-then-retire — panic order causes lockouts |
How do you rotate SSH keys on a VPS safely?
How to replace SSH key on server safely, step by step: install the new public key alongside the old one, prove the new key logs in, and only then delete the old key's line from authorized_keys. HostMyCode's 2026 rotation tutorial phrases the core rule as "add first, verify second, remove last" — and because sshd accepts every key in the file, this order means you never have a moment with zero working keys.
- Confirm your break-glass access. Verify you can reach your provider's web or VNC console (or rescue mode) before touching anything. On a VPS this is your recovery path if every SSH session dies.
- Open a known-good session and leave it open. Keep at least one working SSH session connected until you are completely finished — use
tmuxif you want extra safety. This session is your insurance policy. - Back up
authorized_keyswith a dated name. On the server, runcp -a ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak.$(date +%F). Rollback is then one copy command, not a detective story. - Generate the new pair on your workstation.
ssh-keygen -t ed25519 -f ~/.ssh/vps-prod-2026 -C "admin (prod rotation 2026)"— invoked with no arguments,ssh-keygenalready defaults to Ed25519, and OpenSSH's man page notes Ed25519 keys have a fixed length. Use a passphrase unless the key lives in hardware. - Add the new public key to the server.
ssh-copy-id -i ~/.ssh/vps-prod-2026.pub user@your-server-ip— the official ssh-copy-id man page explains it appends the key to the remote user's~/.ssh/authorized_keys, creating file and directory if needed. Add to a non-root sudo user first where possible. - Verify the new key — and nothing else. From a second terminal, run
ssh -i ~/.ssh/vps-prod-2026 -o IdentitiesOnly=yes user@your-server-ip. The-iflag selects the identity file, andIdentitiesOnly=yesstops your SSH agent from "helping" with the wrong key — the combination proves this key, and only this key, gets you in. Log in and runsudo -vto confirm privileges too. - Retire the old key — last. How to remove old SSH key from authorized_keys without mistakes: open the file and delete only the old key's line (one line = one key), then verify what remains:
ssh-keygen -lf ~/.ssh/authorized_keyslists the fingerprints so you can confirm exactly which keys remain. Record each new fingerprint and a "last rotated" date per server.
What safety rails should you set before touching keys?
Three rails turn a scary edit into a reversible one. First, provider console access — nearly every VPS product includes a web console in its panel, including the cheap VPS hosting plans most beginners run on, so confirm it loads before you start. Second, the open working session from step 2 above: as SSD Nodes' backdoor-remediation guide warns, open a second terminal on your (clean) machine and confirm the new key logs in before you close the console session, because a typo in authorized_keys locks you out. Third, the dated backup: cp -a before every edit means any mistake is a single command away from reversal.
One more rail people skip: file permissions. ~/.ssh must be 700 and authorized_keys must be 600 — run chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys after any edit. This is not cosmetic: sshd's StrictModes setting (on by default) checks modes and ownership of the user's files before accepting a login, so sloppy permissions can silently break key authentication even when the key itself is perfect.
How often should you rotate SSH keys?
Rotate interactive user keys at least every one to two years, and production service-account keys about every six months. That cadence comes from Encryption Consulting's SSH key-lifecycle guidance, which frames rotation against PCI DSS and NIST SP 800-53 expectations; their example program runs annually for interactive users and every six months for production service accounts, with Ed25519 as the preferred algorithm.
Smaller teams can reasonably tighten that: HostMyCode's 2026 tutorial suggests every 90–180 days as a practical default. And the schedule is only half the rule — rotate immediately, outside any cadence, when someone leaves the team, a laptop is lost or stolen, a key was shared insecurely (pasted into a chat, committed to a repo), or any incident suggests exposure. A calendar schedule limits blast radius; event-driven rotation contains actual damage.
How do you rotate SSH keys after a breach?
After a breach you rotate from a clean machine, check every user's authorized_keys, and treat the old environment as compromised until proven otherwise. The model case is the 29 October 2026 backdoor: Cursor's own extension marketplace served tampered Claude Code builds 2.1.312 and 2.1.313 for macOS and Windows between about 2:27am PT and 1:35pm PT that day, and the injected code appended the attacker's Ed25519 public key — comment svc-telemetry — to ~/.ssh/authorized_keys, alongside persistence mechanisms and a reverse SSH tunnel.
SSD Nodes' remediation guide gives the exact playbook, and its central sentence is worth quoting verbatim: "Then replace every SSH key your servers trust, and do it from a clean machine, because anyone who used that planted key could read your private keys." In practice that means: on the clean machine (one that never ran the tampered build), create a new pair and do not copy the old private key onto it; reach each server via your provider's console or an unaffected second admin; then search every user's key files — sudo grep -rn svc-telemetry /root/.ssh /home/*/.ssh — and read every remaining line of each authorized_keys by hand. Cursor's own notice echoes the same direction: rotate "credentials and sessions accessible from affected hosts, from a trusted system." And remember that uninstalling the malicious extension does not remove the planted key or its persistence — only the rotation plus IOC sweep does.
Should you automate SSH key rotation?
Orchestrate it, but do not let a naive script execute it blindly. PortalCloud's essay on automated rotation explains why: a "set it and forget it" script that regenerates keys every few days can hit a network hiccup mid-push and delete the old key before the new one lands — a lockout that needs console access to fix; a stale server inventory leaves skipped hosts holding "ghost keys" an attacker can use indefinitely; and silent authorized_keys overwrites destroy the audit trail of who changed access and why.
The safe pattern is staged automation with verification at every step — a script that backs up, adds, tests, and only then retires, on one host at a time, logging each action for review. PortalCloud's closing line says it best: "Treat key rotation as a security control, not a convenience feature."
What are the most common lockout mistakes?
Almost every SSH lockout during rotation is one of five avoidable errors. Learn them once and the checklist above becomes almost boring — which is exactly the point.
| Mistake | Why it locks you out | The fix |
|---|---|---|
| Deleting the old key before verifying the new one | You discover the new key doesn't work only after the working key is gone | Add first, verify second, remove last — no exceptions |
A typo when hand-editing authorized_keys | One broken line can invalidate the key you need (SSD Nodes' explicit warning) | Dated backup before every edit; prefer ssh-copy-id over manual pasting |
| Wrong file permissions | StrictModes rejects logins when ~/.ssh or authorized_keys are too open | chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys after each change |
| Your SSH agent offers the wrong key | The server sees an unexpected identity and denies access even though the right key exists | Test with ssh -i newkey -o IdentitiesOnly=yes so only the new key is offered |
| No console access confirmed beforehand | A lockout becomes unrecoverable without the provider's web console or rescue mode | Confirm console/rescue access before step one |
How do you rotate keys across many servers without missing one?
Treat fleet rotation like a rollout, not a one-off. Keep a text inventory of every host (hostname, IP, OS, role), rotate on one low-risk server first — staging or internal tooling — and only then move to production in a maintenance window with console access standing by.
Distribution can be a simple loop from your workstation, no orchestration tool required:
for host in 203.0.113.11 203.0.113.12 203.0.113.13; do ssh-copy-id -i ~/.ssh/vps-prod-2026.pub admin@$host done for host in 203.0.113.11 203.0.113.12 203.0.113.13; do ssh -i ~/.ssh/vps-prod-2026 -o IdentitiesOnly=yes -o BatchMode=yes admin@$host 'echo OK $(hostname)' done
The second loop matters more than the first: it verifies each host non-interactively, so a missed or misconfigured node shows up immediately. Retire the old keys on each host only after its own verification passes — the checklist scales host by host, never as one big blind push.
Sources
- SSD Nodes, "Backdoored Claude Code extension: what to check" — ssdnodes.com
- HostMyCode, "SSH key rotation tutorial (2026): Replace VPS admin keys safely without downtime or lockouts" — hostmycode.com
- PortalCloud, "Why Automated SSH Key Rotation Can Be a Hidden Risk" — portalcloud.org
- OpenBSD man pages: ssh-keygen, ssh, ssh_config, sshd, sshd_config
- Debian man page archive: ssh-copy-id(1)
- Encryption Consulting, SSH key lifecycle guidance — encryptionconsulting.com
Frequently asked questions
Do I need downtime to rotate SSH keys?
No. Because authorized_keys accepts one key per line, the new key works the moment it is added — existing sessions stay connected and new logins can use either key until you retire the old one. Rotation is a file edit, not a restart.
Does changing my private key alone count as rotation?
No. The server only trusts what is in authorized_keys; if the old public key's line is still there, anyone holding the old private key can still log in. The old key stops working only when its line is deleted from every user's key file on the server.
What should I do if I get locked out mid-rotation?
Use your provider's web console or rescue mode to get a shell, then restore the dated backup of authorized_keys (cp ~/.ssh/authorized_keys.bak.2026-11-03 ~/.ssh/authorized_keys) and fix permissions. This is why the checklist makes console access step zero.
Is Ed25519 the right choice for new keys?
Yes for new deployments: ssh-keygen generates an Ed25519 key even with no arguments, Ed25519 is a fixed-length key so no size flags are needed, and both HostMyCode's tutorial and Encryption Consulting's guidance prefer it over RSA. If you must use RSA, the OpenSSH default is 3072 bits.
Can I rotate keys for all users on a server at once?
Each Linux account has its own authorized_keys, so you rotate per account — audit root and every human and service account. The SSD Nodes backdoor guide is explicit: check /root/.ssh and /home/*/.ssh, not just your own user, because an attacker's key could be planted anywhere.

