Password authentication on SSH is the single setting that turns a leaked or guessed credential into a shell. Turning it off is five lines of config; doing it across a fleet without locking yourself out is the part that needs an order. This is that order, including the check that proves keys work before you disable the fallback, why AuthenticationMethods beats PasswordAuthentication alone, and how to leave one deliberate way back in.
Password SSH is the setting that converts a guessed, reused or leaked credential straight into a shell on your server. Every internet-facing host gets a constant background of login attempts against root, admin, ubuntu and a dictionary of the rest. With passwords enabled, that background noise is a lottery someone eventually wins.
Turning it off is a handful of lines. Doing it on forty machines without locking yourself out is a sequence, and the sequence is what this is about.
The order that does not lock you out
Never start by disabling passwords. Start by proving keys work.
1. Put the key on every host, while passwords still work.
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@server1.example.com
Or across a fleet, if you already have Ansible:
ansible all -i inventory.ini -m authorized_key -a "user=deploy state=present key='{{ lookup('file', '~/.ssh/id_ed25519.pub') }}'" --ask-pass
2. Prove the key works, on every single host, before changing anything.
ansible all -i inventory.ini -m ping
If a host does not answer here, it will not answer after you disable passwords either. Fix it now, while you still have the fallback.
3. Only then change the config.
# /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
Modern distributions read /etc/ssh/sshd_config.d/*.conf, which is a better place than editing the main file, because a package upgrade will not fight you over it. Check that your sshd_config actually has the Include line; if it does not, edit the main file instead.
KbdInteractiveAuthentication matters. On many systems, turning off PasswordAuthentication alone still leaves a password prompt available through PAM keyboard-interactive. People disable one, test, see a prompt, and conclude the change did not apply.
4. Validate the config before you restart.
sshd -t && systemctl reload ssh
sshd -t parses the configuration and exits non-zero on a syntax error. Running it first is the difference between a reload and an outage.
5. Keep the session you have open, and test in a second one.
Open a new terminal and connect. If it fails, you still have the first session to undo the change. Closing your only session before testing is how this goes wrong.
Check what is actually in effect
Configuration files lie, because of includes, match blocks and the order of the first-wins rules. Ask the daemon instead:
sshd -T | grep -Ei 'passwordauthentication|kbdinteractive|permitrootlogin|pubkeyauthentication'
sshd -T prints the effective configuration after all includes are resolved. This is the only answer worth trusting, and it is the one to run across the fleet afterwards as proof.
Leave one deliberate way back in
Disabling passwords means a lost key is a lost server. Decide in advance which door stays open.
On a cloud provider, that is the serial or emergency console. On Hetzner, a rescue system. On bare metal, IPMI or physical access. Whichever it is, test that you can actually reach it before you need it, because discovering that your console access was never configured is a bad thing to learn at midnight.
A second, separate key held by a second person is the other common answer, and a good one.
Two more settings worth the same trip
While you are in the file, both of these cost nothing:
AllowUsers deploy admin
MaxAuthTries 3
AllowUsers means an attacker who somehow obtains a key for an unexpected account still gets nothing. MaxAuthTries cuts the number of attempts per connection.
If you want a second factor rather than a fallback, AuthenticationMethods publickey,keyboard-interactive requires both a key and a TOTP prompt, in that order. That is a real improvement over a key alone for administrative access, and it is worth the setup only if you will actually keep the TOTP secrets somewhere recoverable.
What this does not fix
Removing password SSH removes one entire class of attack. It does not help if the key itself is unprotected on a laptop, committed to a repository, or shared between six people and never rotated. Passphrase the private key, keep it in an agent, and give each person their own.
Fleet-wide hardening, done once and then kept true as machines come and go, is part of our security and compliance work and our server management engagements.
Frequently asked questions
How do I disable SSH password authentication on a fleet without locking myself out?
Prove keys work before touching the config. Copy the key to every host while passwords still work, confirm each one answers with ansible all -i inventory.ini -m ping, and only then set PasswordAuthentication no. Validate with sshd -t && systemctl reload ssh, keep the existing session open, and test from a second terminal so the first one can undo the change if the login fails.
How do I copy an SSH public key to many servers with Ansible?
Run ansible all -i inventory.ini -m authorized_key -a "user=deploy state=present key='{{ lookup('file', '~/.ssh/id_ed25519.pub') }}'" --ask-pass while password login still works. For a single host, ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@server1.example.com does the same job. Copy keys before any config change, while the password fallback still exists.
Why does SSH still show a password prompt after setting PasswordAuthentication no?
On many systems PAM keyboard-interactive authentication still offers a password prompt when only PasswordAuthentication is disabled, so set KbdInteractiveAuthentication no as well. People often turn off one, test, see a prompt and conclude the change never applied. A drop-in such as /etc/ssh/sshd_config.d/10-hardening.conf with PasswordAuthentication no, KbdInteractiveAuthentication no, PermitRootLogin prohibit-password and PubkeyAuthentication yes covers both paths.
Should SSH hardening settings go in sshd_config.d or the main sshd_config?
A drop-in file such as /etc/ssh/sshd_config.d/10-hardening.conf is the better place on modern distributions, because a package upgrade will not fight over it. The drop-in only takes effect if sshd_config contains the Include line for that directory, so check for the line first. When the Include line is missing, edit the main file instead.
How do I check which SSH server settings are actually in effect?
Ask the daemon with sshd -T, which prints the effective configuration after every include is resolved. Configuration files can mislead because of includes, Match blocks and the first-wins ordering. Filter the output with sshd -T | grep -Ei 'passwordauthentication|kbdinteractive|permitrootlogin|pubkeyauthentication' and run the same command across the fleet afterwards as proof.
How do I get back into a server after losing the SSH key once passwords are disabled?
Plan the way back in before disabling passwords, because without one a lost key means a lost server. On a cloud provider the route is the serial or emergency console, on Hetzner the rescue system, and on bare metal IPMI or physical access. Test that the chosen route actually works ahead of time. A second, separate key held by a second person is the other common answer.
How do I require both an SSH key and a TOTP code to log in?
Set AuthenticationMethods publickey,keyboard-interactive in the sshd configuration, which requires a key and then a TOTP prompt, in that order. For administrative access a key plus a second factor is a real improvement over a key alone. The setup is only worth doing if the TOTP secrets will be kept somewhere recoverable.
Does disabling password SSH protect against a stolen private key?
No. Turning off password SSH removes one whole class of attack, and a key left unprotected on a laptop, committed to a repository, or shared between six people and never rotated is a separate problem. Give the private key a passphrase, keep it in an agent and issue each person their own. AllowUsers deploy admin also limits logins to named accounts, so a key for an unexpected account gets nothing.
Read how we handle it in Cybersecurity.
Related Articles
Visitors Already Use Post-Quantum TLS. Most Servers Do Not
About 70 percent of browser traffic reaching Cloudflare uses post-quantum TLS, but only about 15 percent of origin servers do. The gap is usually the server's OpenSSL version. Here is how to check an origin, which systems ship OpenSSL 3.5, and what to change in nginx.
SecurityHow to Handle Secrets in CI Without Leaking Them Into Logs
The safest credential in your pipeline is the one that does not exist between jobs. OpenID Connect lets a workflow authenticate directly to a cloud provider and receive a token that expires on its own, which removes the stored key entirely. Masking is the backstop for everything left over, and it is worth knowing exactly where it stops working, because it relies on finding an exact match for the value. This guide covers the short-lived credential setup, the limits of redaction, and what to actually do in the ten minutes after a secret reaches a log.
SecurityA cPanel Account With Email Access Can Reach Root, and Every Supported Version Is Affected
CVE-2026-67401 lets an authenticated cPanel account holder with mail privileges create arbitrary files and run code as root. cPanel lists all supported versions as affected and has shipped patched builds. The precondition is an ordinary customer account, which on a hosting platform anyone can buy.