Ubuntu: loading a key into ssh-agent at login with a user-level systemd service

By default, if an SSH key file is dropped into your personal ‘~/.ssh’ directory that matches a set of standard names, then it will automatically be used as an identity when logging into a remote site (id_rsa, id_dsa, id_ecsda, id_ed25519, or identity).

For example, this makes it simple to comply with Github’s requirement to use ssh keys instead of a password because the standard ssh-keygen command generates ‘~/.ssh/id_ed25519’ which will automatically be picked up by ssh.

# generate ssh keypair in ~/.ssh
$ ssh-keygen -t ed25519 -C "your_email@example.com"

# once the public side is loaded into github, validate success
$ ssh -T git@github.com
Hi *****! You've successfully authenticated, but GitHub does not provide shell access.

This should work on Ubuntu without even needing to invoke ssh-agent as a process, and is the simplest way to enable automatic remote authentication.

However, if your file does not match one of these names in the standard location then you need to figure out what hook you will use to invoke ssh-agent and then load the key.   Using .bashrc or .bash_profile could be options, but even better is to write a user level Systemd service.

Here are the steps required to load a user level systemd service that invokes ssh-agent and loads a custom private key required for authentication.

Prerequisites

The ssh-agent needs to use the SSH_AUTH_SOCK environment variable.   The problem is this may already be in use by Gnome, and it will collide unless we disable the Gnome keyring.

# already in use by gnome if set to 'run/user/<id>/keyring/ssh'
echo $SSH_AUTH_SOCKET

If the environment variable above is set, then disable Gnome keyring:

# copy gnome config to personal local settings
mkdir -p ~/.config/autostart
cp /etc/xdg/autostart/{gnome-keyring-secrets.desktop,gnome-keyring-ssh.desktop} ~/.config/autostart/

# disable gnome keyring
echo 'X-GNOME-Autostart-enabled=false' >> ~/.config/autostart/gnome-keyring-ssh.desktop
echo 'X-GNOME-Autostart-enabled=false' >> ~/.config/autostart/gnome-keyring-secrets.desktop

Now set the value that ssh-agent expects for SSH_AUTH_SOCK and reboot for the changes to take.

# show runtime dir, should be /run/user/<id>
echo $XDG_RUNTIME_DIR

# set new desired path for SSH_AUTH_SOCK 
echo SSH_AUTH_SOCK DEFAULT="${XDG_RUNTIME_DIR}/ssh-agent.socket" >> ~/.pam_environment

# force settings
sudo reboot -h now

Enable user-level Systemd service

Now grab the ssh-agent.service file from my github project and place it into your ‘~/.config/systemd’ directory, which is where use-level systemd service files are found.

# make directory for use-level systemd service
mkdir -p ~/.config/systemd/user/

# place user-level systemd service file
wget -O ~/.config/systemd/user/ssh-agent.service https://raw.githubusercontent.com/fabianlee/blogcode/master/systemd/ssh-agent.service

Update the systemd service file with the ssh private key you want to loaded into the ssh-agent.

# set value of the ssh private key you want to load
# %u is a special variable inside a service file
my_private_key="/home/%u/.ssh/id_mygithubsecret"

# update the value in the systemd service file
sed -ie "s@^Environment=KEYFILE=.*@Environment=KEYFILE=$my_private_key@" ~/.config/systemd/user/ssh-agent.service

Enable the user-level systemd service:

# start and check status of systemd service
systemctl --user start ssh-agent
systemctl --user status ssh-agent

# logs will go out to syslog
# service will output the success of ssh-agent
# and will also list the ssh identity loaded
tail -n100 /var/log/syslog

# if $SSH_AUTH_SOCK is set appropriately (e.g. /run/user/<id>/ssh-agent.socket)
echo $SSH_AUTH_SOCK
# then you should be able to see the loaded identity manually
ssh-add -l

# if this is all sucessful, then permanently enable service
systemctl --user enable ssh-agent

If there are errors, then you should edit the service file and reload the daemon.

# if changes made to systemd service file
vi ~/.config/systemd/user/ssh-agent.service

# then daemon needs to be reloaded
systemctl --user daemon-reload
# and restart service
systemctl --user restart ssh-agent

# output goes to syslog
tail -f /var/logs/syslog

 

REFERENCES

unix.stackexchange, creating an ssh-agent systemd service file

wiki archlinux, disabling gnome keyring use of SSH_AUTH_SOCK

man page, ssh-agent

man page, ssh-add

systemd docs

unix.stackexchange. where do I put my systemd unit file

askubuntu.com, user level systemd service

github docs, new ssh agent and adding it to ssh-agent

stackoverflow, using systemd template as workaround for no CLI parameters

unix.stackexchange, gnome keyring and disabling set of SSH_AUTH_SOCK

 

 

NOTES

on other linux flavors, may need to enable ‘AddKeysToAgent’ to personal ssh config. Not necessary with Ubuntu

mkdir -p ~/.ssh/
touch ~/.ssh/config
chmod 600 ~/.ssh/config
chown $USER ~/.ssh/config
echo 'AddKeysToAgent yes' >> ~/.ssh/config

changing github repo from https to git

git remote set-url origin git@bitbucket.org:username/reponame.git

This value in ~/.pam_environment did NOT work to disable gnome keyring.  It takes ‘X-GNOME-Autostart-enabled=false’ to disable

# did not work in newer gnome on ubuntu
GSM_SKIP_SSH_AGENT_WORKAROUND DEFAULT=1