This page describes a simple walkthrough to set up ssh which is
not filtered (per ipf/pf), with
user@host access control by sshd
itself, and with S/Key OTP (One Time Password) for insecure channels.
You want this, ...
- because, you too have a shellbox with some users which each have a static IP, and you want only them to login, only from their own box.
- and, from 'unknown' boxes, you only want to allow a pseudo-user with only S/Key OTP login. You can do the rest using 'su'.
| Note: in the text, I use 'normal login' when I mean 'login using fixed password' |
In general, see manual pages for
skey(1),
skeyinfo(1),
PAM(8),
pam.conf(5) and
sshd_config(5).
I chose to keep s/key and 'normal' passwords totally separated; that way, even if
someone knows the 'normal' password, he/she still cannot login from an arbitrary box.
(Normal password could be known in event of keyboard sniffers or whatever.)
| Note: the upside to this scheme is that 'normal' and s/key passwords are each used only where they should: 'normal' passwords from trusted boxes (i.e. users on their own box), and s/key passwords only from untrusted boxes. The downside is of course, that you always have to carry your OTP's with you some way or another (see Bonus material), even if you know the box you happen to be sitting at is, in fact, trustworthy. Your choice! :-) |
Configuring an s/key-only user (let's say '
otpuser') can be done like this:
# useradd -m otpuser
# su otpuser
$ skeyinit
Password: <<<password is still blank, so just type 'Enter'>>>
[Adding otpuser]
Reminder - Only use this method if you are directly connected
or have an encrypted channel. If you are using telnet
or rlogin, exit with no password and use skeyinit -s.
Enter secret password: <<<enter s/key password; this is for generating OTP only>>>
Again secret password: <<<enter it again>>>
ID otpuser skey is otp-md4 99 myhost
Next login password: ONE TWO THREE FOUR FIVE SIX
$ logout
# vipw <<<change otpuser's password field to '*' to disable normal login>>>
#
We now have a user
otpuser that can only login using s/key passwords.
| Note: it is good/better practice to set a normal password for the new user for now, verify that both normal and s/key login work, and eventually disabling normal password (and verifying normal login doesn't work anymore). |
On NetBSD 4.x, one has to explicitly add s/key authentication to pam.d/ssh as follows:
For NetBSD 3.x, nothing needs to be changed, except adding
...to /etc/ssh/sshd_config, and restarting sshd using
Test, assuming ssh is set up to allow access from all from localhost:
$id
uid=1001(michai) gid=100(users) groups=100(users)
$ ssh -l otpuser localhost
Password: <<<type 'Enter' without typing a password>>>
otp-md4 99 myhost12345
S/Key Password: <<<enter 'ONE TWO THREE FOUR FIVE SIX' as displayed earlier>>>
$ id
uid=1002(otpuser) gid=100(users) groups=100(users)
$
Note that the password, once used, is not valid a 2nd time. You can
also verify the 'normal' login using fixed password doesn't work, because
we disabled it using '*' for password field.
In /etc/sshd_config, add items of the following form to allow access control:
AllowUsers otpuser smith@1.2.3.4 wesson@9.8.7.6
This will allow user
otpuser to connect from anywhere, and allow
smith and
wesson to connect only from their own (static IP) boxes.
Alternatively, one could use PAM-based user/host access control; see
pam_login_access(8)
and
login.access(5).
You can get the next 3 passwords like this:
# su otpuser
$ skey -n 3 `skeyinfo | awk '{ print $4" "$5 }'`
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: <<<enter the s/key password you typed earlier>>>
96: NOSE FOOT RUSH FEAR GREY JUST
97: YAWN LEO DEED BIND WACK BRAE
98: SOME SIX WORDS THAT WERE COMPUTED
$
(We wasted 1 password (with sequence number '99') already using aforementioned
test, so the next one up is #98.)
Verify that...
- user otpuser can login from anywhere
- user otpuser can only login using s/key OTP, not normal password
- users can only login from their own boxes
I use a script to display the next bunch of OTP's, like this:
# cd /usr/local/sbin
# ls -l nextotp
-rwx------ 1 root wheel 115 Jul 13 11:52 nextotp
# sed 's/^/> /' < nextotp
> #!/bin/sh
>
> next=`skeyinfo otpuser | awk '{ print $4" "$5 }'`
> su otpuser -c "skey -p MySecretSKeyPassword -n 8 $next" | tail -r
#
...and another one to put a GIF image of those to my cellphone:
# ls -l otp2phone
-rwx------ 1 root wheel 730 Jul 13 11:38 otp2phone
# sed 's/^/> /' < otp2phone
> #!/bin/bash
>
> PHONEHOST=phobos # My 'USB' box is not the one running this script
> PICNAME=otp.gif
>
> ### make sure phonehost is up
> ping -c 1 -w 3 $PHONEHOST &>/dev/null
> if [ $? -ne 0 ]; then
> echo "Host \"$PHONEHOST\" down."
> exit 1
> fi
>
> ### mount phone on phonehost
> rsh $PHONEHOST '/sbin/mount -t msdos /dev/sd0e /mnt' >/dev/null 2>&1
> if [ $? -ne 0 ]; then
> echo "Unable to mount medium on host \"$PHONEHOST\"."
> exit 1
> fi
>
> ### GIF'erize pic and copy to phone
> nextotp \
> | tr -d : \
> | sed 's/^ *//;s/ *$//' \
> | xargs -n 4 echo \
> | text2gif \
> > /tmp/$PICNAME
> rcp /tmp/$PICNAME $PHONEHOST:/mnt/mobile/picture
> rm -P /tmp/$PICNAME
>
> ### unmount phone
> rsh $PHONEHOST /sbin/umount /mnt
#
...and yes, I use passwordless root rsh on my LAN, and the
tr/
sed/
xargs
mess there is to produce a somewhat rectangular text layout, so that
things will still be readable without the phone having to scale too oddly :-)
Considering ...
- I normally live as user 'michai',
- I don't want to waste time on multiple (mostly PuTTY) ssh logins,
- screen(1) complains about ptty perms after using su
...I wrote this script, to be used with the 'pam_exec' module, in pam.d/su:
# cd /usr/libexec
# ls -l pam_suauth
-rwx------ 1 root wheel 196 Jul 14 16:58 pam_suauth
# sed 's/^/> /' < pam_suauth
> #!/bin/sh
>
> # $1 : user_from
> # $2 : user_to
> # return code is 0 iff PAM_RUSER/PAM_USER matches $1/$2
>
> if [ "$PAM_RUSER" != "$1" ]; then exit 1; fi
> if [ "$PAM_USER" != "$2" ]; then exit 1; fi
> exit 0
#
Deploy it as follows:
# grep pam_suauth /etc/pam.d/su
auth sufficient pam_exec.so /usr/libexec/pam_suauth otpuser michai
#
Now, user
otpuser can su to
michai without password.
Next, configure
otpuser's
shell to either create/attach a
screen session or su to
michai, depending on
whether it is a login shell or not. Since the
otpuser user is not used for real
work anyway, I chose to do it this way:
# cd ~otpuser
# tail -n 1 .profile
export ENV=$HOME/.shrc
# sed 's/^/> /' < .shrc
> ### see if we are already running inside screen, if not, create or attach, if yes, su michai.
> case $0 in -*) exec screen -D -RR ;; *) exec su - michai; esac
>
> ### (shouldn't reach here)
> echo "If you can read this, something is wrong (.shrc)"
#
Now, when a remote ssh connection is made, a screen session is started or (forcibly)
attached, and each created window (with non-login shell) will immediately run
michai's login shell. (I happen to like that, or rather, I am too lazy to configure
bash properly :-)