2017-10-16
Getting ssh-agent working in Fedora 26's Cinnamon desktop environment
I have just been through an extensive yak-shaving exercise to use ssh-agent with Cinnamon and have it actually work reliably on Fedora 26.
The first question you might ask is why even use ssh-agent instead of the default of gnome-keyring-daemon. That's straightforward; gnome-keyring-daemon still doesn't support ed25519 keys, despite a very long standing open bug about it (and another bug for ECDSA keys). I'm also not sure if current versions support Yubikey-based SSH keys, which I also care about, and apparently there are other issues with it.
(One charming detail from the GNOME ed25519 bug is that apparently there is no maintainer for either gnome-keyring-daemon as a whole or perhaps just the SSH keys portions of it. This situation doesn't inspire any great fondness in me for gnome-keyring-daemon, to put it one way.)
In Fedora 26, I ran into two problems with my previously-working
ssh-agent environment. The first problem is
that gnome-terminal
doesn't inherit the correct $SSH_AUTH_SOCK
setting, even if it's set in the general environment and is seen
by other programs in my Cinnamon environment.
The core problem seems to be that these days, all your gnome-terminal
windows are actually created by a single master process, and in Fedora 26 this is started through
a separate systemd user .service
. I don't know how that service
is supposed to inherit environment variables, but it doesn't get
the correct $SSH_AUTH_SOCK
; instead it always winds up with
/run/user/${UID}/keyring/ssh
, which is the gnome-keyring-daemon
setting. My solution to this is pretty brute force; I added a
little stanza to my session setup script that symlinked this path
to the real $SSH_AUTH_SOCK
.
(This implies that other systemd user .service
units also probably
have the wrong $SSH_AUTH_SOCK
value, but they're all 'fixed'
by my hack.)
The larger issue is that a ssh-agent
process was only started the
first time I logged in after system reboot. If I logged out and
then logged back in again, my session had a $SSH_AUTH_SOCK
value
set but no ssh-agent
process. In fact, it had the first session's
$SSH_AUTH_SOCK
value, which pointed to a socket that no longer
existed because it had been cleaned up on session exit. I'm not
sure what causes this, but I have noticed that there are a whole
collection of systemd user .service
units under user@${UID}.service
that linger around even after I've logged out of my session. It certainly
appears that while these exist, new Cinnamon sessions inherit the old
session's $SSH_AUTH_SOCK
value. This inheritance is a problem because
of a snippet in /etc/X11/xinit/xinitrc-common:
if [ -z "$SSH_AGENT" ] && [ -z "$SSH_AUTH_SOCK" ] && [ -z "$SSH_AGENT_PID" ] && [ -x /usr/bin/ssh-agent ]; then if [ "x$TMPDIR" != "x" ]; then SSH_AGENT="/usr/bin/ssh-agent /bin/env TMPDIR=$TMPDIR" else SSH_AGENT="/usr/bin/ssh-agent" fi
This starts ssh-agent only if $SSH_AUTH_SOCK
is unset. If it's set
to a bad value, no new ssh-agent is started and your entire session
inherits the bad value and nothing works. My workaround was to change
xinitrc-common to clear $SSH_AUTH_SOCK
and all associated environment
variables if it was set but pointed to something that didn't exist:
if [ -n "$SSH_AUTH_SOCK" ] && [ ! -S "$SSH_AUTH_SOCK" ]; then unset SSH_AGENT unset SSH_AUTH_SOCK unset SSH_AGENT_PID fi
This appears to make everything work.
After I had worked all of this out and set it up, Jordan Sissel shared a much simpler workaround:
I used a oneliner that would kill gnome-keyring and replace it with ssh-agent on the same $SSH_AUTH_SOCK :\ Super annoying, though.
If I was doing this I wouldn't kill gnome-keyring-daemon entirely;
I would just make my session startup script run a ssh-agent
on
/run/user/${UID}/keyring/ssh
(using ssh-agent's -a
command line
argument).
(It's likely that gnome-keyring-daemon does other magic things that my Cinnamon session cares about. I'd rather not find out what other bits break if it's not running, or have it restart on me and perhaps take over the SSH agent socket again.)
PS: I'd file bug reports with Fedora except that I suspect they'd consider this an unsupported environment, and my track record with Fedora bug reports is not great in general. And filing bug reports with Fedora against gnome-keyring-daemon is pointless; if it's not getting action upstream, there's not much Fedora can do about it.