Last month the debian package for gnupg was changed in the unstable branch from providing version 1.4 to providing 2.1. Users of debian jessie and even stretch in principle shouldn't be concerned by this change. But for sid users this is a major change and some ppl might need a bit of guidance through the process... well at least I needed some. Here's a post about what issues I encountered and how I fixed them or my comprehension of their cause.
The change needs some readjusting, but it is for good reasons. The use of agents is interesting for some security reasons, and the storage format is way faster than it was in gpg 1.4. This and the codebase for 2.1 is apparently in a way better shape.
First and foremost, ppl who read this post should probably familiarize themselves with the changes that the version brings.
Auto-migration of keys happened long ago
First thing that I got sorted out was this: I had had gnupg2 installed on my computer for quite a while already. It was installed automatically as a dependency to password-store. Normally gpg2 automatically migrates your public and secret keyrings automatically for you to the new storing format. This is super neat, but it happened automatically when I first used password-store, and then I didn't migrate to using gpg2 (oops).
Re-importing secret keyring
During the time I persisted in using 1.4, I created a new authentication subkey for use with monkeysphere. This subkey was not automatically migrated when I finally switched to gpg 2.1 thanks to the package change. This is normal: the automatic migration happened a bunch of time ago.
The fix was easy, reimport secret key material:
gpg --import ~/.gnupg/secring.gpg
Using the new, faster public key storage
You also probably want to move your public keyring to the new storage format which is way faster. As described in the GnuPG 2.1 release notes linked above, you can achieve this with the following series of commands:
cd ~/.gnupg
gpg --export-ownertrust >otrust.lst
mv pubring.gpg publickeys
gpg --import-options import-local-sigs --import publickeys
gpg --import-ownertrust otrust.lst
mv pubkeys pubring.gpg
This will create a file named pubring.kbx
which is the new storage file. The
above commands ensure that you properly import all public keys, public and
local signatures and keep your ownertrust intact. The file pubring.gpg
is
then kept in place so that you can still use it with gpg1.
Agents
GnuPG 2.1 now relies heavily on agents. This is actually nice since only one process is holding onto your key material and the others just ask for it to the agent. It also means that network access is totally segmented off to a process of its own. So you have at least two agents: gpg-agent and dirmngr. Those two agents are started automatically by gpg commands, which is convenient.
Dirmngr configuration
In order to contact the wild, wild, Internet, gpg will ask a new agent called dirmngr to access the network and report its findings. You'll be using it among other things to search for keys and to publish your newly updated key for those signatures you've acquired, or UIDs you added.
For this you need to configure dirmngr, see man (8) dirmngr for a list of
options. You can set the same options in ~/.gnupg/dirmngr.conf
. For example
you can set the keyserver to hkps://hkps.pool.sks-keyservers.net
.
If the dirmngr doesn't want to start, the only info you'll get when trying to search for keys with gpg is that connection to the dirmngr timed out. This is pretty annoying: you'll get no detail of why it just won't work.
In order to debug what's happening, you can run the dirmngr manually and it should tell you what's wrong. For example, here we have a syntax error on a config option:
$ dirmngr
dirmngr[29289.0]: /home/gabster/.gnupg/dirmngr.conf:13: invalid option
Once it starts and tells you OK Dirmngr 2.1.15 at your service
then you can
quit and try doing that gpg network operation you wanted to do.
gpg-agent and SSH keys
I've been using Monkeysphere for
some time now to provide access to servers. With gpg 1.4 in order to be able to
use the key material, it was necessary to export it to the ssh-agent process.
Now it's possible to ask gpg-agent to expose the keys you want to SSH and be
used as the ssh-agent process. This means there's no need to use
monkeysphere s
anymore!
In order to do this you first need to enable this support for the agent. In
~/.gnupg/gpg-agent.conf
, add the line:
enable-ssh-support
Then restart the gpg-agent. (you can kill the process and then start it again
with gpgconf --launch gpg-agent
. If you're using systemd, see below)
Once this is done, you should see a socket file in
/var/run/user/$uid/gnupg/S.gpg-agent.ssh
. We want to point ssh to this socket
so that it communicates directly with the gpg-agent. Add this to your preferred
shell initscript; in my case ~/.bashrc
:
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
The if block is there because if you run gpg-agent --daemon /bin/bash
for
example, the environment will be set by the agent itself and the variable that
we're checking against will be set. The SSH_AUTH_SOCK variable tells SSH to
talk to this socket for communicating with the ssh-agent.
Since SSH also doesn't communicate the current TTY name to gpg-agent, we need to set another variable in order to communicate the current TTY name to gpg-agent. This is useful so that gpg-agent knows where to send prompts for passwords. Again in your favorite shell initscript, add the following:
export GPG_TTY=$(tty)
Now we only have two more details to sort out.
Configure which keys/subkeys are exposed to SSH
The gpg-agent doesn't expose all of your key material to the SSH process. In fact you need to specify which sub-keys should be exposed. For this you need to find the subkey's keygrip. Run this to find it:
$ gpg -k --with-keygrip <your@uid.com>
pub rsa4096/0xC4ADA67875247FCF 2011-04-25 [SC] [expires: 2016-11-03]
Key fingerprint = 5F73 EFCB 02FC E345 C107 7477 C4AD A678 7524 7FCF
Keygrip = BF3DB7C51C596974DF58DC5860BE9F88A12CA19F
uid [ unknown] Perception <perception@rt.koumbit.net>
uid [ undef ] Network operations center <noc@koumbit.org>
uid [ full ] Koumbit frontdesk <info@koumbit.org>
uid [ full ] Koumbit support <support@koumbit.org>
uid [ unknown] Production <prod@rt.koumbit.net>
uid [ unknown] Services <services@rt.koumbit.net>
uid [ unknown] Koumbit sales <ventes@koumbit.org>
uid [ unknown] Facturation <facturation@rt.koumbit.net>
sub rsa4096/0x32873884B600AD97 2011-04-25 [E] [expires: 2016-11-03]
Keygrip = CD56911C4CE3173BD4D0AE5DCDBA29F738F14B39
sub rsa4096/0xDC837CFBE0D1124E 2015-08-20 [A]
Keygrip = C87589642DE00D1306350DD5C20F35C409427D45
In this example the key has one subkey with authentication capability (A).
We'll expose it to SSH by dropping the hexadecimal keygrip value on a line in
~/.gnupg/sshcontrol
:
echo "C87589642DE00D1306350DD5C20F35C409427D45 0" >> ~/.gnupg/sshcontrol
The trailing 0 in the echo above is the TTL of the key before SSH needs to revalidate with gpg-agent. In this case, we set it to 0 so that it doesn't expire: you'll get prompted for the key's password only upon first use.
Once this is done, you can verify that the key is exposed by listing keys with
ssh-add
:
$ ssh-add -l
4096 SHA256:7mb85m/biclOdJ4JB62rmrWe8nfV/Nwcmwop/Svdo3k (none) (RSA)
Success!
Once configuration is correctly established, you can also import ssh keys from
default files (e.g. id_ed25519
) by using ssh-add
without parameters.
Automatically starting the gpg-agent
When using gpg-agent for provide SSH with key material, you need to somehow automatically start the gpg-agent by yourself. GnuPG commands will auto-start the agent for you, but SSH doesn't know (and probably doesn't care) how to do this.
The simplest method is to call gpg-connect-agent /bye
in your shell
initscript.
But you can also use systemd to do this for you which means the agent will be started even if you don't have a terminal open. First you need to ensure you have a package installed, since without it communication between gpg-agent and your X session will be impossible:
sudo apt install dbus-user-session
With this in place, you can enable the service for your user:
gpgconf --kill gpg-agent
systemctl --user enable gpg-agent.service
systemctl --user start gpg-agent.service
This is not the terminal you are looking for
Now that you have a gpg-agent process running, you might notice that if you move around from your X session to an SSH connection towards your computer (some ppl do weird things... hey! my laptop is crashing all the time, but if I ssh in it doesn't... don't judge!) then the password prompts will not show up, or will show up in the wrong place. gpg commands normally pass the display and tty information to the agent so that things just work, but SSH doesn't pass this information. In such a case you'll probably end up getting this utterly useless message:
sign_and_send_pubkey: signing failed: agent refused operation
So you might need to call this command to make the gpg-agent point to the right place for the prompts:
gpg-connect-agent updatestartuptty /bye
After this you should get prompted for passwords and you should be able to connect to hosts with your keys.