Archived Documentation
This documentation is no longer maintained and may contain outdated information. It is preserved for historical reference.
Multiple systemd SSH Agents
This works great on my Debian Bullseye / i3wm system. I don’t see why this wouldn’t work on other distros / DEs but YMMV.
Create a ssh-agent systemd service template
To enable agent creation for all users, create /etc/systemd/user/ssh-agent@.service:
- Create directory structure:
sudo mkdir -p /etc/systemd/user/ - Create the service file: ```ini cat « EOF | sudo tee /etc/systemd/user/ssh-agent@.service [Unit] Description=SSH authentication agent for %I Before=default.target
[Service] Type=simple Environment=SSH_AUTH_SOCK=%t/%i-agent.socket ExecStart=/usr/bin/ssh-agent -D -a %t/%i-agent.socket SuccessExitStatus=2
[Install] WantedBy=default.target
vim: ft=dosini ts=2 sts=2 sw=2 sr et EOF
To enable agent creation for **only you**, create `~/.config/systemd/user/ssh-agent@.service`:
- Create directory structure:
``` bash
mkdir -p ~/.config/systemd/user/
- Create the service file: ```bash cat « EOF > ~/.config/systemd/user/ssh-agent@.service [Unit] Description=SSH authentication agent for %I Before=default.target
[Service] Type=simple Environment=SSH_AUTH_SOCK=%t/%i-agent.socket ExecStart=/usr/bin/ssh-agent -D -a %t/%i-agent.socket SuccessExitStatus=2
[Install] WantedBy=default.target
vim: ft=dosini ts=2 sts=2 sw=2 sr et
EOF
Enabling creation for all users **does NOT** mean that all users can
access *your* agent, it just means that they can create *their own*
agents!
------------------------------------------------------------------------
## Administration
### Manage the ssh-agent service
- Start and enable the agent as your regular user (and similar for the other agent(s)):
``` bash
systemctl --user enable --now ssh-agent@<name>.service
- Check status of the ssh-agent service:
systemctl --user status ssh-agent@<name>.service - Stop the ssh-agent service:
systemctl --user stop ssh-agent@<name>.service
Naming the ssh-agent services
- Whatever name you use for each service will be included in the name of the agent’s socket. For example, if we named one ‘‘foo’’ and another
bar:systemctl --user enable --now ssh-agent@foo.service systemctl --user enable --now ssh-agent@bar.service - We would have two new socket files:
"$XDG_RUNTIME_DIR/foo-agent.socket" "$XDG_RUNTIME_DIR/bar-agent.socket"
Set a default ssh-agent
- Create an environment variable in your preferred startup file (eg
~/.profile,~/.bash_profile, etc):socketpath="$XDG_RUNTIME_DIR/<name>-agent.socket" if [ -S "$socketpath" ]; then export SSH_AUTH_SOCK="$socketpath" fi
Configure SSH to use the agent
- Use the IdentityAgent directive and add the SSH agent socket in your
~/.ssh/config:Host myhost ... AddKeysToAgent yes IdentityAgent "/run/user/%i/<name>-agent.socket" IdentitiesOnly yes - ForwardAgent can be configured to forward the agent in
~/.ssh/config:Host myhost ... AddKeysToAgent yes ForwardAgent "/run/user/%i/<name>-agent.socket" IdentityAgent "/run/user/%i/<name>-agent.socket" IdentitiesOnly yes - Leaving those unconfigured, the hosts will use whatever
$SSH_AUTH_SOCKis set to by default.
Manage the keys in the ssh-agent
- For the default ssh-agent, running only the commands will work:
- Add keys to the agent:
ssh-add ~/.ssh/ed_25519 - List keys in the ssh-agent:
ssh-add -L - Clear keys from the agent:
ssh-add -D
- Add keys to the agent:
Prepend the command with the environment variable to access other ssh-agents:
- Add keys to the agent:
SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/<name>-agent.socket" ssh-add ~/.ssh/work - List keys in the ssh-agent:
SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/<name>-agent.socket" ssh-add -L - Clear keys from the agent:
SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/<name>-agent.socket" ssh-add -D
Configuring IdentityAgent and AddKeysToAgent in
~/.ssh/configwill automatically add the key to the correct agent when you use it.
Gotchas
Debian auto-starts a ssh-agent at login.
- Comment or remove the line in
/etc/X11/Xsession.optionsto stop it from starting:sudo sed -i 's/^use-ssh-agent$/# use-ssh-agent/g' /etc/X11/Xsession.options ssh-add -Lwill only list keys in$SSH_AUTH_SOCK.- Specify the ssh-agent by passing the variable:
SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/<name>-agent.socket" ssh-add -L
- Specify the ssh-agent by passing the variable:
- If using ssh-askpass, add the following to the service file:
# DISPLAY required for ssh-askpass to work Environment=DISPLAY=:0
ssh-agent exits with code 2 which results in ‘failed’ state on stop and I found 2 options to remedy this:
- Inform systemd that a successful exit status is
2:SuccessExitStatus=2 - Prefix the ExecStart with a
-to suppress this behavior:ExecStart=-/usr/bin/ssh-agent -D -a %t/%i-agent.socket - Currently untested: Enable linger for users who need the agents to be active while not logged in:
loginctl enable-linger <user> - https://manpages.debian.org/bullseye/systemd/loginctl.1.en.html#User_Commands
Example
After following the steps above, as an example I’ll create a “default” agent for my everyday ssh keys and a “work” agent for my work ssh keys.
Create “Default” SSH Agent
- Start and enable the “default” ssh-agent:
systemctl --user enable --now ssh-agent@ssh.service - Check status:
systemctl --user status ssh-agent@ssh.service - Configure environment for the “default” agent:
cat << EOF >> ~/.profile socketpath="$XDG_RUNTIME_DIR/ssh-agent.socket" if [ -S "$socketpath" ]; then export SSH_AUTH_SOCK="$socketpath" fi EOF - Source the file to load the variable:
source ~/.profile - Add keys to “Default” agent:
ssh-add ~/.ssh/key - List keys in “Default” agent:
ssh-add -L
Create “Work” Agent
- Start and enable a “work” agent:
systemctl --user enable --now ssh-agent@work.service - Check the status:
systemctl --user status ssh-agent@work.service - Add entries for work machines:
Host work-workmachine-1 HostName XX.XX.XX.XX ForwardAgent "/run/user/%i/work-agent.socket" ProxyJump work-jump - Add wildcard entry for work machines at bottom of
~/.ssh/config:Host work-* User username IdentityFile "%d/.ssh/work" IdentityAgent "/run/user/%i/work-agent.socket" - Add keys to “Work” agent:
SSH_AUTH_SOCK="XDG_RUNTIME_DIR/work-agent.socket" ssh-add ~/.ssh/work - List keys in “Work” agent:
SSH_AUTH_SOCK="XDG_RUNTIME_DIR/work-agent.socket" ssh-add -L
Configuring IdentityAgent and AddKeysToAgent in
~/.ssh/configwill add the key to the correct agent when you first use it.
Bonus Tip
- You can create a
sshdirectory in your$XDG_RUNTIME_DIRto contain the agent socket files. - This is a good opportunity to make use of systemd’s ‘‘tmpfiles.d’’ to create the directory at boot.
- Create directory to hold the config files:
mkdir -p ~/.local/share/user-tmpfiles.d - Create a configuration file:
cat << EOF > ~/.local/share/user-tmpfiles.d/ssh-config.conf d %t/ssh 0700 - - - EOF - Create the directory:
systemd-tmpfiles --user --create - Enable the tmpfiles service so it creates the directory at boot:
systemctl --user enable --now systemd-tmpfiles-setup.service - Enable the cleanup timer:
systemctl --user enable --now systemd-tmpfiles-clean.timer - Edit the paths in the files above to add the
sshdir. For example:Environment=SSH_AUTH_SOCK=%t/ssh/ssh-agent.socket
For multi-user systems, make sure to add/configure files in
/etc/skelso the agent dependencies are set up during user creation.
Conclusion
That’s the general idea and should get your system set up with as many ssh-agents as you would ever want to create. Enjoy!
Links
- https://manpages.debian.org/stable/openssh-client/ssh-agent.1.en.html
- https://manpages.debian.org/stable/systemd/systemd.service.5.en.html#SERVICE_TEMPLATES
- https://manpages.debian.org/stable/systemd/systemd.unit.5.en.html#SPECIFIERS
- https://manpages.debian.org/stable/openssh-client/ssh-agent.1.en.html
- https://manpages.debian.org/stable/openssh-client/ssh_config.5.en.html
- https://manpages.debian.org/stable/openssh-client/ssh-add.1.en.html
- https://manpages.debian.org/stable/systemd/tmpfiles.d.5.en.html
- https://manpages.debian.org/stable/systemd/systemd-tmpfiles.8.en.html
- https://wikitech.wikimedia.org/wiki/Managing_multiple_SSH_agents
- https://unix.stackexchange.com/a/623559