Recently, I was concerned about having to get access to my systems from an unprotected terminal. I wasnt about to load my private key on any terminal out there, and I already do not allow passwords in the standard database. The only way I figured I could protect the authentication to my machine from an untrusted terminal would be S/Key. Unfortunately, many current ssh client implementations do not natively support S/Key (although, OpenSSH does have some support hacked into it).
Note: trojaned clients that inject commands without the user suspecting goes beyond the scope of this document. I'm restricting the scope of this document to login authentication.
S/Key is a OTP (One Time Password) authentication system which uses the MD4 algorithm to convert a secret into a series of words which can be used to authenticate the user. The S/Key system never reuses the challenge since the S/Key undergoes a sequence of transformations to generate each successive challenge.
Note: There have been security issues regarding S/Key. Please read mudge's article regarding the subject.
My server is running NetBSD-current, and I'm security paranoid. I do not allow
passwords on my system; only RSA keys are allowed as authentication to
my server. In the event that a user is unable to connect using their identity
which is listed in .ssh/authorized_keys
, I give the user the
option of using S/Key passwords. This is obviously only secure if their S/Key
generator is secure.
After I run
skeyinit
for the user,
login
will
check the /etc/skeyusers
file to generate the proper S/Key
challenge. A user can later run an S/Key
generator
to determine the correct challenge-response in order to successfully log in.
I've written a simple wrapper that allows the execution of
/bin/login
to require secure (kerberized/skey) passwords. This
wrapper is intended to be used as the login shell of a specific user. The
wrapper then calls /bin/login
with the flags -s
,
which requires secure passwords, and -h
which sets the hostname
flag in the process' arguments. The wrapper will only exec login
if there are no arguments being passed to it (thereby avoiding issues like
scp, or ssh "command").
Here are the steps I took to combine the features of SSH with S/Key:
skeyuser
user.
/path/skeylogin
skeylogin.c
Here is an example of my configuration:
{shelly:~} grep skey /etc/passwd skeyuser:*:521:521:S/Key User:/:/usr/local/bin/skeylogin {shelly:~} ls -l /usr/local/bin/skeylogin -rwsr-x--- 1 root skeyuser 6795 Jun 2 11:22 /usr/local/bin/skeylogin {shelly:~} ls -l /usr/bin/login -rwx------ 1 root wheel 19200 May 20 21:46 /usr/bin/login {shelly:~} ssh skeyuser@shelly Last login: Thu Jun 1 22:17:26 2000 from bmw.metachar.net NetBSD 1.4Y (GW-GENERIC) #0: Sat May 20 19:25:47 EDT 2000 Welcome to NetBSD! login: sirsyko Password [s/key 99 foobar12345]:
Thanks to the following people for their feedback: