Matt Brown asked if I could think of any way to allow a certain group of users to scp into a host and use a password, while requiring a valid key pair for most other users. Perry suggested a solution to this a while ago, so I sat down and had a quick look at it, and got it working.
I configured sshd such that:
This bypasses direct /etc/passwd auth, but allows standard PAM based auth via the ChallengeResponseAuthentication mechanism. This will allow everyone to login with a password if possible, so we need to configure pam. For this, I used the pam_listfile module, checking that the user had a particular shell, /usr/bin/scponly, as their shell:
cat “/usr/bin/scponly” > /etc/scpshells
I then edited /etc/pam.d/sshd:
auth required pam_env.so
auth required pam_listfile.so item=shell sense=allow file=/etc/scpshells onerr=fail
auth sufficient pam_unix.so likeauth nullok
auth required pam_deny.so
auth required pam_nologin.so
session required pam_limits.so
session required pam_unix.so
account required pam_unix.so
password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
password sufficient pam_unix.so nullok md5 shadow use_authtok
password required pam_deny.so
I probably don’t need all of that in the sshd pam snippet, but I just dumped the contents of the included files into to to make editing it easier.
To test this I added /bin/bash to /etc/scpshells, and verified that I could ssh in by using a pasword. I then removed it, and verified that I could no longer ssh in with a password. Combine this with a suitable shell (/usr/bin/scponly), and I can create users that can scp in with a password – or with a key if they care – but cannot get a local shell; all other users cannot authenticate via PAM, and so must provide a valid key.