personal blog
git clone git://
Log | Files | Refs | README

commit e846df30bdd5f90c743a6ecc997860f371accc6a
parent a9aff7316b28d489dbf360d3ca0c0a0c59e4b5a8
Author: pyratebeard <>
Date:   Fri,  2 Dec 2022 09:23:50 +0000

Merge branch 'secret_agent_man'

Aentry/ | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aimg/sshkey_poll_results.png | 0
2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/entry/ b/entry/ @@ -0,0 +1,79 @@ +For as long as I can remember I have used one SSH key pair for each device. I know there are some who prefer to use a different key for different accounts. I tried this in the past but felt it didn't increase the security sufficiently enough to warrant the complexity in my use case. + +I have three main devices; my desktop PC, my laptop, and my phone. This means that any system I need to `ssh` on to requires three entries in the *authorized_keys* file. + +I use `drist` for ensuring my keys are on my servers (see a [previous post](20210305-the_usefulness_of_drist.html){target="_blank" rel="noreferrer"} about this tool), meaning I can connect from any of my devices. + +When I rebuilt my laptop recently I generated a new key pair, then updated my `drist` configuration and pushed it out to my systems. All was well until I wanted to connect to my account on []({target="_blank" rel="noreferrer"}, and realised I had not pushed the updated public key for my laptop to my SDF account. + +This got me thinking. For those that use a GPG key, it is very common to have one key that belongs to an identity. In my case [my key]({target="_blank" rel="noreferrer"} is used with my email, git commit signing, and other encryption to prove I am pyratebeard. The private key has been securely copied to my laptop and phone and imported into the GPG keyring. + +Could one SSH key pair for _my identity_ be enough? If the private key was securely copied to my devices, then my systems and any accounts that require `ssh` only need to know about one key. + +To get an idea of how others work I put out [a poll]({target="_blank" rel="noreferrer"} on Mastodon. + +![results](/img/sshkey_poll_results.png#fitwidth) + +It surprised me that an equal number of people use one key per device as those that use one key for all. + +Maybe using one key isn't such a bad idea. Of course this changes my threat model. If any of my devices are compromised I would have to replace the key on all of them. There has to be a secure way of achieving this. + +When a GPG key is loaded into your keyring you don't have to keep the private key. With SSH keys there is no keyring, `ssh` uses the private key file when connecting. There is of course `ssh-agent` which can load the key in memory, but the private key still has to be read after a reboot. The key will still need a passphrase to be used, just like using your GPG key still requires a passphrase, but something about having the GPG key in a keybox file seems more secure than the SSH key "just lying around". + +As it turns out you can add an SSH key as a subkey to a GPG key, then `gpg-agent` will provide the authentication instead of `ssh-agent`, and more importantly you don't need an SSH private key file. + +At first I attempted to add my existing SSH key to my GPG key, but hit a few blocks and started down a rabbit hole. Instead I opted to create a new SSH key. This would mean I would have to push it out to everywhere I needed it, a small price for ease of setting up. + +It is a good idea to take a backup of your existing GPG key +``` +gpg2 -a --export-secret-keys <key_id> > gpg-backup.asc +``` + +To generate a new SSH key incant +``` +gpg2 --quick-add-key <key_id> ed25519 auth 0 +``` + +Now is a good time to take the new SSH public key and copy it everywhere you need it. You could use a tool such as `drist` or do it manually. I could not figure out how to do it with `ssh-copy-id`, if anybody knows how then please get in touch +``` +gpg2 --export-ssh-key <key_id> +``` + +Next we can stop our `ssh-agent` and `gpg-agent`. I use [keychain]({target="_blank" rel="noreferrer"} for managing my agents so incant +``` +keychain --agents ssh,gpg -k +``` + +We have to tell GPG which subkey to use for SSH, we do this by taking the _keygrip_ and putting it into GPG's _sshcontrol_ file +``` +gpg2 -k --with-keygrip <key_id> +echo <keygrip> >> ~/.gnupg/sshcontrol +``` + +Now to start the `gpg-agent` back up, no `ssh-agent` required. In my `zsh` config I modified the `keychain` command to remove the option to start `ssh-agent`. I then set the `SSH_AUTH_SOCK` variable +``` +eval $(keychain -q --agents gpg --nogui --eval 0xC7877C715113A16D) +gpg-connect-agent updatestartuptty /bye >/dev/null +if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ] ; then + export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" +fi +``` + +You can also see a `gpg-connect-agent` command in there. This is used to tell GPG to update the TTY it is using. GPG has no way of knowing which TTY you are using, so when it requires `pinentry` it needs to know which TTY to listen for user interaction. You could avoid this by using `pinentry` with a GUI. + +Now if you open a new terminal, or source your config, SSH should work using your GPG key. You will be prompted to enter a passphrase with the first connection, this is the same as your GPG passphrase. + +Now you can copy your updated GPG key to your other devices (you may need to delete the existing key before importing) +``` +gpg2 -a --export-secret-keys <key_id> > gpg_with_ssh.asc +``` + +The SSH subkey is working okay so far. I am using it on my desktop (running Arch Linux), my laptop (running OpenBSD), and with [Termux]({target="_blank" rel="noreferrer"} on my phone. + +There have been a few issues though, hopefully easily fixed with a bit of investigating. On Termux I noticed that if I have two (or more) `tmux` windows I need to rerun the `gpg-connect-agent` command otherwise `pinentry` may startup on the other window. + +On OpenBSD `pinentry` seems to crash `tmux`. This is my first OpenBSD install as a workstation so I am still figuring things out. + +During my research I was also reminded of SSH certificates and their advantages over key pairs. I am going to delve into that with my own systems (expect a write up!) but it doesn't help on systems I do not control, such as SDF. + +Relying only on my GPG for SSH still feels a bit odd but I will stick with it for a while and see how it goes. It certainly makes my *authorized_keys* file management easier! diff --git a/img/sshkey_poll_results.png b/img/sshkey_poll_results.png Binary files differ.