How to Disable SSH Password Authentication Safely
Security Intermediate 4 min read

How to Disable SSH Password Authentication Safely

Disable SSH password authentication without locking yourself out: test keys first, override every Match block, verify the result, keep a rollback.

Published: November 6, 2026 • Updated: November 6, 2026
sshsshd_configlinux hardeningopenssh

To disable SSH password authentication safely, confirm key login works first, set PasswordAuthentication no where sshd reads it first, check every Match block, validate the file, restart the daemon and verify the effective setting from a second session. Skipping any of these is how admins lock themselves out or leave passwords on. The OpenSSH password bypass on Alpine made this an urgent stopgap for musl hosts.

What does PasswordAuthentication no change?

It tells sshd to stop accepting the SSH password authentication method. The default for this setting is yes, so a config file that never mentions it still allows password logins.

The sshd_config manual lists KbdInteractiveAuthentication as a separate keyword with its own default of yes. Setting PasswordAuthentication no says nothing about it, so review that keyword as a separate decision while you are in the file.

Before you change anything

Work through this list on each host:

  1. Confirm your own key login works from a new connection.
  2. Find anyone still using passwords. On Alpine, search /var/log/messages for sshd lines reading Accepted password for. Those people, scripts and vendor tools will break when you make the change, so move them to keys first.
  3. Check that keys can log in to the accounts you depend on. Under Alpine's PAM-less package, an account with ! in its shadow password field cannot log in with a key either.
  4. Confirm you have another way in, such as a console or out-of-band session, in case the restart goes wrong.
  5. Keep your current session open until you have tested a new login. Do not close it to test.

Why can a setting in sshd_config be ignored?

Because sshd uses the first value it reads for most keywords, a line lower in the file or in a later include can have no effect. A match block can also override the global value for the connections it covers.

The manual states it plainly: "Unless noted otherwise, for each keyword, the first obtained value will be used." This has two practical results.

First, placement matters. A drop-in file only wins if its include is read before any other PasswordAuthentication line, which is why people name these files with a low number such as 00-no-passwords.conf. Older systems may not read the drop-in directory at all: Alpine's default config reads it from 3.19 onward, and earlier releases ignore it.

Second, Match blocks can undo your work. PasswordAuthentication is one of the keywords allowed inside a block, and when the criteria are satisfied, the block's keywords override the global section. A leftover Match block that allows passwords for one user or address range keeps them on for that case, even when the global setting says no.

How do you disable SSH password authentication?

Add a line setting the option to no in a location sshd reads first, change any existing lines that say yes, including those inside match blocks, then test the configuration and restart the daemon.

Alpine's advisory gives a sequence for its own systems, run as root:

mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sed -i.bak -e '1i PasswordAuthentication no' \
  -e 's/^\(\s*PasswordAuthentication[^y#]*\)yes/\1no/i' \
  /etc/ssh/sshd_config
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication

Here is what each part does:

  • The first two commands create the drop-in file for releases that read it.
  • The sed command adds the setting at the top of the main file, so it applies even on older releases, and changes yes to no on every matching line, including those inside a Match block. It keeps the original as /etc/ssh/sshd_config.bak.
  • sshd -t checks the configuration, and the && means the restart happens only if the check passes.
  • sshd -T prints the effective settings.

The last command should print passwordauthentication no. On other distributions, the service manager command differs, so use the restart command your init system provides, and check first whether your main file includes the drop-in directory before relying on it.

How do you confirm the change worked?

Open a second session with your key and confirm it logs in, then check that sshd reports the setting as no. Keep the original session open until both checks pass.

Also confirm that a password attempt is refused, using a test account from a machine you control. If you run Match blocks, test from a connection that matches them, because a global check does not prove what those connections receive. Then read the file once more and search it for remaining PasswordAuthentication lines set to yes.

Rollback

If something breaks, use the session you kept open. Alpine's undo is to delete the drop-in and restore the backup:

rm /etc/ssh/sshd_config.d/00-no-passwords.conf
cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
sshd -t && rc-service sshd restart

Make it stick

A manual change does not survive a rebuild, so put the setting in your configuration management or image build. Cloud images are the easy case to miss. Alpine notes that images configured through cloud-init write PasswordAuthentication no, while its tiny-cloud images do not. Check which one each fleet actually uses rather than assuming.

Then add a recurring check that reports any host whose effective value is yes. Run it across every platform, because musl and glibc hosts carry different risks but both benefit from having no password path on internet-facing SSH.

This does not replace patching

Disabling password logins closes the OpenSSH bypass, and Alpine says either the update or this change is enough. Treat it as a stopgap on affected hosts and still install the fixed package, then restart sshd. A later rebuild from an old image or a restored config file could bring password logins back, and an unpatched binary would then be exposed again.