SSH comes out of the box with quite a few security features 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.
The 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.
To 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:
sudo apt-get update
sudo apt-get install otpw-bin libpam-otpw
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.
Before 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. This will not interfere with our local logins or with our logins through the DigitalOcean web console.
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-auth
file. 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:
#@include common-auth
Below this, let’s add some lines that will allow us to use the OTPW system to handle password requests:
auth required pam_otpw.so
session optional pam_otpw.so
When you are finished, save and close the file.
Now 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:
sudo nano /etc/ssh/sshd_config
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.
UsePrivilegeSeparation yes
PubkeyAuthentication yes
ChallengeResponseAuthentication yes
PasswordAuthentication no
UsePAM yes
Once you’ve set these parameters, want to restart our SSH daemon so that our changes can take affect:
sudo service ssh restart
Now 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-gen
command. This would typically output the human-readable text to standard out, but we can pipe it into a file for safe-keeping:
cd ~
otpw-gen > nothingtosee.txt
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.
Afterwards, you will have an ~/.otpw
file 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 ~/nothingtosee.txt
.
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.
From a computer that is not configured with your SSH key (you can also temporarily move your key out of your ~/.ssh
directory) you can test out the new one-time password system.
Log into the user that you’ve configured with OTPW as you normally would:
ssh demouser@server1.com
Password 253:
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 ~/.otpw
file, 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:
Password 161/208/252:
A ~/.otpw.lock
file 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:
rm ~/.otpw.lock
Next time, you will be prompted for only one password again.
I 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 ~/.bashrc
for the users implmenting OTPW:
nano ~/.bashrc
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 ~/.otpw
file 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.
Setting up OTPW can provide you with an option for logging into your server from an insecure location. While it does suffer from some of the drawbacks of regular password logins, it provides a middle ground between key-based logins, which should never be transferred to an insecure computer, and regular password logins, which have many flaws and vulnerabilities.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
It looks like OTPW does not delete used OTPs (overwriting them with dashes in the .otpw file). This does not seem to interfere with basic operations but (maybe) can lead to unwanted OTP reuse on the long run. (Just tried on Linux Mint 20.1).
Can we use this after ssh for a sudo password?
Next time, you will be prompted for only one password again.
I suppose it’s impossible to remove the .lock file manually when you try to log in through the SSH. In my case I choose the crontab variant:
Every minute this string checks does the $HOME/.otpw.lock exist. If it is - .otpw.lock will be remove at the start of the next minute. For me it’s pretty convenient - to wait a minute and get a chance to log in again. Good luck.