From 1c4c9efa87e34a1a100c82dc999ddaa2451ca913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wxcaf=C3=A9=20=28Cl=C3=A9ment=20Hertling=29?= Date: Tue, 3 Jul 2018 01:05:34 +0200 Subject: [PATCH] adds post on using the yubikey for every single fucking thing --- content/yubikey_for_everything.md | 489 ++++++++++++++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 content/yubikey_for_everything.md diff --git a/content/yubikey_for_everything.md b/content/yubikey_for_everything.md new file mode 100644 index 0000000..3da3659 --- /dev/null +++ b/content/yubikey_for_everything.md @@ -0,0 +1,489 @@ +Title: Yubikey for EVERYTHING +Date: 2018-06-27T15:17+02:00 +Author: Wxcafé +Category: +Slug: content/yubikey_for_everything +Header_Cover: //pub.wxcafe.net/img/yubikey_cover.jpeg + +When I first started at the job I'm currently at at [Gandi](https://gandi.net), +I was given a Yubikey NEO, looked into it for a few minutes and quickly decided +to not give more thought about it. I put it away and didn't look back, partly +because the `yubikey-personalization-gui` is maybe the most unusable and +unintelligible interface I've ever seen, and partly because I had a 4096 bit key +and didn't think to make smaller subkeys to put in the smartcard (the NEO only +supports 2048 bit keys). + +A few weeks ago I decided to buy a Yubikey 4 on a drunken evening and got it in +the mail a few days later, having completely forgotten I had ordered it. +I decided to finally take a look at how this thing worked and what I could +actually do with it. + +So, first things first. The Yubikey is basically a GPG smartcard, with an added +X.509 smartcard, WITH added U2F support. It can also be used to do TOTP/HOTP +with the Yubico app on android smartphones or computers. It can probably also be +programmed to solve quadratic equations, but I haven't tried. + +To clarify: functionally, a smartcard is a device that has an integrated small +CPU and storage space for keys, and that you can only write keys to, not read +from. The integrated CPU can then be asked to sign/encrypt/decrypt arbitrary +data, but the keys can never be compromised from the key itself. + +Anyway, my use case is as such: beforehand, I stored my GPG and SSH keys on my +everyday computers, but I couldn't use either of them on my work computers (I +didn't want to leave personal stuff like that on work equipment). I wanted to be +able to connect to my servers and ideally decrypt files on any computer +I encounter (okay, decrypting files on anyone's computer is not a great idea, +but there are a few computers I trust enough to decrypt files on them but not to +give them my private keys). I also use [pass](https://www.passwordstore.org/) to +store my passwords, decrypting them with the yubikey everywhere is nice. Since +the key allows me to access my passwords, I feel like putting the second factor +of authentication on it just wouldn't be reasonable, so I'm still using my phone +as a 2fa TOTP source. Finally, I stored an X.509 cert for OpenVPN to try and see +how it would work with the yubikey. I'm not using it for now but it's there. + +--- + +### GPG key storage + +Anyways, here's how to use this thing: + +- First, always keep a backup of your private keys. You'll need them to sign + other people's keys at keysigning parties, and if you lose the yubikey you'll + also need them to recover... well, everything. Anyway, keeping a good offline + backup or two is important. + +- We're gonna start by adding our [GPG + subkeys](https://alexcabal.com/creating-the-perfect-gpg-keypair/) to the + yubikey. This is really easy, since the yubikey is detected as a smartcard by + gpg: + +``` +$ gpg --edit-card + +gpg --card-status +Reader ...........: Yubico Yubikey 4 OTP U2F CCID 00 00 +Application ID ...: D2760001240102010006076003030000 +Version ..........: 2.1 +Manufacturer .....: Yubico +Serial number ....: 07600303 +Name of cardholder: [not set] +Language prefs ...: [not set] +Sex ..............: unspecified +URL of public key : [not set] +Login data .......: [not set] +Signature PIN ....: not forced +Key attributes ...: rsa2048 rsa2048 rsa2048 +Max. PIN lengths .: 127 127 127 +PIN retry counter : 3 0 3 +Signature counter : 0 +Signature key ....: [none] +Encryption key....: [none] +Authentication key: [none] +General key info..: [none] + +gpg/card> admin +Admin commands are allowed + +gpg/card> passwd +gpg: OpenPGP card no. D2760001240102010006076003030000 detected + +1 - change PIN +2 - unblock PIN +3 - change Admin PIN +4 - set the Reset Code +Q - quit + +Your selection? 3 +PIN changed. + +1 - change PIN +2 - unblock PIN +3 - change Admin PIN +4 - set the Reset Code +Q - quit + +Your selection? 1 +Pin changed. + +1 - change PIN +2 - unblock PIN +3 - change Admin PIN +4 - set the Reset Code +Q - quit + +Your selection? q + +gpg/card> url +URL to retrieve public key: https://pub.wxcafe.net/wxcafe.asc + +gpg/card> name +Cardholder's surname: Hertling +Cardholder's given name: Clément +Error: Only plain ASCII is currently allowed. +Cardholder's given name: Clement + +gpg/card> login +Login data (account name): wxcafe + +gpg/card> sex +Sex ((M)ale, (F)emale or space): M + +gpg/card> lang +Language preferences: en + +gpg/card> list + +Reader ...........: Yubico Yubikey 4 OTP U2F CCID 00 00 +Application ID ...: D2760001240102010006076003030000 +Version ..........: 2.1 +Manufacturer .....: Yubico +Serial number ....: 07600303 +Name of cardholder: Clement Hertling +Language prefs ...: en +Sex ..............: male +URL of public key : https://pub.wxcafe.net/wxcafe.asc +Login data .......: wxcafe +Signature PIN ....: not forced +Key attributes ...: rsa2048 rsa2048 rsa2048 +Max. PIN lengths .: 127 127 127 +PIN retry counter : 3 0 3 +Signature counter : 0 +Signature key ....: [none] +Encryption key....: [none] +Authentication key: [none] +General key info..: [none] + +gpg/card> % + +``` + +The default PINs are `123456` for the user PIN and `12345678` for the admin PIN. + +Do take caution to export the private keys for safekeeping *BEFORE* moving them +to the yubikey (the gpg `keytocard` command *MOVES* the keys, after you've run it +*you don't have the private keys available anymore to backup*) + +Now that we've prepped the card, we're gonna move the keys over to it. We're +gonna move only the subkeys over, and since we're gonna need to use the yubikey +for everything we'll have an Encryption subkey, a Signing subkey and an +Authentication subkey. + +``` + +$ gpg --edit-key wxcafe@wxcafe.net +gpg (GnuPG) 2.2.7; Copyright (C) 2018 Free Software Foundation, Inc. +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Secret key is available. + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 1 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb* rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> keytocard +Please select where to store the key: + (1) Signature key + (3) Authentication key +Your selection? 1 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb* rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 1 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 2 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb* rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> keytocard + +Please select where to store the key: + (2) Encryption key +Your selection? 2 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb* rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 2 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 3 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb* rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> keytocard +Please select where to store the key: + (3) Authentication key +Your selection? 3 + +sec rsa4096/58DD226B3EA71DC7 + created: 2016-12-29 expires: 2019-06-18 usage: SC + trust: ultimate validity: ultimate +ssb rsa4096/11E99643DEE9E336 + created: 2018-06-29 expires: 2019-06-29 usage: S +ssb rsa4096/E00F13324D0D1703 + created: 2018-06-29 expires: 2019-06-29 usage: E +ssb* rsa4096/FD92FB8BD73D1D70 + created: 2018-06-29 expires: 2019-06-29 usage: A +[ultimate] (1). Wxcafé +[ultimate] (2) Wxcafé +[ultimate] (3) Wxcafé +[ultimate] (4) Wxcafé <🖕@fu.cking.network> +[ultimate] (5) [jpeg image of size 22243] + +gpg> key 3 + +gpg> save + +gpg> % + +``` + +Now that this is done, we only need to `gpg --card-status` should show us this: + +``` + +Reader ...........: 1050:0407:X:0 +Application ID ...: D2760001240102010006076003030000 +Version ..........: 2.1 +Manufacturer .....: Yubico +Serial number ....: 07600303 +Name of cardholder: Clement Hertling +Language prefs ...: en +Sex ..............: male +URL of public key : https://pub.wxcafe.net/wxcafe.asc +Login data .......: wxcafe +Signature PIN ....: not forced +Key attributes ...: rsa4096 rsa4096 rsa4096 +Max. PIN lengths .: 127 127 127 +PIN retry counter : 3 0 3 +Signature counter : 0 +Signature key ....: 752F 1ED2 D038 BCB6 F09C A942 11E9 9643 DEE9 E336 + created ....: 2018-06-29 22:27:20 +Encryption key....: 37B4 4050 8744 344C 0975 2656 E00F 1332 4D0D 1703 + created ....: 2018-06-29 22:28:22 +Authentication key: 775D 1613 1B3F FEE7 843F D3BC FD92 FB8B D73D 1D70 + created ....: 2018-06-29 22:29:29 +General key info..: sub rsa4096/11E99643DEE9E336 2018-06-29 Wxcafé +sec# rsa4096/58DD226B3EA71DC7 created: 2016-12-29 expires: 2019-06-18 +ssb> rsa4096/11E99643DEE9E336 created: 2018-06-29 expires: 2019-06-29 + card-no: 0006 07600303 +ssb> rsa4096/E00F13324D0D1703 created: 2018-06-29 expires: 2019-06-29 + card-no: 0006 07600303 +ssb> rsa4096/FD92FB8BD73D1D70 created: 2018-06-29 expires: 2019-06-29 + card-no: 0006 07600303 + +``` + +To actually use the keys we just copied over, we need to install a smarcard +daemon (`apt install scdaemon`) and authorize our user to access it. For that we +write a udev rule in (`/etc/udev/rules.d/70-yubikey.conf`) with this in it: +https://raw.githubusercontent.com/Yubico/libu2f-host/master/70-u2f.rules + +Now we should be able to use the yubikey to sign and encrypt whatever we want! +We can test this by doing `touch test; gpg -a --sign test`, which should prompt us +for the yubikey PIN and then create the `test.asc` file. + +We can still do `gpg --export-secret-keys `, and while it looks like it +works (because GPG's output is undecipherable and it's UX is the worst thing +I've ever seen), it actually outputs "stubs", which allows a system to "see" the +keys on the card. They're not needed anymore since for a while now, gpg +--card-status automatically detects the keys on the card. + +Now we want to use our gpg authentication key with SSH, to log in to our +servers. To do that, we need to tell gpg-agent to act as an ssh-agent, by adding +a single line to its configuration: `echo 'enable-ssh-support' >> +.gnupg/gpg-agent.conf`. Then we restart gpg-agent (`gpgconf --kill gpg-agent`) +and we should be set. Unplug the key, plug it back in, run `gpg --card-status`, +then `ssh-add -L` should show you a public key that ends with +`cardno:xxxxxxxxxxxx`. That means it's done, you can now add this public key to +`.ssh/authorized_keys` on your remote systems and you should be able to log in +with that key. + +--- + +### X.509 key and certificate storage + +Now for the X.509 storage, this is a bit easier. You will need to make a pkcs12 +out of your certificate and associated key (`openssl pkcs12 -export -out out.p12 +-inkey key.pem -in cert.crt --certfile ca.crt -nodes`), and then we can import +it into the yubikey (this will not destroy the .p12 file, nor the key or cert, +because this has a sensible UX, as opposed to gnupg): `yubico-piv-tool -s 9c -i +out.p12 -K PKCS12 -a import-key -a import-cert -k` + +In my case, I was using this with OpenVPN, so I needed to install opensc-pkcs11 +(which is a library that allows applications to see certificates from +a smartcard), then to look up under which ID OpenVPN saw my certificate with +`openvpn --show-pkcs11-ids /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so`. After +that, I updated my OpenVPN configuration by replacing the cert and key lines +with + +``` +pkcs11-id 'piv_II/PKCS\x2315\x20emulated/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +pkcs11-providers /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so +``` + +And then it worked like a charm! What actually stopped me is that I use +networkmanager on my machines since `wicd` is dead, and it doesn't support that +kind of config. Of course, wicd would since it can launch arbitrary scripts... +but I'm stuck with NM and so I can't use this easily, sadly. + +--- + +### Pass + +So, technically [pass](https://www.passwordstore.org/) is not related to the +yubikey at all, and doesn't directly interact with it. If you haven't heard +about it, it's a simple password manager for unix written in bash by +[zx2c4](https://www.zx2c4.com/). *But* it uses GPG as an encryption mechanism, +and since I was moving towards using GPG to authenticate SSH connections, +I thought I might as well start using pass with the yubikey. So, here goes. + +Pass is a very simple password manager, so simple that all it does is keep your +passwords for you and output them when you ask nicely. It's installed on +basically all systems with the package manager (in my case, `apt install pass`), +and then it's a matter of `pass init ` to initialize the folder with the +specified gpg key id, `pass git init` and `pass git remote add origin ` +to use git to store the passwords (that's optional, but it's so much better it'd +be dumb not to do it...). Then you can add a password with `pass insert `, +or generate one with `pass generate `. Don't forget to `pass git +push` (it'll commit automatically if it's in git). + +To see all the passwords you have in pass, use `pass ls`, and to read a specific +password use `pass `. The problem with that is that the password is +written to stdout, and we don't really want to a) have people able to snoop the +password, nor b) open a terminal and copy-paste every time we want to get +a password. That's where passmenu comes in! It's a simple script included with +pass (at least it is in debian) in +`/usr/share/doc/pass/examples/dmenu/passmenu`, and it relies on dmenu to show +you all of your passwords. From there, you can type a few letters and select +which password you want, and once you confirm your selection it will copy it +into your clipboard, ready for you to paste into any password field. There are +extensions to have it support TOTP and other stuff too, but as previously I'm +not too comfortable with putting all my eggs in the same basket. + +So yeah, move all your passwords to pass and make them as complex as possible! +When you get to a new machine you can simply `git clone ~/.password-store` +and `apt install pass` and you're all set! Don't lose your GPG key though, or +you're **_SCREWED_**. + +Don't lose it. Ever. Print it out and put it in the bank. Whatever. But don't +lose it. + +Anyway, that was it! I'm seriously happy with how this solution works for me, +and how secure it is without sacrificing much towards usability, even improving +it in most cases. + +(P.S.: I don't get anything by saying this, but my employer (gandi) has +a partnership thing in place with yubico, such that if you login on [this +page](https://www.yubico.com/solutions/gandi/) with a gandi account, you get 20% +off your yubikey. You don't even need to buy anything with gandi afaik, only to +have an account)