How do I mount an eCryptFS encrypted partition on login?
Solution 1:
Tried this on XFCE, but I'm not positive if Unity/Gnome/KDE/etc are all the same for run-on-login startup files, so YMMV.
A .desktop file in ~/.config/autostart will get run on login, telling it to run a bash script that mounts your encrypted folder should work. Since your home is already encrypted, you could store the other mount passphrase in the bash script, not perfect security but still encrypted on disk, if you didn't want to enter it each time. For example ~/.config/autostart/test.desktop
. A very basic one like this should work:
[Desktop Entry]
Type=Application
Exec=/home/user/.config/autostart/runme.sh
Or to wait a few seconds before starting (ex. give the desktop time to initialize before prompting for a passphrase) and run as root, try this:
[Desktop Entry]
Type=Application
Exec=sudo bash -c "sleep 5; /home/user/.config/autostart/runme.sh"
Or if it needs more detail, copy & edit an existing one (if there are any), or there should be a GUI way to make one under System → Preferences → Startup Applications, then click Add. Or more lines like this should work too (for XFCE anyway, probably cut the OnlyShowIn line):
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=test.sh
Comment=test.sh
Exec=/home/user/.config/autostart/test.sh
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=true
Hidden=false
It just runs the target file, and doesn't work with Exec=~/.config/autostart/test.sh
so replace "user" accordingly. You could probably use one long line instead of pointing it at a bash script.
I'm looking into the mount part now, testing with a virtual pc. There are some complications since you're already using eCryptFS with an encrypted home, and I tested a while ago & you can't have an encrypted home and another encrypted "Private" folder in your home (with encrypted-setup-private
& encrypted-mount-private
), but just using ecryptfs-add-passphrase
& calling mount.ecryptfs
/ mount -t ecryptfs
should work...
Skip to the below script for one that does work. Here's what could work, but I didn't have much luck with. Both these scripts ask you to enter your passphrase, so they're not insecure, though you could edit it if you want, or use xenity
to enter it instead of in a terminal. Here, mount needs to be run as root, so need to insert keys to "sudo" keyring. Running whole script as root should work...? Probably was barking up the wrong tree here.
#!/bin/bash
# mostly copied from ecryptfs-mount-private
# otherhome should be the path to the folder just outside the actual encrypted home,
# For example, /home/.ecryptfs/[user] and must be readable
otherhome=/otherpartition/home/.ecryptfs/user
decrypted=/media/decrypted
WRAPPED_PASSPHRASE_FILE="$otherhome/.ecryptfs/wrapped-passphrase"
MOUNT_PASSPHRASE_SIG_FILE="$otherhome/.ecryptfs/Private.sig"
PW_ATTEMPTS=3
MESSAGE=`gettext "Enter your login passphrase:"`
if [ ! -d "$decrypted" ]; then
mkdir -p "$decrypted" || { echo "$decrypted does not exist, can not create"; exit 1; }
fi
# interactively prompt for the user's password
if [ -f "$WRAPPED_PASSPHRASE_FILE" -a -f "$MOUNT_PASSPHRASE_SIG_FILE" ]; then
tries=0
stty_orig=`stty -g`
while [ $tries -lt $PW_ATTEMPTS ]; do
echo -n "$MESSAGE"
stty -echo
LOGINPASS=`head -n1`
stty $stty_orig
echo
if [ $(wc -l < "$MOUNT_PASSPHRASE_SIG_FILE") = "1" ]; then
# No filename encryption; only insert fek
if printf "%s\0" "$LOGINPASS" | ecryptfs-unwrap-passphrase "$WRAPPED_PASSPHRASE_FILE" - | ecryptfs-add-passphrase -; then
sig=`head -n1 $otherhome/.ecryptfs/Private.sig`
break
else
echo `gettext "ERROR:"` `gettext "Your passphrase is incorrect"`
tries=$(($tries + 1))
continue
fi
else
if printf "%s\0" "$LOGINPASS" | ecryptfs-insert-wrapped-passphrase-into-keyring "$WRAPPED_PASSPHRASE_FILE" - ; then
sig=`head -n1 $otherhome/.ecryptfs/Private.sig`
fnek_sig=`tail -n1 $otherhome/.ecryptfs/Private.sig`
break
else
echo `gettext "ERROR:"` `gettext "Your passphrase is incorrect"`
tries=$(($tries + 1))
continue
fi
fi
done
if [ $tries -ge $PW_ATTEMPTS ]; then
echo `gettext "ERROR:"` `gettext "Too many incorrect password attempts, exiting"`
exit 1
fi
if [ -v fnek_sig ]; then
# filename encryption enabled, $fnek_sig has been set
mount -i -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_sig=$sig,ecryptfs_fnek_sig=$fnek_sig $otherhome/.Private $decrypted
else
# no filename encryption
mount -i -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_sig=$sig $otherhome/.Private $decrypted
fi
else
echo `gettext "ERROR:"` `gettext "Encrypted private directory is not setup properly"`
exit 1
fi
if grep -qs "$otherhome/.Private $decrypted ecryptfs " /proc/mounts 2>/dev/null; then
echo
echo `gettext "INFO:"` `gettext "Your private directory has been mounted."`
echo
fi
exit 0
This script does work,
though I had trouble running any executable script from inside an encrypted home. Had to call it as an argument to bash
/sh
, with
sudo bash -c ./ecryptfs-mount-single.sh [--rw] [encrypted folder] [mountpoint]
Here it is:
#!/bin/sh -e
#
# ecryptfs-mount-single
# Modified by Xen2050 from:
#
# ecryptfs-recover-private
# Copyright (C) 2010 Canonical Ltd.
#
# Authors: Dustin Kirkland <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
error() {
echo "ERROR: $@" 1>&2
echo "Usage: ecryptfs-mount-single [--rw] [encrypted private dir] [mountpoint]"
echo "\tWill attempt to mount [encrypted private dir (.Private)] to [mountpoint]"
echo "\twith standard options: ecryptfs_cipher=aes,ecryptfs_key_bytes=16"
echo "\n\t--rw\tmount with read-write access (optional)"
echo "\t[mountpoint] will attempt to be created if it does not exist"
exit 1
}
info() {
echo "INFO: $@"
}
# We need root access to do the mount
[ "$(id -u)" = "0" ] || error "This program must be run as root."
# Handle parameters
opts="ro"
if [ "$1" = "--rw" ]; then
opts="rw"
shift
fi
if [ -d "$1" ]; then
# Allow for target directories on the command line
d="$1"
# Only supplying one directory
else
error "No private directory found; it must be supplied."
fi
if [ ! -d "$2" ]; then
mkdir -p "$2" || error "mountpoint $2 does not exist, can not create"
fi
# mount directory on the command line
tmpdir=$2
# Determine if filename encryption is on
ls "$d/ECRYPTFS_FNEK_ENCRYPTED"* >/dev/null 2>&1 && fnek="--fnek" || fnek=
if [ -f "$d/../.ecryptfs/wrapped-passphrase" ]; then
info "Found your wrapped-passphrase"
echo -n "Do you know your LOGIN passphrase? [Y/n] "
lpw=$(head -n1)
case "$lpw" in
y|Y|"")
# Use the wrapped-passphrase, if available
info "Enter your LOGIN passphrase..."
ecryptfs-insert-wrapped-passphrase-into-keyring "$d/../.ecryptfs/wrapped-passphrase"
sigs=$(sed -e "s/[^0-9a-f]//g" "$d/../.ecryptfs/Private.sig")
use_mount_passphrase=0
;;
*)
use_mount_passphrase=1
;;
esac
else
# Fall back to mount passphrase
info "Could not find your wrapped passphrase file."
use_mount_passphrase=1
fi
if [ "$use_mount_passphrase" = "1" ]; then
info "To recover this directory, you MUST have your original MOUNT passphrase."
info "When you first setup your encrypted private directory, you were told to record"
info "your MOUNT passphrase."
info "It should be 32 characters long, consisting of [0-9] and [a-f]."
echo
echo -n "Enter your MOUNT passphrase: "
stty_orig=$(stty -g)
stty -echo
passphrase=$(head -n1)
stty $stty_orig
echo
sigs=$(printf "%s\0" "$passphrase" | ecryptfs-add-passphrase $fnek | grep "^Inserted" | sed -e "s/^.*\[//" -e "s/\].*$//" -e "s/[^0-9a-f]//g")
fi
case $(echo "$sigs" | wc -l) in
1)
mount_sig=$(echo "$sigs" | head -n1)
fnek_sig=
mount_opts="$opts,ecryptfs_sig=$mount_sig,ecryptfs_cipher=aes,ecryptfs_key_bytes=16"
;;
2)
mount_sig=$(echo "$sigs" | head -n1)
fnek_sig=$(echo "$sigs" | tail -n1)
mount_opts="$opts,ecryptfs_sig=$mount_sig,ecryptfs_fnek_sig=$fnek_sig,ecryptfs_cipher=aes,ecryptfs_key_bytes=16"
;;
*)
continue
;;
esac
(keyctl list @u | grep -qs "$mount_sig") || error "The key required to access this private data is not available."
(keyctl list @u | grep -qs "$fnek_sig") || error "The key required to access this private data is not available."
if mount -i -t ecryptfs -o "$mount_opts" "$d" "$tmpdir"; then
info "Success! Private data mounted at [$tmpdir]."
else
error "Failed to mount private data at [$tmpdir]."
fi
Unmounting before/when logging out, and maybe removing the keys from the kernel keyring (with keyctl
clear or purge, sudo keyctl clear @u
clears all) are probably good ideas. I had a 2nd folder mounted inside an encrypted home, and logged out, it apparently unmounted the 2nd folder (not in /proc/mounts) but still showed up in mount
.