How to edit sshd_config without locking yourself out
A safe routine for changing sshd_config over SSH: validate with sshd -t, check the effective settings for your login, and arm a timed rollback first.
On this page
The routine1. Keep a session open2. Back up the file3. Validate, then check the effective settings4. Arm a rollback before you reload5. Reload, test, cancelThe changes that lock people outHave a way in that is not SSHThe same routine, built into the editorFAQEveryone who runs servers has done it once: change sshd_config, reload, close the terminal, and discover that the only door into the machine is now shut. The fix is usually a console session through a cloud provider, sometimes a drive to a data centre. The prevention is a five-step routine that takes two minutes.
The routine
- Keep your current session open.
- Back up the file.
- Validate the new file with
sshd -t, and check what sshd will really do for your login withsshd -T. - Arm a timed rollback on the server.
- Reload, test a fresh login from a second terminal, then cancel the rollback.
Each step guards against a different mistake.
1. Keep a session open
Reloading sshd does not disconnect sessions that are already established. They run in their own processes. Your open terminal is your way back in, so do not close it until a new login has worked.
2. Back up the file
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak-a keeps the owner, the mode and the SELinux context.
3. Validate, then check the effective settings
A syntax check:
sudo sshd -t && echo OKsshd -t reads the configuration and reports the first error with its line number. If it prints anything, stop. A reload usually refuses a broken file, but a restart with one leaves no daemon listening at all.
A syntax check is not enough, though. A file can be valid and still shut you out. Ask sshd what it will do for your login:
sudo sshd -T -C user=deploy,addr=203.0.113.7 | grep -iE \
'passwordauthentication|pubkeyauthentication|permitrootlogin|allowusers|allowgroups|authenticationmethods'-T prints the effective configuration after every Include and Match block is applied. -C supplies the connection to evaluate Match blocks for: your user and the address you connect from.
Why your edit may have no effect
sshd uses the first value it reads for each keyword. On Debian and Ubuntu the main file starts with:
Include /etc/ssh/sshd_config.d/*.confSo a drop-in file wins over anything further down the main file. The classic case is a cloud image with /etc/ssh/sshd_config.d/50-cloud-init.conf containing PasswordAuthentication yes. You set PasswordAuthentication no in the main file, reload, and passwords still work. sshd -T shows the truth:
sudo sshd -T | grep -i passwordauthentication
grep -ri passwordauthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/4. Arm a rollback before you reload
This is the step most people skip. Tell the server to put the old file back in five minutes unless you say otherwise:
sudo systemd-run --on-active=5min --unit=sshd-rollback \
/bin/sh -c 'cp -a /etc/ssh/sshd_config.bak /etc/ssh/sshd_config && systemctl reload ssh'systemd-run creates a one-off timer that survives your session ending. On Fedora, RHEL, Arch and openSUSE the service is called sshd, not ssh.
On a system without systemd, at does the same job:
echo 'cp -a /etc/ssh/sshd_config.bak /etc/ssh/sshd_config && service ssh reload' | sudo at now + 5 minutes5. Reload, test, cancel
Reload rather than restart:
sudo systemctl reload sshNow open a second terminal and log in again. If you use connection sharing, a plain ssh would reuse your existing connection and prove nothing, so switch it off for the test:
ssh -S none deploy@serverIf the login works, cancel the rollback from either session:
sudo systemctl stop sshd-rollback.timerIf it does not work, you have two options, both good: fix the file in the session you kept open, or wait for the timer to restore it.
The changes that lock people out
| Change | How it goes wrong | Check first |
|---|---|---|
PasswordAuthentication no | Your key was never authorised for this account | Log in with the key before you make the change |
PermitRootLogin no | You log in as root and have no other account with sudo | Create and test the other account first |
AllowUsers or AllowGroups | The list leaves you out. Once it exists, everyone not on it is refused | sshd -T -C user=you |
Port 2222 | A firewall, a security group or SELinux still allows only 22 | Open the new port first, and keep Port 22 as a second line until the new one works |
AuthenticationMethods publickey,keyboard-interactive | The second factor is not set up for your account | Test on a second account |
AllowTcpForwarding no on a bastion | Every host that is reached through it becomes unreachable | List what jumps through this host |
UsePAM no | Account and session rules that PAM enforced silently change | Leave it alone unless you know why |
Two notes on moving the port. With SELinux enforcing, sshd cannot bind a new port until you allow it:
sudo semanage port -a -t ssh_port_t -p tcp 2222On Ubuntu 24.04, where sshd is socket-activated, a new port also needs the socket unit regenerated:
sudo systemctl daemon-reload && sudo systemctl restart ssh.socketHave a way in that is not SSH
The routine above makes a lockout unlikely, not impossible. Know your out-of-band path before you need it: the serial console of your cloud provider, a hypervisor console, IPMI or iDRAC, or a rescue mode that mounts the disk. Check that it works on a quiet day.
The same routine, built into the editor
Safe Change in Gatesys SSH is this routine as a review sheet. Saving sshd_config from the SFTP browser, or from your own editor, opens it:
- The diff of what you changed.
- The server’s own check:
sshd -ton a staged copy, so a broken file never reaches/etc/ssh. - Your login, before and after. It runs
sshd -T -Cfor the login you are using and shows the effective settings side by side. An edit that sshd reads the same way, because an included file wins, is marked no effect. - Findings in red when the login you are using would be refused, when sshd would stop listening where you came in, or when forwarding goes off for hosts that jump through this one, by name.
- A backup under
/var/backups/gatesys, five kept per file. - The safety net. A systemd timer on the server restores the old file after 1, 3 or 10 minutes. Gatesys SSH then makes a fresh login with the same key and asks New login works. Keep this change? If you do nothing, the server puts the old file back.
It works the same for nginx files with nginx -t, sudoers with visudo -cf, and systemd units. The review sheet, the checks, the backup and the safety net are in the free plan. Describing the change in a sentence and letting the Farabi assistant draft it needs Pro.
FAQ
How do I test sshd_config before applying it?
Run sudo sshd -t. It validates the file and exits silently when it is correct. Then run sudo sshd -T to see the effective settings, which is the only way to catch a value overridden by an included file or a Match block.
Does restarting sshd disconnect my current session?
Normally no. Established sessions run in their own processes and survive a reload or a restart of the daemon. Prefer reload, and keep the session open until a new login has worked.
Why does my sshd_config change have no effect?
sshd uses the first value it reads for each keyword. A file in /etc/ssh/sshd_config.d/ that is included at the top of the main file overrides what comes later. Check with sudo sshd -T | grep -i keyword.
I am locked out of SSH. What now?
Use an out-of-band console: your cloud provider’s serial or web console, a hypervisor console, or rescue mode. Restore the backup of sshd_config, run sshd -t, and restart the service.
Is it “ssh” or “sshd” in systemctl?
Debian and Ubuntu name the service ssh. Fedora, RHEL, CentOS, Arch and openSUSE name it sshd.
