[HowTo] Use kwallet as a login keychain for storing SSH key passphrases on KDE

Difficulty: ★★☆☆☆

INTRODUCTION

Every time you need to authenticate an SSH session on KDE you’ll be prompted for your SSH key passphrase. Below are the steps that to remove this “feature”:

  1. Set kwallet as a passphrase store for SSH keys.
  2. Start the SSH agent upon login as a systemd service.
  3. Add all private keys present in ~/.ssh/ to the SSH agent.

INSTRUCTIONS

1. Install any required packages

Update your system and install the required packages as follows:

sudo pacman -Syu --needed kwallet ksshaskpass kwalletmanager

The modules required to unlock kwallet at login are located in the kwallet-pam and/or signon-kwallet-extension packages. Reinstalling these ensures you have everything. kwalletmanager isn’t necessary, but provides a convenient GUI to view the contents of kwallet .

2. Set the SSH_ASKPASS environmental variable

Use nano to create a new shell script named ssh-askpass.sh in /etc/profile.d/:

sudo nano /etc/profile.d/ssh-askpass.sh

Then add the following text:

#!/bin/sh

export SSH_ASKPASS=/usr/bin/ksshaskpass

NB: Alternatively, if you do not wish make SSH_ASKPASS a system-wide environmental variable you can set it in ~/.zshenv, ~/.bashrc, or equivalent.

3. Set the SSH_AUTH_SOCK environmental variable

Use nano to edit your login shell, e.g. ~/.zshenv, ~/.bashrc, etc:

nano ~/.zshenv

Then add the following text:

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"/ssh-agent.socket

4. Create the ssh-agent systemd service

Create the user-level systemd directory if it does not already exist:

mkdir -p ~/.config/systemd/user

Use nano to create the following ssh-agent systemd service:

nano ~/.config/systemd/user/ssh-agent.service

Then add the following text:

[Unit]
Description=SSH agent (ssh-agent)

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
Environment=DISPLAY=:0
ExecStart=ssh-agent -D -a $SSH_AUTH_SOCK
ExecStop=kill -15 $MAINPID

[Install]
WantedBy=default.target

5. Reload the user-level system daemon

Run the following code to reload the user-level system daemon:

systemctl --user daemon-reload

6. Enable the new user-level systemd service

Enable the new user-level systemd service:

systemctl --user enable ssh-agent.service

7. Create startup script to add SSH keys to the agent

Use nano to create the following ssh-add.desktop startup script:

nano ~/.config/autostart/ssh-add.desktop

Then add the following text:

[Desktop Entry]
Exec=ssh-add -q ~/.ssh/key1 ~/.ssh/key2 ~/.ssh/key3 < /dev/null
Name=ssh-add
Type=Application

Note that your keys need to be listed in the Exec line.

8. Reboot

Reboot for the changes to take effect.

sudo systemctl reboot

9. Add your SSH key passphrases to kwallet

You may be prompted by a series of dialogue boxes asking for each of your SSH key passphrases. If not, run the following code for each of your SSH private keys to store their passphrases in kwallet:

ssh-add -q /path/to/key < /dev/null

AUTHOR’S NOTES:

12 Likes

Please have a look how to get it to work with ssh-agent running as systemd service.
in the arch forum under this title (I’m not allowed to post links):
plasma: ssh-add autoscript doesn’t work w ssh-agent as systemd-service

I’ve had a go at rewriting this. Let me know how you get on.

2 Likes

Hi I think it should be systemctl and not systemd in steps 5 and 6.

HTH
Jojo

3 Likes

Welcome and right you are: wiki post edited accordingly

2 Likes

Ooooohhh, THANK YOU Feakster and friends!

I was trying the Arch Wiki instructions (as a matter of fact, those in the KDE Wallet and SSH Keys pages) but they were not working. What’s different is the use of a systemd service and SSH_ASKPASS export in the profile.

  • I was asked for my SSH keys’ passwords on next logon
  • Now VSCode (from AUR) does not ask for my key’s password when I connect to a remote VM with Remote-SSH

I couldn’t be happier! It’s a small thing, but being asked for my password everytime I changed folder on my VM in VS Code was really a pain.

1 Like

# ssh-add -q ~/.ssh/id_ed25519 < /dev/null
Could not open a connection to your authentication agent.

