How can I flush my ssh keys on power management activity?
Using ssh-agent
and private keys per the usual. Everything's working as normal.
My question regards best practices on flushing keys from ssh-add
on activity like sleep, suspend, hibernate, etc. I thought about writing a simple wrapper around those commands, but then wondered if are they even called? Or does the kernel initiate this activity directly? Are the PM utilities strictly userland?
I would like this additional layer of security beyond locking my screen, etc. and was wondering if anyone else had solved this elegantly or has best practices to recommend. Thanks.
Solution 1:
You might be able to have a user daemon listen for the status change over D-Bus. It looks like gnome-power-manager doesn't expose any signals for this, but you might be able to get something from hal or DeviceKit-power/upower.
Solution 2:
I have a little pm
script that run's user-defined scripts for each logged in user on suspend/hibernate, resume/thaw. I've used this to kill or restart processes that don't behave well over suspend. User's can create scripts in ~/.user-pm
which are run in lexicographic order on suspend and reverse order on resume. $1
has the pm operation name.
You could simply add a user-script that calls "ssh-add -D
" on suspend/hibernate. (you'll have to look up the SSH_AUTH_SOCK
somewhere, but I assume you'd need that for any solution).
Here's the global pm
hook:
> cat /etc/pm/sleep.d/10_run_user_parts
#!/bin/sh
USER_PM_DIR=".user-pm"
# foreach logged in user
for user in `users | grep -o "\S*" | sort -u`; do
user_home=`getent passwd "${user}" | awk -F: '{print $6}'`
# check user has a valid home-directory
[ -d $user_home ] || continue
user_pm_dir="$user_home/$USER_PM_DIR"
# check for user-pm directory
[ -d "$user_pm_dir" ] || continue
# call run-parts as $user
case "$1" in
hibernate|suspend)
su -c "run-parts --arg=\"$1\" \"${user_pm_dir}\"" "${user}"
;;
thaw|resume)
su -c "run-parts --reverse --arg=\"$1\" \"${user_pm_dir}\"" "${user}"
;;
*) exit $NA ;;
esac
done
I'm on ubuntu - this should work for debian too - otherwise, YMMV
Solution 3:
If you add your key using the "-c" option to "ssh-add", it requires that you confirm every use. This isn't as good as removing the key from your agent on suspend, if you also lock your screen it can have a similar effect, since the key use can't be confirmed until you login.
In the past I accomplished this key removal by running a simple script that woke up every few seconds and looked for the program that locks the screen, and if it was found it would do the "ssh-add -D". Then once it went away, it would invoke the "ssh-add -c" again to ask me for the password. I ended up switching to just relying on confirmation and screen locking when I suspend or leave the keyboard.
Solution 4:
Thanks @Greg for your answer, I took the liberty of expanding on it to make it more "freedesktop" compliant, since pm-utils is a freedesktop.org project.
This script now will work in config.d
, power.d
, and sleep.d
with a copy or a symlink. It'll then look for scripts to run in ~/.config/pm/
using the same folder names (config.d
, power.d
, and sleep.d
) as /etc/pm
.
#!/bin/sh
scriptdir=`cd $(dirname $0) && pwd`
USER_PM_DIR=".config/pm/$(basename $scriptdir)"
# foreach logged in user
for user in `users | grep -o "\S*" | sort -u`; do
user_home=`getent passwd "${user}" | awk -F: '{print $6}'`
# check user has a valid home-directory
[ -d $user_home ] || continue
user_pm_dir="$user_home/$USER_PM_DIR"
# check for user-pm directory
[ -d "$user_pm_dir" ] || continue
# call run-parts as $user
case "$1" in
hibernate|suspend)
su -c "run-parts --arg=\"$1\" \"${user_pm_dir}\"" "${user}"
;;
thaw|resume)
su -c "run-parts --reverse --arg=\"$1\" \"${user_pm_dir}\"" "${user}"
;;
*) exit $NA ;;
esac
done
Then this is my script to remove all keys from the ssh-agent
on suspend/hibernate, and re-add a key used for SparkleShare. Just to be sure, it also checks for other ssh-agent
s and removes all the keys from them.
#!/bin/sh
case "$1" in
hibernate|suspend)
if [ ! -z $SSH_AUTH_SOCK ] && [ -r $SSH_AUTH_SOCK ]; then
ssh-add -D
fi
for SSH_AUTH_SOCK in `find /tmp/ssh-*/agent.* -user $USER`; do
SSH_AUTH_SOCK=$SSH_AUTH_SOCK /usr/bin/ssh-add -D
done
;;
thaw|resume)
if [ ! -z $SSH_AUTH_SOCK ] && [ -r $SSH_AUTH_SOCK ]; then
/usr/bin/ssh-add -t 0 ~/.config/sparkleshare/2011-03-21_14h15.key
fi
for SSH_AUTH_SOCK in `find /tmp/ssh-*/agent.* -user $USER`; do
SSH_AUTH_SOCK=$SSH_AUTH_SOCK ssh-add -t 0 ~/.config/sparkleshare/2011-03-21_14h15.key
done
;;
esac