Overview

Why?

Allows you to use a smartcard for SSH authentication

Extends you PGP Web-of-Trust to your SSH identity

Gives you more options which are potentially easier in distributing your public key

Using gpg-agent or ssh-agent is more secure than using an id_rsa key file

Why not?

If you are not already using PGP keys, this is definitely not for you.

Definitely works (well) on Linux. Should work fine on OSX, although it is untested and will certainly require some deviations from this page. Windows... good luck and may the odds be ever in your favor.

Kinda difficult and prone to break as it isn't done often. Notable difficulties:

  • direct access to the private key. Reasons for wanting to do this include:
    • creating an id_rsa file for use by non-standard clients
    • creating an SSL self-signed cert or CSR
      • Usable for certificate based web authentication
      • the Aruba controllers only accept public keys (for SSH or Web auth) in an SSL cert
  • Using gpg-agent may conflict with the system's keyring manager, such as gnome-keyring

How?

Create a PGP/GPG subkey and let gpg-agent handle the authentication (similar to using ssh-agent) and/or export the key for edge cases.

Required software

The version I used is listed. Other versions may or may not work. YMMV.

  • gpg 2.1.7
  • openssh 7.1p1
  • openssl 1.0.2d

If you have need of the raw private key, you will also need:

  • gpg <= 2.0
    • This requirement may change in the future [bug][discussion]
    • I used 1.4.19, installed as gpg1
    • To export the unencrytped key
  • monkeysphere 0.37
    • To do convert the key format

The GPG homedir is assumed to be ~/.gnupg on this page. Adjust accordingly if needed.

I've used my key-ids for examples. Obviously, use your own.

Create the subkey

Create an authentication subkey.

Setup your client

Using gpg-agent

Requires gnupg >= 2.1

Add the keygrip to ~/.gnupg/sshcontrol

  1. Find the keygrip 
    • The keygrip is different from the key ID or Fingerprint
    • It is a string of 40 hex characters
    • Display it with: gpg --with-keygrip -k your_master_key_id
  2. Add the keygrip to ~/.gnupg/sshcontrol
    • A single line with just the keygrip is sufficient
    • see the man page gpg-agent(1), section FILES/sshcontrol for details

      # Key fingerprint = ADE6 00A7 FFEA 1234 4839  2726 0806 7CFD 3A60 8725
      C7FCF7CF5C15838CE68FABC02023AFA6AC0097C6 0

Enable ssh support in gpg-agent

  1. Add the option enable-ssh-support to ~/.gnupg/gpg-agent.conf

    # Enable SSH support
    enable-ssh-support

Configure ssh to use gpg-agent for authentication

This section deals with setting environment environment variables and making sure gpg-agent is using them correctly. This will be highly dependent on your environment. I run a pretty barebones system without a login manager, so your setup will likely look different. Use discretion.

The SSH_AUTH_SOCK environment variable tells ssh what to use for authentication. It should point to ~/.gnupg/S.gpg-agent.ssh. This only needs to be set once on login and does not change.

# use gpg-agent for ssh authentication
typeset -gx SSH_AUTH_SOCK="${HOME}/.gnu/S.gpg-agent.ssh"

The environment variable GPG_TTY tells gpg-agent what the current TTY is. This determines what kind of prompt you will get (graphical vs terminal). This needs to be run anytime your TTY changes types (such as going from TTY1 to an X session).

# update tty for gpg-agent
typeset -x +g GPG_TTY="${TTY}"
gpg-connect-agent updatestartuptty /bye &> /dev/null

Verify

To verify the key is loaded in gpg-agent and it is ready to use the key for authentications, use ssh-add:

$ ssh-add -l
4096 SHA256:xEZNBAWyYttFyWwNfBPSg65gMmQ25morER+QvgzQ1Bk (none) (RSA)

Using the exported private key

warnings and considerations

  • hic sunt dracones
  • Requires gpg <= 2.0 and monkeysphere
  • Use the appropriate precautions when using / working with the unencrypted private key.
  • Using key authentication in this manner may negate some of the benefits of having an ssh keypair tied to a PGP master key. Consider the implications and goals. You may be better off using a different auth key in the traditional manner.

Export the private key

  1. GPG 2.1 stores the private keys in ~/.gnupg/private-keys-v1.d, not ~/.gnupg/secring.gpg. Export the gpg2 secret keyring to secring.gpg.

    gpg --export-secret-keys 0xEB77F7CC0DBAF5F5 > ~/.gnupg/secring.gpg


  2. Use gpg1 to export the unencrypted private key

    gpg1 --export-options export-reset-subkey-passwd --export-secret-subkeys 0x08067CFD3A608725! | openpgp2ssh 08067CFD3A608725 > privkey.pem
    • gpg
      • must be gpg <= 2.0

      • Use an exclamation point (!) after the subkey-id to denote that only the specified key should be exported, and not the master key with all its subkeys.
      • key-id does use the 0x prefix
    • opengpg2ssh
      • part of the monkeysphere suite
      • key-id does not use the 0x prefix
    • privkey.pem
      • Is an unencrypted PEM RSA private key
      • This format can be used as an id_rsa file for openSSH, or as a key file for openSSL

Distributing public keys

The authentication subkey can be distributed through a keyserver just like any other key. The advantage is that if someone already has your master public key, and the appropriate trust relationship has been established, then getting the new subkey should be as easy as gpg --refresh-keys.

That there is a bug in an older version of gpg which freaks out on getting new subkeys for an already existing key in the keyring. If you get an error when you try to refresh your keys, upgrade gpg.

To generate an id_rsa.pub file:

In gpg <= 2.1.10:

gpgkey2ssh 08067CFD3A608725 > pid-id_rsa.pub

In gpg >= 2.1.11:

gpg --export-ssh-key 0x08067CFD3A608725 > pid-id_rsa.pub

This file can be generated by the local or remote user as long as the subkey is in the local keyring. Once you have the id_rsa.pub file, it can be used like a normal ssh public key (e. g. appended to ~/.ssh/authorized_keys).

References