Looks like your ssh agent isn’t running.

Today I felt like I need to once again try this and have it fixed myself. My findings are as follows:

This is the only way it worked for me. Adding lines to ~/.bashrc, ~/.zshrc and ~/.config/fish made no effect.
So, a working route for me was adding

export SSH_ASKPASS=/usr/bin/ksshaskpass
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"/ssh-agent.socket

to /etc/profile.d/ssh-askpass.sh

Another hiccup. Under no circumstances it worked as an auto-generated systemd service, failing each time and always. I made it work only with full path to the key of interest and without “< /dev/null” part. Neither tilde dash nor $HOME could be accepted in the path to ssh key.

And finally I have no prompt for the key password in Plasma - something I have had in Gnome by default since forever. Pity we have to jump so many hoops to get here but anyway it was well worth it.

1 Like

Super helpful - thank you. For some reason the funtoo keychain simply does not work, and git asks for every push anyway, even though it says it is adding the keys to the keychain. Oh well. Done thinking about it thanks to this article.

Hello, sorry for reopening this topic.

I followed all the steps in this tutorial and the linked sites and it seems to be working, but vscode is still asking me for my ssh key passphrase every time it sends a command to the GitHub repo. Is there anything I can change so that vscode uses the wallet/ssh-agent?

Last update screwed something up. None of this work.

Hi,

I’ve followed this guide to automate borg backups using kwallet, ksshaskpass, ssh-askpass, ssh-agent, ssh-add and systemd units (services). The procedure is well described here and the instructions helped me a lot - thank you!

I’ve successfully automated periodic backups of my home directory to one repository (using a systemd user service) but have some trouble automating periodic backups of my system files to another repository (using a systemd system service). The problem is probably not so much borg-, but rather systemd- and kwallet-related and I assume that user privileges and environment variables/ settings play a role. Hope you don’t mind me seeking assistance here.

The part I’m struggling with is the following:

In the script executed from the systemd user service to backup /home/<user> I use

BORG_PASSCOMMAND="kwalletcli -f 'borg' -e 'passphrase'"

to retrieve the passphrase of the borg keyfile from kwallet. Works like a charm.

In the script executed from the systemd system service (i. e. as root) to backup system files I use

BORG_PASSCOMMAND="sudo -E -u <user> kwalletcli -f \'borg\' -e \'passphrase\'"

to retrieve the passphrase as described on StackExchange Unix & Linux (post 611188 in “kwallet get password as root user” - first and only answer as of 2023-10-19T22:00:00Z)

If I execute the corresponding script directly as root, everything works perfectly fine. The passphrase is read from kwallet and the backup is created as expected. But if the script is being executed from the systemd system service, borg fails with the error message “cannot open wallet”.

I declare/ export some (environment) variables in that script to access kwallet and the ssh-agent of my usual (login) user, namely USER, LOGNAME, HOME, SSH_ASKPASS, SSH_ASKPASS_REQUIRE and SSH_AUTH_SOCK. As mentioned, this works fine if the script is being executed directly as root, but not in the systemd system service. SSH connection works including reading the passphrase of the private key from kwallet.

Any ideas which puzzle piece I am missing to get this running also inside the systemd system service?

EDIT 2023-10-23:

I managed to set it up properly so it is working now.

I had to set/ export a few more environment variables in the script executed by the systemd system service, namely DBUS_SESSION_BUS_ADDRESS, DESKTOP_SESSION, DISPLAY=":0", KDE_APPLICATIONS_AS_SCOPE, KDE_FULL_SESSION="true", KDE_SESSION_UID and XDG_RUNTIME_DIR. I used printenv to compare the environments when executing the script directly as root and from the systemd system unit.

I then encountered the issue desribed on StackExchange Unix & Linux in post “‘Invalid MIT-MAGIC-COOKIE-1 key’ when trying to run program remotely”, it was solved by the first (as of 2023-10-22T22:00:00Z) answer to that subject (post 496877).

For me there was just one crucial part missing for this to work:
The autostart file in ~/.config/autostart also needed this line to actually work:

X-KDE-AutostartScript=true

Inconsistency detected.
I do not use this method so I prefer to not edit the wiki, maybe there are other things at play here that I am missing.
The consistent way would be to use .zshrc

Also, I think “system-wide” would be /etc/profile or /etc/environment.