How To Install and Use OTPW for Single-Use SSH Passwords on Ubuntu 14.04

Published on June 17, 2014
How To Install and Use OTPW for Single-Use SSH Passwords on Ubuntu 14.04


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.

Basic Concept

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.

Install the Components

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.

Editing PAM to Take Advantage of OTPW

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.

Configure SSHD

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

Creating OTPW Password Files

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:

280 3 12 8
. . .

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.

Trying it out

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:

. . .
. . .

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.

Caveats and Bugs

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"

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.

Learn more about us

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

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?

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 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:

* * * * * bash -c '[ -L "$HOME/.otpw.lock" ] && rm "$HOME/.otpw.lock"'

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.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel