Should I delete users' passwords once I set up public key authentication for SSH?

If you have root access to the server and can regenerate ssh keys for your users in case they lose them

AND

you're sure a user (as a person) won't have multiple user accounts and they need to switch between those on an SSH session (well, they can also open multiple SSH sessions if the need arises)

AND

they will never need "physical" (via keyboard+monitor or via remote console for a VM) access to the server

AND

no users have password-gated sudo access (i.e. they either don't have sudo access at all, or have sudo access with NOPASSWD)

I think you'll be good.

We have many servers at work configured like this (only some accounts need access to the VM via vmware remote console, the others connect only via SSH with pubkey auth).


This question originally mentioned passwd --delete <username> which is unsafe: with that, the encrypted password field in /etc/shadow will be completely empty.

username::...

If you've configured your sshd to refuse password authentication, then that's safe with SSH... But if any other service on your system uses password authentication and is not configured to reject null passwords, this allows access without a password! You don't want this.


adduser --disabled-passwdwill produce an /etc/shadow entry where the encrypted password field is just an asterisk, i.e.

username:*:...

This is "an encrypted password that can never be successfully entered", i.e. this means the account is valid and technically allows logins, but it makes authentication by password impossible to succeed. So if you have any other password-authentication-based services on your server, this user is blocked from them.

Only authentication methods that use something other than standard account password (e.g. the SSH keys) will work for this user, for any service that uses the system password files in this system. When you need an user that can log in with SSH keys only, this is what you want.

If you need to set an existing account to this state, you can use this command:

echo 'username:*' | chpasswd -e

There is a third special value for encrypted password field: adduser --disabled-login, then the field will contain just a single exclamation mark.

username:!:...

Like the asterisk, this makes password authentication impossible to succeed, but it also has an additional meaning: it marks the the password as "locked" for some administration tools. passwd -l has much the same effect by prefixing the existing password hash with an exclamation mark, which again makes the password authentication impossible to use.

But here's a trap for the unwary: in year 2008, the version of passwd command that comes from the old shadow package was changed to re-define passwd -l from "locking the account" to just "locking the password". The stated reason is "for compatibility with other passwd version".

If you (like me) learned this a long time ago, it may come as a nasty surprise. It does not help matters that adduser(8) is apparently not yet aware of this distinction either.

The part that disables the account for all methods of authentication is actually setting an expiration date value of 1 for the account: usermod --expiredate 1 <username>. Before year 2008, passwd -l that originates from the shadow source kit used to do this in addition to prefixing the password with an exclamation mark - but does no longer do that.

Debian package changelog says:

  • debian/patches/494_passwd_lock-no_account_lock: Restore the previous behavior of passwd -l (which changed in #389183): only lock the user's password, not the user's account. Also explicitly document the differences. This restores a behavior common with the previous versions of passwd and with other implementations. Closes: #492307

The bug histories for Debian bug 492307 and bug 389183 may be helpful in understanding the thinking behind this.