pam_mount and sshfs with password authentication

Posted by johns on Wed 26 Mar 2008 at 16:19

Tags: , , ,

pam_mount is "a Pluggable Authentication Module that can mount volumes for a user session". It is used to automatically mount a network share or volume when a user logs in, and unmount it when the user logs out sshfs is a FUSE filesystem that allows mounting a directory using the SSH sftp subsystem.

pam_mount and sshfs work if SSH keys are set up, but will fail if one tries to use password authentication. In most cases it is better to use SSH keys, but sometimes there may be too many users (or too many computers) for this to be feasible.

If you have tried to use ssh in a script you might have noticed the following:

 $ echo password | ssh root@192.168.26.139
Pseudo-terminal will not be allocated because stdin is not a terminal.
root@192.168.26.139's password:

ssh never reads the password from stdin (which is what pam_mount expects), instead it opens the terminal directly. To get around this one can either use expect (which allocates a PTY and emulates a terminal), or one can use $SSH_ASKPASS. $SSH_ASKPASS is normally used to specify a X11 program which prompts the user for a password.

Below is a wrapper for ssh/sshfs which prompts for a password on stdin and sets things up so that ssh will call the wrapper to get the password, which will be read from the parent process using a pipe. The idea comes from the python version of LDM, the LTSP Display Manager, which passes the password to ssh this way.

#!/bin/bash
# Copyright (C) 2008 John S. Skogtvedt <jss at bzz.no>
# Licence: GNU GPL v3 or later at your option

if [ -n "$SSH_ASKPASS_FD" ]
then
	read password <&$SSH_ASKPASS_FD
	echo "$password"
	exit 0
elif [ $# -lt 1 ]
then
	echo "Usage: echo password | $0 <ssh command line>" >&2
	exit 1
fi

export SSH_ASKPASS=$0
export SSH_ASKPASS_FD=4
[ "$DISPLAY" ] || export DISPLAY=dummy:0
read password

exec 3<&0
# write password 100 times to make repeated ssh connections work
for x in $(seq 100)
do
  echo "$password"
done | exec setsid "$@" 4<&0 0<&3

Install and test the script:

$ sudo install sshaskpass.sh /usr/local/bin
$ stty -echo; read pw; stty echo
$ echo "$pw" | sshaskpass.sh ssh fileserver date

You should add the remote host to the global ssh_known_hosts file. Otherwise sshfs will fail unless the user has ssh'ed to the host before.

# ssh-keyscan -t rsa,dsa fileserver >> /etc/ssh/ssh_known_hosts

Configure pam_mount.

# vim /etc/security/pam_mount.conf.xml

These are only the changes necessary to get pam_mount to work with sshfs. PAM setup is fairly simple (see /etc/pam.d/common-pammount), and covered elsewhere.

The version of libpam-mount in testing has a new XML configuration format, but the equivalent changes for older versions should hopefully be obvious (I'm not sure it works though, I have only tested with 0.33 in testing).

Find the line that defines the mount command to be used for FUSE. Change it so it looks like this:

<fusemount>sshaskpass.sh mount.fuse %(VOLUME) %(MNTPT) -o %(OPTIONS)</fusemount>

Note that I also changed the OPTIONS part of the line. It is necessary because the way it's defined in the original file, -o and the options are sent in the same argument, breaking mount.fuse's argument parsing.

Add a volume/directory to be mounted. With user set to root and invert set to 1, the line is active for every user other than root.

<volume user="root" invert="1" fstype="fuse" path="sshfs#%(USER)@fileserver:" mountpoint="~/fileserver" options="reconnect,nonempty" />

That should be it. Log in and test.

To mount directly on the home directory instead:

<volume user="root" invert="1" fstype="fuse" path="sshfs#%(USER)@fileserver:" mountpoint="~/" options="reconnect,nonempty,allow_root" />

If using allow_root, you have to uncomment the user_allow_other line in /etc/fuse.conf.

reconnect tells sshfs to reconnect if the connection is lost. nonempty allows mounting on a non-empty mountpoint (home directories are rarely empty). allow_root is necessary to avoid problems with pam_mkhomedir and display managers like GDM, which make sure the user's homedirectory exist on login.

If pam_mount doesn't unmount the sshfs filesystem at logout, saying user seems to have other remaining open sessions (if debugging is enabled in pam_mount.conf.xml), it is probably because you're also using pam_mount when logging in with ssh. To work around this, either don't use pam_mount for ssh logins, or set UsePrivilegeSeparation no in /etc/ssh/sshd_config. The problem is that a file isn't deleted on logout. To delete it manually:

# rm /var/run/pam_mount/user

Update: If using sshfs CVS or a release later than March 28th 2008, you can use the new password_stdin option instead of the wrapper script.

Update 2: As noted in a comment, if using pam_mount version 0.35 or later: the -o workaround is no longer necessary, and pam_mount includes a SSH_ASKPASS wrapper written in C that can be used by specifying ssh="1".

-- John S. Skogtvedt, BzzWare AS.

 

 


Posted by allan (74.94.xx.xx) on Wed 26 Mar 2008 at 20:28
[ Send Message ]
Nice article. I authenticate against my private key (login, and ssh are configured in similar fashion) which then caches my credentials in ssh-agent for later use:

common-auth:
auth required pam_ssh.so keyfiles=id_dsa

gdm:
auth requisite pam_nologin.so
auth required pam_env.so readenv=1
auth required pam_env.so readenv=1 envfile=/etc/default/locale
@include common-auth
@include common-account
session required pam_limits.so
@include common-session
@include pam-ssh-sessiont
@include common-password
session optional pam_script.so user=allan

I was not able to get the mount stuff working reliably on etch, so I ended up using pam_script instead:

pam_script_ses_close:
if [ "$PAM_USER" != "${1#user=}" ]
then
exit 0
fi
fusermount -q -u /home/$PAM_USER/media


/Allan

[ Parent | Reply to this comment ]

Posted by Anonymous (91.164.xx.xx) on Fri 28 Mar 2008 at 23:52
what about the "sshpass" package ?

[ Parent | Reply to this comment ]

Posted by Anonymous (134.76.xx.xx) on Tue 20 May 2008 at 01:11
This has been refined and included in pam_mount 0.35, released April 06 2008.

[ Parent | Reply to this comment ]

Posted by johns (84.208.xx.xx) on Wed 21 May 2008 at 10:15
[ Send Message | View Weblogs ]
Thanks, I added a note to the end of the article.

[ Parent | Reply to this comment ]

Posted by Anonymous (66.195.xx.xx) on Fri 21 Oct 2011 at 14:44
This procedure, taking into account the updates posted, no longer seems to work on Ubuntu 11.10. Please see my issue on Ubuntu's Launchpad:

https://answers.launchpad.net/ubuntu/+question/174686

Granted, a lot has changed since 2008. Can you refresh this article to bring it into 2011?

Thanks!

- Joe

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

Which init system are you using in Debian?






( 1057 votes ~ 6 comments )