[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: *Now* what is starting ssh-agent?



Jul. 26, 2022 17:00:46 Greg Wooledge <greg@wooledge.org>:

> On Tue, Jul 26, 2022 at 03:40:48PM -0300, Chris Mitchell wrote:
>> Here's my service file:
>>
>> $ cat /etc/systemd/user/ssh-agent.service
>
> According to systemd.unit(5) this directory is for "User units created
> by the administrator".

Yup, that's me!
In practice, it means units placed there are user units that are
available to all users on the system, so they can
start/stop/enable/disable/… their own instances of those units via
"systemctl --user" commands (or root can do the same for all users at
once with "systemctl --global). A unit in this directory will supersede
a same-named unit in /usr/lib/systemd/user, and may in turn be
superseded on a user-by-user basis via their respective
~/.config/systemd/user directories.

> PID 1 is the system instance of systemd.  Not a user instance.
> The ssh-agent with PID 3011 is being started by the system instance,
> so it is a system unit.  It's not your locally defined user unit.

Oh, yes. I should have realized that. Weird that the system instance
would be configured to start an ssh-agent at all, but I'll definitely
look there next.

> Things you should look at next, I suppose:
>
> systemctl status ssh-agent
> systemctl --user status ssh-agent

The --user one shows that my custom "global" user unit at
/etc/systemd/user is up and running as expected, which I can verify by
manually changing SSH_AUTH_SOCK to point to the socket specified there
and accessing the agent. If the *system* systemd instance is actually
launching an ssh-agent and injecting corresponding env-vars into my
regular user environment, that is deeply strange, and I'm reasonably
sure I haven't done anything that could cause that outcome.

# systemctl status ssh-agent.service
  Unit ssh-agent.service could not be found.

# systemctl list-units --all *ssh*
      UNIT LOAD ACTIVE SUB DESCRIPTION
  0 loaded units listed.

> Starting an ssh-agent via systemd is completely outside of my
> experience, though, and I don't really understand why you'd attempt
> it.  It's not clear to me *at all* how you would communicate the
> environment variables from the ssh-agent invocation over to the
> user's login session.

My setup is to have each user's "user" systemd instance manage their
ssh-agent (which is also how the Bookworm package handles it, though
with some differences in the implementation details). Being a
long-running daemon type process that provides a service to other
processes, ssh-agent struck me as an ideal candidate for being handled
by the service manager. The only environment variable that remains
relevant now that systemd handles the process control stuff is
SSH_AUTH_SOCK, and because I specify a consistent socket location, I
can set that statically for all login sessions, the same way you would
go about adding a custom location to PATH or whatever.

Advantages include:
* hands-on learning experience with systemd, which is clearly here to
  stay,
* make ssh-agent start, and behave consistently, regardless of what DE
  I use, or no DE, or no X or Wayland or graphical anything,
* any user who has a non-zero number of active login sessions gets
  exactly one ssh-agent process, regardless of what "type" of session(s)

For example: if I log in to XFCE4, load a few ssh keys into my
ssh-agent, and something causes X to hang, I swap to VT1 and log in
there. Systemd no-ops my ssh-agent.service because it's already
running, and access to ssh-agent works right there in VT1, including the
already-loaded keys. Now I restart lightdm, which kills the session
that started my ssh-agent.service, but because I still have a non-zero
number of active login sessions (VT1), systemd keeps that service
running. Then I can swap back to the lightdm greeter and log in to
XFCE4, or KDE, or Enlightenment, or whatever, and my ssh-agent is
already up and ready with the keys I loaded earlier. Just for fun, if I
want to make ssh-agent socket-activated for every user on the system
instead of auto-started at login, I can drop a ~5 line ssh-agent.socket
file in /etc/systemd/user/ alongside the ssh-agent.service file,
systemctl --global disable the .service unit and enable the .socket
unit instead, and that's it.

I've been using this "global" systemd user unit to manage ssh-agent for
a couple of years now, and it's just about perfect… except when some
legacy workaround comes along and clobbers things.

Cheers!
 -Chris


Reply to: