openSUSE let a password in after I had turned passwords off
sshd takes a typed password in two ways. My hardening tool closed one of them, and openSUSE left the other open.
My hardening tool told me an openSUSE machine only took SSH keys now. Then I logged in to it with a password.
The tool is Linux Hardener, a Rust program of mine that finds weak settings on Linux machines and fixes them. I test it in containers on six distributions. On the openSUSE Leap 16.0 one, it wrote PasswordAuthentication no into the SSH server's config, and the next scan passed the check it called "Require key-based authentication only".
I got there through issue #185, a request for logins that need both a key and a password. Looking into it, I tried a keyboard-interactive login on the hardened container, the kind where the server asks the questions. A login limited to the plain password method was refused, but keyboard-interactive with the account password got in. The client's log said so:
Authenticated to 10.242.117.2 ([10.242.117.2]:22) using "keyboard-interactive".
The SSH server program, sshd, has two separate ways to take a typed password, and PasswordAuthentication only switches off the one called password. The other is keyboard-interactive, described in RFC 4256. The server sends whatever prompts it likes, and the client shows them and sends back what you type, without knowing what they are for.
With UsePAM yes, sshd lets PAM decide what those prompts ask. PAM is the set of Linux libraries that programs like sshd use to check logins. What gets asked then depends on how PAM is set up. On my container the system log showed my typed password going to pam_unix, the PAM module that checks a normal account password. The portable OpenSSH manual says PAM keyboard-interactive "usually serves an equivalent role to password authentication".
The switch for keyboard-interactive is KbdInteractiveAuthentication, which defaults to yes. The OpenSSH client also tries it before password by default, so I think a plain ssh with no key loaded would have asked for my password.
openSUSE was the only one of the six that left keyboard-interactive on. Its openssh package carries a patch that turns UsePAM on, and nothing it ships sets KbdInteractiveAuthentication, so sshd's default applies. Arch, Debian, Ubuntu and Fedora ship KbdInteractiveAuthentication no, and Rocky Linux 10 ships ChallengeResponseAuthentication no, the old name for the same setting. Issue #186 has the table.
My tool never looked at either name. For password logins it only checked PasswordAuthentication, so the other five were fine all along, just not because of anything I did.
Reading the config files wouldn't have shown me this either. On openSUSE no line sets it, and a missing line looks fine while sshd runs with yes. Rocky has the reverse problem. Its setting uses the old name, which sshd reads as the same option, so a check for the new name alone would find nothing and call it open.
It's easier to ask sshd. sshd -T prints every setting sshd will actually use, defaults and included files counted. It needs the server's host keys, so run it with sudo:
sudo sshd -T | grep -iE '^(usepam|passwordauthentication|kbdinteractiveauthentication|authenticationmethods) '
If that shows UsePAM yes and KbdInteractiveAuthentication yes, keyboard-interactive is open even with PasswordAuthentication no. The exception is when every list in AuthenticationMethods also asks for a key. Newer sshd prints the names in mixed case and older versions in lower case, which is why the grep ignores case. Keyboard-interactive takes whatever PAM asks for, which on my container was the account password.
The annoying part is that I already had a test for this kind of thing. My differential suite compares what my tool reports with what the system really does. It applies the hardening in a test container and then asks the real programs what they ended up with, sshd -T in SSH's case, instead of trusting my own code to read the files back. Its header says why it exists. My tool's own reader and writer had once "agreed with each other and disagreed with Linux".
But the suite only checked the SSH settings my tool managed, and keyboard-interactive wasn't one of them. After an apply on openSUSE, sshd -T said yes for it, and nothing in the suite looked. The suite checks it now, and on the openSUSE container sshd reports no after the apply.
The fix makes the tool manage KbdInteractiveAuthentication too, with a target of no, under the same compliance checks as PasswordAuthentication. So the password-login checks pass only when neither method can finish a login on a password alone. It reads the old name as well, the way sshd does. And the old check's description now reads "Disable SSH password authentication", which claims only what the setting does.
There's one case where off is wrong, and it's the kind of setup #185 asked for. AuthenticationMethods is a setting that lists which methods a login must pass, in order. This line wants a key first and then a keyboard-interactive prompt:
AuthenticationMethods publickey,keyboard-interactive
There keyboard-interactive is the second step and has to stay on. Switch it off and sshd refuses to start, because no list can be completed. So the tool leaves it alone when every list needs more than a typed password, such as a key.
If you look after SSH and mean no passwords, set both PasswordAuthentication no and KbdInteractiveAuthentication no, unless you use a key-first setup like that one. Then run the sshd -T line and try both logins from another machine:
ssh -o PreferredAuthentications=password you@host
ssh -o PreferredAuthentications=keyboard-interactive you@host
A password prompt that lets you in on the second one means passwords are still on. The fix is on main and goes out with the next release, so the Arch User Repository package doesn't have it yet.
My suite asks sshd about both settings now. What found this, though, was a password login I tried for a different reason.
Sources and further reading:
- Linux Hardener and its fix commit
- Issue #186 and issue #185
- The differential suite
- OpenBSD's sshd_config and sshd manual pages
- OpenBSD's ssh_config manual page
- Portable OpenSSH's sshd_config page
- RFC 4256, keyboard-interactive authentication
- The pam and pam_unix manual pages
- openSUSE's PAM patch for openssh
- openSUSE Leap 16.0
- The AUR package