I haven't been safe/paranoid enough with my digital security. A component of which is how I use SSH keys. The short version... fucking badly. Problem, realization of said problem, possible solution.
I’ve landed on a simple equation for what’ll remedy my current fear levels:
3 things, NBD, but oh, the details. I’ll start from the bottom.
I picked up a Yubikey a couple of weeks ago. When I bought it, I didn’t really know what it was, but it looked security-ish. Turns out it is both a GPG smartcard and a hardware factor for multi-factor authentication. Cool.
Now, Yubikey as a hardware factor is peazy. I’m using it with LastPass, and it’s simply a matter of sticking it in a USB slot and touching the metal bit.
Using Yubikey as a smartcard is a bit trickier. This isn’t implicit to Yubikey, but smartcards in general. Additionally, using GPG keys to SSH places is kinda face-numbing. Since I’m new to GPG, I of course inadvertently opted to take the most-face-numbing-est path.
Some of the sights along the way:
- Install GnuPG
- Configure GnuPG
- Configure gpg-agent
- Generate a GPG master key (revocation certs, text backup, etc.)
- Generate subkeys for authentication, signing and encryption
- Publish keys to a keyserver
- Move secret keys to Yubikey
If you, dear reader, would also like to use a Yubikey for SSH, then read on.
Installing Stuff
Regardless of where you’ll be generating your keys
(Tails maybe?), you’ll need gpg2
and a few other
packages on your daily computer.
# mac
$ brew install gnupg2 pinentry-mac
# ubuntu
$ sudo apt-get install gnupg2 scdaemon pcscd pcsc-tools pinentry-gnome3
Configuring Stuff
Next, you’ll need to configure gpg2
and gpg-agent
. Read through
this
and this, then
download them to ~/.gnupg
. Both will need a bit of modification afterwards.
# look at this before you download it, duh
# yea, these are long, and look like shit when they wrap.
# ~/.gnupg/gpg.conf
$ curl https://raw.githubusercontent.com/ioerror/duraconf/master/configs/gnupg/gpg.conf > ~/.gnupg/gpg.conf
# ~/.gnupg/gpg-agent.conf
$ curl https://gist.githubusercontent.com/killtheliterate/e05ab738948cd00fcf35/raw/596b4b5a0dae98da496529fc35ebb365436f056a/gpg-agent.conf > ~/.gnupg/gpg-agent.conf
You’ll need to set up gpg-agent.conf
to use a relevant pinentry
program.
For mac, I’m using pinentry-mac
. For Ubuntu, I’m using pinentry-gnome3
.
Don’t use pinentry
, which caused me so much grief that I’ll call it out
again later in this post. You’ll also need to download the certificate
described in gpg.conf
and modify gpg.conf
to point at wherever you decide
to put the certificate.
Generating Keys
Now you’ll need to generate keys:
- A master key
- A subkey for encrypting things
- A subkey for authentication (this’ll be for SSH)
- A subkey for signing things
A lot of folks recommend generating these keys in an environment like Tails. If you use a Tails that has never been online, it’s less likely that your master key will become compromised. Bonus-mode, Tails has a feature to persist keys. This means you can have a secure copy of Tails on a USB flash drive, with an encrypted partition that contains your keys.
If you opt to go this route, you’ll need to move your subkeys from Tails to an OS that works with smartcards. Basically, export your subkeys, your public keys, and then put them on another USB drive. Plug that in to your daily computer and import your keys.
To export keys:
$ gpg2 --export-secret-subkeys -a ${YOUR_KEY_ID} > private.asc
$ gpg2 --export -a ${YOUR_KEY_ID} > public.asc
To import keys:
$ gpg2 --import private.asc
$ gpg2 --import public.asc
Publish Public Keys
Now that you’ve got some public keys, you should publish them to a keyserver.
People will then be able to look you up and encrypte messages for you. If
you’ve configured gpg.conf
correctly, you can publish your keys to
https://sks-keyservers.net. There are some good
alternatives of course, such as http://keys.gnupg.net
and https://pgp.mit.edu. From what I understand,
publishing to one should propagate to the others.
My public key is available here.
Send your public keys:
$ gpg2 --send-keys YOUR KEY ID
Set Up Yubikey
Alright… Finally, Yubikey. The gist is to configure your Yubikey, and then move your secret subkeys to it.
You’ll need to enable the smartcard interface of your Yubikey using
ykpersonalize
. This is pretty painless, and Yubico wrote a nice post about
it here.
Now, configure the Yubikey. This means setting an admin password, a key
password, and other optional pieces of information like your name. Of
particular interest is URL of public key
, as you can use that to fetch your
keys should you ever need to (say you need to use someone else computer).
Both passwords you set up on the card should be strong. They key password is what you’ll be prompted for when using your Yubikey to encrypt/decrypt/authenticate.
$ gpg2 --card-edit
gpg/card> admin
gpg/card> passwd
# etc.
Hell Is scdaemon
Configuring my Yubikey is where this process became especially hellacious.
I encountered many errors that basically amounted to scdaemon
not
working/running. scdaemon
, as I understand it, is how gpg-agent
connects
to smartcards. If it’s not running, or is for-any-reason fucked up, smartcards
won’t work. On Ubuntu, this was resolved by explicitly installing scdaemon
and a few other packages. If you followed the install steps spelled out near
the top, you should be good. For both Mac and Ubuntu I had to edit gpg.conf
to use a pinentry program that was not pinentry
, namely pinentry-mac
or
pinentry-gnome3
. This bums me out, but it bums me out less than gpg-agent
not working.
First and foremost, make sure gpg-agent
is running.
# this will say everything is chill-mode if it's running, and start it
# otherwise
$ gpg-agent
Move Your Secret Subkeys
Alright, ready to move your subkeys to the Yubikey? Yup.
$ gpg2 --edit-key YOUR KEY ID
gpg> toggle # so we're working with secret keys
gpg> key 1 # select the key you want to move
gpg> keytocard
# Then select the slot to move it to. There should only be one option for
# each subkey if you've made single-purpose keys.
gpg> save
If everything is legit, running gpg2 --card-status
will print out a display
that contains some info about your subkeys. Additionally, gpg2 -K
will
generate a little readout that displays your secret subkeys with a >
preceding them.
SSH
As mentioned right up top, I mostly wanted to use a Yubikey for SSH. That
requires a bit of configuration in .zshrc
, .bash_profile
, or whatever
shell configuration file is relevant to you.
if [ -f "${HOME}/.gpg-agent-info" ]; then
. "${HOME}/.gpg-agent-info"
export GPG_AGENT_INFO
export SSH_AUTH_SOCK
fi
export GPG_TTY=$(tty)
Now, you’ll need an SSH compatible public key to add to, say, github, or
authorized_keys
. Get it by running:
# copy/paste the relevant key
$ ssh-add -L
Perfect. You now have a GPG key you can use for SSH, and it’s on a Yubikey. Paranoia abatement successful.
Further reading: