Generate one time passwords for scp only accounts


Content Contributer
I wanted to generate some one time passwords to allow a friend to login 10 times via scp to download some stuff. Sounds strange but I wanted to ensure that he is not using the account for anything else.

So there are two things todo:

  1. Generate one time passwords
  2. Lock a user to scp only
Let's start with 1.:

  • Install otpw

    sudo apt-get install otpw-bin libpam-otpw

  • Configure common-auth
    nano /etc/pam.d/common-auth
    Find the line:
    auth    [success=1 default=ignore] nullok_secure
    and add these lines above:
    auth       sufficient
    session    optional
    So every login will first try optw and afterwards try the common auth methods.
  • Configure sshd
    Add a otpw config file:
    nano /etc/pam.d/otpw
    With content:

    auth sufficient
    session optional

    Include otpw config to sshd auth config:

    nano /etc/pam.d/sshd

    Search for:

    @include common-auth

    And add this line above:

    @include otpw

    Afterwards modify sshd config:
    Ensure that this three parameters are set to "yes":

    UsePrivilegeSeparation yes
    ChallengeResponseAuthentication yes
    UsePAM yes

  • Restart sshd
    service ssh restart

This is a basic configuration of otpw. It ensures that otpw is only used for users which do have a otpw config file (~/.otpw) in their home directory. All other users will not notice that otpw is active.

Following command will generate 4 one time passwords:

otpw-gen -h 5 -w 64

Following command will generate 10 one time passwords:

otpw-gen -h 6 -w 79

Output would look like this (called with context of user):

otpw-gen -h 6 -w 79
Generating random seed ...

access to your account with this information alone. Therefore, you
enter that each time directly before entering the one-time password
(on the same line).

corresponding passwords have to be appended after the prefix
of the old one.

Enter new prefix password:
Reenter prefix password:

Creating '~/.otpw'.
Generating new one-time passwords ...

OTPW list generated 2013-07-09 20:02 on debian

000 AN2: 3:GL 002 gz7C wMeR 004 BQZs BLns 006 u9AQ 8GfI 008 G:Ui C+jo
001 ZiAZ qeDV 003 cQQr v8O4 005 O/fD 3koN 007 JrLO ROZr 009 wZAT 7zrf


SSH login:

login as: test
Using keyboard-interactive authentication.
Password 003:
Linux debian 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686

the exact distribution terms for each program are described in the

permitted by applicable law.
Last login: Tue Jul 9 20:03:23 2013 from
[email protected]:~$

If you entered the prefix password "pass" the real password for 003 is:

passcQQr v8O4

Just append it without any space.

Now create a group for all optw users and add the users:

addgroup optw
adduser test optw

And change file permissions:

chown root:eek:ptw /home/test/.otpw
chmod 640 /home/test/.otpw

And to ensure that noone can reset the passwords:

chmod 750 /usr/bin/otpw-gen

Now start with point 2. - limit shell to scp:

apt-get install rssh
apt-get install scponly

There are two shells doing that:

  • rssh is a configurable shell that limits the actions of a user
  • scponly is a shell that ... well ... only has scp commands.
Now you have to add the shell to a user:

usermod -s /usr/sbin/scponly test
usermod -s /usr/sbin/rssh test

And you can confiure rssh quite descent:

nano /etc/rssh.conf


# Leave these all commented out to make the default action for rssh to lock
# users out completely...


# if your chroot_path contains spaces, it must be quoted...
# In the following examples, the chroot_path is "/usr/local/my chroot"
user=test:011:000010:"/opt/scpspace/test chroot" # scp with chroot


I don't like the otpw-gen handling because even if you chown the file to root:root the .otpw file is recreated when the user is calling otpw-gen. So everytime I have to add a user I have to chmod /usr/bin/otpw-gen.

So I am still searching for a better solution for one time passwords.

How do you lock users and the number of logins?
Last edited by a moderator:


New Member
Thank you for the one time passwords configuration. I can use this if I have to connect to my server from a workstation I don't own.
  • Like
Reactions: acd


New Member

%otpw ALL= (root) NOPASSWD: /usr/local/bin/
#set -x
set -o nounset

OTPWOPTS="-h 6 -w 79"


umask 0037

  echo "This script must be run from sudo" 1>&2
  exit 1

if [ "$SUDO_USER" = "" ]; then
  echo "Please run from sudo and not directly as root" 1>&2
  exit 2;

export SUDO_HOME=$( bash -c "echo ~$SUDO_USER" )

if [ ! -d "$SUDO_HOME" ]; then
  echo "Could not determine user's shell" 1>&2
  exit 3;

export OTPWFILE="$SUDO_HOME/.otpw"

passwd -S "$SUDO_USER" | awk '{ng=0; if ($2 == "NP") {print "Password is unset";ng=ng+1;} else if ($2 == "L") {print "User is locked";ng=ng+2;}; if ($5 == 0) {print "User is disabled";ng=ng+4}; if (ng != 0) {exit ng+8};}' 1>&2
if [ $? != 0 ] ; then
  exit $?

if ! id "$SUDO_USER" | cut -d' ' -f 3 | grep $OTPWGROUP >/dev/null; then
  echo "User is not in $OTPWGROUP group" 1>&2
  exit 4

# if we got this far, we can go ahead and change the pw
cleancontrol() {
  if [ $OKEXIT != 1 ]; then
    if [ $RMONABORT != 0 ]; then
      rm -rf $OTPWFILE
      echo "OTP file removed, run again to set it." 1>&2
    stty sane
    exit 4;

trap cleancontrol EXIT


# verify with new versions that otpw-gen correctly removes files owned by the user
# (inc symlinks) before executing and doesn't just blindly write to -f, otherwise uncomment.
#rm -rf "$OTPWFILE"

otpw-gen $OTPWOPTS
if [ $? != 0 ]; then
  exit $?

if [ -x `which setfacl`"" ] && setfacl -bm u:"$SUDO_USER":r "$OTPWFILE" 2> /dev/null ; then
  chmod 640 "$OTPWFILE"

exit 0


New Member
I am using rssh for a lot of things now because it is easy to create users and to limit them to one action and to one folder without using different tools.