I got inspired to look into this by this post:
http://www.linuxjournal.com/content/configuring-one-time-password-authentication-otpw
The idea of
one time passwords is fairly simple -- even if someone manages to keylog your password (or see you type it in) it will be useless to them, as it can only be used once.
The implementation is also fairly simple: if you divide a password in half, and only let one half be static (the
prefix) and the other half come from a pre-agreed list (the
suffix), you can have a secure way of changing your password in a practical way.
Let's say that I decide that the static, prefix part should be 'ice' and that we make a pre-agreed list of suffices that we can use to make passwords:
001. box
002. flower
003. icle
004. skating
005. fishing
You should print this list and keep it reasonably safe. Without the prefix it is not useful. Likewise, any keylogger on a compromised computer will find out the prefix, but it will be useless without the suffix list. So keep that it in mind -- make sure that no-one gets hold of both.
You then try to log in via ssh from a remote client, and you get prompted for password 004 -- this means that the password you need to use is iceskating.
In real-world applications the suffixes are random, and not at all related to the prefix. Also, once the list has been generated it is not stored (so you better print it) -- only the hashes or the complete passwords are.
Note that the choice isn't really between OTPW and regular static password -- you can use both, just like you can use SSH with both key and password.
Set up
http://www.linuxjournal.com/content/configuring-one-time-password-authentication-otpw?page=0,2 deals with a number of different use scenarios. I'm only interested in enabling OTPW for
remote SSH at this stage i.e. local login is using static passwords by default.
(if you're travelling with a laptop you may consider using OTPW for everything)
You need libpam-otpw. In addition, otpw-bin is useful for generating the suffix/hash list.
sudo apt-get install libpam-otpw otpw-bin
Generate a list of hashes and suffices:
otpw-gen|tee otpw.list
Print the list and delete it afterwards.
You now have a ~/.otpw file filled with hashes.
Create
/etc/pam.d/ssh-otpw.
auth sufficient pam_otpw.so
session optional pam_otpw.so
and edit
/etc/pam.d/sshd -- include the ssh-otpw file immediately before common-auth to set the order of log in methods.
auth required pam_env.so # [1]
auth required pam_env.so envfile=/etc/default/locale
@include ssh-otpw
@include common-auth
account required pam_nologin.so
@include common-account
@include common-session
session optional pam_motd.so motd=/run/motd.dynamic noupdate
session optional pam_motd.so # [1]
session optional pam_mail.so standard noenv # [1]
session required pam_limits.so
@include common-password
This way, if there's a ~/.otpw file you'll first be prompted for a one-time password. Otherwise that option will be skipped, so users with and without OTPW can co-exist happily.
In /etc/ssh/sshd_config, set
ChallengeResponseAuthentication yes
and make sure that UsePrivilegeSeparation and UsePAM are also set to yes (should be on Debian Wheezy).
sudo service ssh restart
and that's it!
Testing
To test, use a different computer and try to log in. I've got all my local computers set up to use keys to log in, so I had to to
ssh -o PubKeyAuthentication=no me@beryllium
Password 267:
In my list, 267 was given as
dfuF XE+L
so (pretending that my prefix was ice) my password was
icedfuFXE+L.
If you answer that challenge wrong, you'll be asked for your static password instead. If you want to keep that secret, then interrupt the connection and retry.
Easy!
Once you start running out of password, run otpw-gen again for a new list.