SSH comes out of the box with quite a few security feature to make sure that your connections are secure and that you can authenticate to a remote host without worries. In particular, SSH keys create a secure way to connect without transmitting your password or passphrase over the internet.
However, there are situations where using an SSH key is not reasonable or might actually be insecure. Let's say that you are trying to use SSH from a public computer or a computer that you are trying to troubleshoot for a friend. The public key system assumes that the computer that you are connecting from is at least somewhat trustworthy. This is not always the case.
If you are using a key pair in this scenario, even if your key is password protected, the key will be decrypted and put in the local machine's memory to work with, at least in order to authenticate. This means that it is vulnerable if you do not trust the local machine.
A system called One Time Password Authentication or OTPW was created to function within these kinds of circumstances. One time passwords are a system that have been incorporated into other authorization mechanisms like two-factor authentication and single sign-on solutions.
In this guide, we will set up OTPW on an Ubuntu 14.04 VPS instance. This will allow us to log in with a two component password that may only be used once.
Basic ConceptThe way that OTPW works is by hooking into the PAM authentication system.
After you have configured your system to allow logins with OTPW, you can generate a set of password "chunks" by supplying a prefix password. You can then either print these out, keep them on a device you will have access to and that you trust (like encrypted on your phone), or in some other format that you can access without using the computer that you do not trust.
Now, when you are prompted for a password, you will be given a reference number. You will enter the prefix password you created, followed by the password portion associated with the given reference number.
This password will only work one time. If someone is key logging on your computer or is able to see you type the password, it will not matter because it will not be valid after you have logged in.
Install the ComponentsTo configure this system, we need to first install the necessary components.
Since the authentication is handled entirely on the server-side and the client end is no different than a regular password prompt, we will only be installing a few packages on our server.
We will update our package cache and install these from the repository:
As you can see, the mechanism is divided into two parts. The first component is used to generate and manage the one time passwords. The second is the plugin that is used with PAM to authenticate against these password files.
sudo apt-get update sudo apt-get install otpw-bin libpam-otpw
Editing PAM to Take Advantage of OTPWBefore we do anything with our actual passwords, we will need to add OTPW as an option for PAM.
We want to accomplish this in a way that restricts regular password logins, because we assume that you have already set up SSH keys for authentication on computers that you trust. Our configuration will use the SSH keys if they are available, otherwise, it will fall back on the OTPW mechanism.
To do this, we are going to only alter the file that is involved with SSH login.
Open the SSH PAM configuration file:
sudo nano /etc/pam.d/sshd
Towards the top of the file, there is a directive meant to import the
common-authfile. This file allows for regular password authentication without using the OTPW system, which we do not want for our SSH sessions. Let's comment that out:
Below this, let's add some lines that will allow us to use the OTPW system to handle password requests:
When you are finished, save and close the file.
auth required pam_otpw.so session optional pam_otpw.so
Configure SSHDNow that we have the SSH daemon's PAM module configured to use OTPW, we can configure the daemon itself with the appropriate values.
Open the file with root privileges to check out the file:
We are looking for a few separate values. We need to check that each of these parameters is set to the value below. If you cannot find any of the parameters, add and set them. Be sure not to add parameters more than once though, because they can cause the daemon to fail.
sudo nano /etc/ssh/sshd_config
Once you've set these parameters, want to restart our SSH daemon so that our changes can take affect:
UsePrivilegeSeparation yes PubkeyAuthentication yes ChallengeResponseAuthentication yes PasswordAuthentication no UsePAM yes
sudo service ssh restart
Creating OTPW Password FilesNow that our system is configured to use OTPW for SSH users who do not have a public key, we can create the two password files necessary for this system to work.
One file, which will be stored in
~/.otpw, will contain a hashed value of the password segments, one per line. The second file that we will create, is the human-readable one-time password segments, which we should copy to a secure device, print them off, or otherwise put them into a secure, portable location.
All we need to do to generate this list is call the
otpw-gencommand. This would typically output the human-readable text to standard out, but we can pipe it into a file for safe-keeping:
This will generate a random seed and ask for a password prefix. You should use the same common-sense rules that you would use for any regular password. Make sure you'll remember the password.
cd ~ otpw-gen > nothingtosee.txt
Afterwards, you will have an
~/.otpwfile that contains the hashed values of the password suffixes, one per line:
OTPW1 280 3 12 8 253tFMngG2PNYhn 132Kua%SZ+esb6t 237yH7D2FMbQsyW 125rrXfBRwnF+A% 106gJxhJE4jkknj 04135:5:knWIB4: 232/d4kI:n57IcD 244RASe8ka63b8Z 057GmqfFe=pXQqu . . .
You have also piped your unhashed suffixes with their reference number into a file at
OTPW list generated 2014-04-03 18:06 on sshd 000 /rGF h5Hq 056 /zi5 %yTJ 112 J7BT HdM= 168 fdBm X%Tn 224 69bi =9mE 001 GoOG jxYQ 057 E=o3 kuEF 113 zwit p27J 169 nHK9 CXRx 225 IihF =o8g 002 Xm=E PuXc 058 Ok27 ZJ++ 114 On=5 pNYH 170 ZRDa mB5e 226 yYsb CAfn 003 deL+ iHs7 059 /WGS :J4M 115 ZZd/ 8zyU 171 acDd dESV 227 ddjg ipcR 004 KhDn NdfS 060 =tEz ACye 116 FkQ9 8kSu 172 iRSR nZWT 228 9hHd veZ9 005 rGFG K5=7 061 MvUW LRxc 117 2YwY axJJ 173 kEV5 T/Vz 229 wx%n Le6P 006 GWi2 fHjf 062 qOR: WN2x 118 FvD4 oNjT 174 99OT 8KPy 230 /I=Y hicP 007 XPom pEYp 063 8Xvm vZGa 119 UNjF :Kys 175 b95i SU3R 231 keLn aDcK 008 fJI% 3Qs2 064 3I7Q I2xc 120 5Tm9 REQK 176 AVg: 4ijE 232 :aIF op6V 009 P/Sn dSxA 065 A+J6 =4zo 121 LAyj 3m2+ 177 TMuN 9rJZ 233 SWvB %+cL . . .
The left column is the reference number, followed by 8 characters for the suffix. The space between the first and last 4 characters in the suffix is for readability and can optionally be removed when you are entering the suffix.
By default, the generator produces enough suffixes to fit on a standard piece of paper, which is great for printing and one way of carrying the output.
You will have to complete this procedure for each user you wish to configure one-time password access for.
Trying it outFrom a computer that is not configured with your SSH key (you can also temporarily move your key out of your
~/.sshdirectory) you can test out the new one-time password system.
Log into the user that you've configured with OTPW as you normally would:
As you can see, we have been given the suffix that OTPW wants.
First, enter your prefix password, followed directly with the suffix on the same line, without a space between your prefix password and the suffix. You can keep the space that is shown in the suffix file if you wish.
So let's say that my prefix password is "crazyburr!to", and that the suffix file has a column that looks like this:
249 N4HY RsbH 250 +vAz fawn 251 O4/R ZrhM 252 c6kP jgUT 253 I=aA OKSz 254 aYzA :F64 255 3ezp ZpIq 256 ggIi TD2v
In this case, we could type either "crazyburr!toI=aA OKSz" or "crazyburr!toI=aAOKSz".
You should then be able to log in with no problem. If you check your
~/.otpwfile, you will see that one of the hashed lines has been replaced with dashes:
. . . 091icM5kSPVOdcU 274Uf3q/=kTYcu8 229fHfmIsCj7mjQ --------------- 115EzDO6=jM/sOT 143iWCdteSk3kg7 265S+QTGcg+MAZO 174UgXchxsI2g:G . . .
This means that the suffix has been used and is no longer valid.
If two people attempt to log into the account at the same time, OTPW will instead request your prefix password, followed by three suffixes. Each of the three requested suffixes will be different, so that someone who is keylogging and trying to beat you to hitting the enter key will be unable to complete that successfully.
The prompt will look like this:
~/.otpw.lockfile is created in this situation. After a successful login, it should be removed, but there is a bug that causes this not to work in some situations. In this case, just remove the lock manually:
Next time, you will be prompted for only one password again.
Caveats and BugsI mentioned above how sometimes the lock file is not deleted automatically after you've logged in successfully. This is especially common when a user aborts the connection by typing CTRL-C before finishing the prompt.
Another bug that is relatively important is the reporting of the number of valid OTPW entries remaining. This is usually handled by the session line in the PAM configuration, but currently it is not working correctly.
To work around this, Wolfgang Kroener wrote a very simple bash script that implements this functionality in this Debian mailing list thread. We can implement this in a variety of ways, but the simplest is to just add it to the end of our
~/.bashrcfor the users implmenting OTPW:
Towards the bottom, paste this:
if [ "$SSH_TTY" -a -f $HOME/.otpw ]; then PW_LINES=$(wc -l <$HOME/.otpw) PW_USED=$(grep -- ---- $HOME/.otpw | wc -l) echo "OTPW $PW_USED/`echo $PW_LINES-2 | bc` used" fi
You could also add this to a more centralized location. That way it will output depending on if the
~/.otpwfile exists for each user.
Now, when you log in, you will get stats on your current remaining passwords:
OTPW 6/280 used
OTPW recommends that you regenerate your password list when you get beneath 50% of your available passwords. You can do this by re-running the generation command:
otpw-gen > anotherfile.txt
This will overwrite your previous password suffixes, so they will be rendered unusable after this procedure.