Creating A Safe Directory With PAM And EncFS
Creating A Safe Directory With PAM And EncFSContents
. Introduction Introduction
I do work a lot with programs with require credentials Installation of encfs
tar -xzf encfs-*.tar.gz
mkdir -p ~/test/encrypted
The directory encrypted contains the encrypted files, and remains on the harddisk after unmounting and/or shutting down.
The directory decrypted is the interface to it, and disappears when unmounted and/or shutting down. I've chosen for a seperate map in the local machine where for every user logging in a encrypted (and an interface to it) will be stored:
install -m777 -o root -g root /var/lib/encfs
Installation of pam_script
tar -xzf pam-script-*.tar.gz
Pam_script.so uses some parameters. All of them are described in the README in the
source directory. Important are: common parameters
parameters only in the auth part
only in the session part
Adjusting PAM configuration
I've used pam_script in the auth and in the session part of the pam (login,kde) service file. The auth part
Pam_script has the ability (from version 0.1.5) to get the password provided at login, and make
this via an evironmentvariable PAM_AUTHTOK available to scripts.
cat /etc/pam.d/login -- snip -- auth required pam_shells.so auth required pam_script.so expose=1 auth sufficient pam_unix.so use_first_pass auth sufficient pam_ldap.so use_first_pass auth required pam_script.so onauth=/etc/security/onauth.failed auth required pam_deny.so
As you can see I use pam_scripts.so multiple times: The scripts
cat /etc/security/onauth #!/bin/bash
retcode=0;
userid=$1
service=$2
authtok=$3
if [ -z "$authtok" ]; then
authtok=$PAM_AUTHTOK
fi;
userproperties=$(getent passwd | grep -m 1 -E "^$userid")
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
if [ -d /var/lib/encfs ]; then
# create a safe
if [ ! -d /var/lib/encfs/$userid ]; then
install -m700 -o $uidnr -g $gidnr -d /var/lib/encfs/$userid
fi;
if [ ! -d /var/lib/encfs/$userid/encrypted ]; then
install -m700 -o $uidnr -g $gidnr -d /var/lib/encfs/$userid/encrypted
fi;
if [ ! -d /var/lib/encfs/$userid/unencrypted ]; then
install -m700 -o $uidnr -g $gidnr -d /var/lib/encfs/$userid/unencrypted
fi;
if [ ! -d /var/lib/encfs/$userid/run ]; then
install -m700 -o $uidnr -g $gidnr -d /var/lib/encfs/$userid/run
fi;
#
# test the encrypted directory is not already mounted
#
if [ -z "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
#
# create a password-provide-program
#
cd /var/lib/encfs/$userid
md5authsum=$(echo $authtok | md5sum | cut -d " " -f 1)
echo "$md5authsum" > run/tmp
echo "$md5authsum" >> run/tmp
chown $uidnr:$gidnr run/tmp
rm -rf encrypted/*
rm -f encrypted/.encfs*
cat run/tmp | encfs -S /var/lib/encfs/$userid/encrypted /var/lib/encfs/$userid/unencrypted -- -o allow_root 1>>/dev/null
fi;
#
# this is what's all about: storing the credentials in a file
# in this case the password
#
if [ -n "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
cd /var/lib/encfs/$userid/unencrypted/
if [ -f password.tmp ]; then
rm password.tmp
fi;
echo $authtok > password.tmp
fi;
fi;
Some remarks:
#!/bin/bash
userid=$1
service=$2
userproperties=$(getent passwd | grep -m 1 -E "^$userid")
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
#
# this script is run when the authentication failed
# a safe encrypted is still created
# so it's important to remove this safe again
#
if [ -d /var/lib/encfs ]; then
if [ -d /var/lib/encfs/$userid/unencrypted ]; then
#
# test the encrypted directory is not already mounted
#
if [ -n "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
if [ $(w -h $userid | wc -l) -eq 0 ]; then
#
# this user is not logged in on more tty's
# just remove everything and umount the encrypted directory
#
rm -rf /var/lib/encfs/$userid/unencrypted/*
fusermount -u /var/lib/encfs/$userid/unencrypted
rm -rf /var/lib/encfs/$userid/encrypted/*
rm -f /var/lib/encfs/$userid/encrypted/.encfs*
else
#
# this user is still logged in
#
rm -f /var/lib/encfs/$userid/unencrypted/password.tmp
fi;
fi;
if [ -z "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
rm -rf /var/lib/encfs/$userid/encrypted/*
rm -f /var/lib/encfs/$userid/encrypted/.encfs*
rm -rf /var/lib/encfs/$userid/unencrypted/*
fi;
fi;
fi;
Some remarks: The session part
When the session part is reached, it's sure that the credentials provided (password) are correct. This
means that the password - in the the auth fase stored in a temporary file - is correct. So one thing to do in the
session fase is to move the contents of the password.tmp to the permanent one, password. cat /etc/pam.d/login -- snip -- session required pam_mkhomedir.so session required pam_motd.so session optional pam_mail.so empty dir=/var/mail session optional pam_lastlog.so session required pam_env.so session required pam_script.so session required pam_unix.so session required pam_ldap.so The scriptsOn session opencat /etc/security/onsessionopen #!/bin/bash
retcode=0;
userid=$1
service=$2
userproperties=$(getent passwd | grep -E "^$userid")
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
if [ -d /var/lib/encfs/$userid/encrypted ]; then
#
# test the encrypted directory is mounted
#
if [ -n "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
if [ -f /var/lib/encfs/$userid/unencrypted/password.tmp ]; then
if [ -f /var/lib/encfs/$userid/unencrypted/password ]; then
#
# an old passwordfile found
#
if [ -z "(diff /var/lib/encfs/$userid/unencrypted/password /var/lib/encfs/$userid/unencrypted/password.tmp)" ]; then
#
# new password and old one are the same
#
rm /var/lib/encfs/$userid/unencrypted/password.tmp
else
mv /var/lib/encfs/$userid/unencrypted/password.tmp /var/lib/encfs/$userid/unencrypted/password
fi;
else
#
# password not found : it's the first login.
# just move the temporary passwordfile to the remaining
#
mv /var/lib/encfs/$userid/unencrypted/password.tmp /var/lib/encfs/$userid/unencrypted/password
fi;
fi;
if [ -d /etc/session.d/pam/onsessionopen ]; then
for script in /etc/session.d/pam/onsessionopen/*.sh; do
if [ -x $script ]; then
eval $script $userid $service
fi
done;
fi;
fi;
fi;
On session closecat >> /etc/security/onsessionclose #!/bin/bash
userid=$1
service=$2
userproperties=$(getent passwd | grep -E "^$userid")
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
#
# this script is run when the authentication failed
# a safe encrypted is still created
# so it's important to remove this safe again
#
if [ -d /var/lib/encfs ]; then
if [ -d /var/lib/encfs/$userid/unencrypted ]; then
#
# test the encrypted directory is already mounted
#
if [ -n "$(mount | grep -w /var/lib/encfs/$userid/unencrypted )" ]; then
if [ $(w -h $userid | wc -l) -eq 0 ]; then
rm -rf /var/lib/encfs/$service.$userid/unencrypted/*
fusermount -u /var/lib/encfs/$userid/unencrypted
rm -rf /var/lib/encfs/$userid/encrypted/*
rm -f /var/lib/encfs/$userid/encrypted/.encfs*
fi;
else
rm -rf /var/lib/encfs/$userid/encrypted/*
fi;
if [ -d /etc/session.d/pam/onsessionclose ]; then
for script in /etc/session.d/pam/onsessionclose/*.sh; do
if [ -x $script ]; then
eval $script $userid $service
fi
done;
fi;
fi;
fi;
Some remarks: CLOSE_SESSIONS yes
to the /etc/login.defs file. The result
The encrypted directory contains now the credentials, which are only available to the owner and root. By creating a file mount.cifs.conf with these values:
touch /var/lib/encfs/$userid/unencrypted/mount.cifs.conf Now mounting a cifs share is possible with:
/sbin/mount.cifs //fileserver/public /home/sbon/netshares/fileserver/public -o credentails=/var/lib/encfs/sbon/unencrypted/mount.cifs.conf,ip=192.168.0.2
touch /var/lib/encfs/sbon/unencrypted/fusesmb.conf The last link is because fusesmb (started by sbon) expects the configuration file there. fusesmb /home/sbon/network when I'm logged in as myself (sbon). The directory /home/sbon/network has to exist.
|
Join the discussion.
www.seamlessenterprise.com
IP Convergence
Integrate your wireless and wireline networks.
Learn how from the experts at Sprint.
www.seamlessenterprise.com
Wireless & Wireline Integration
Thoughts, strategies and solutions: join the discussion
www.seamlessenterprise.com
Unified Communications 2009
Join the Discussion. Now.
www.seamlessenterprise.com







Recent comments
23 hours 54 min ago
1 day 1 hour ago
1 day 4 hours ago
1 day 7 hours ago
1 day 10 hours ago
1 day 11 hours ago
1 day 11 hours ago
1 day 12 hours ago
1 day 13 hours ago
1 day 14 hours ago