diff --git a/README.md b/README.md index d6e2224..7700e53 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ This is a guide to using [YubiKey](https://www.yubico.com/products/yubikey-hardware/) as a [SmartCard](https://security.stackexchange.com/questions/38924/how-does-storing-gpg-ssh-private-keys-on-smart-cards-compare-to-plain-usb-drives) for storing GPG encryption, signing and authentication keys, which can also be used for SSH. Many of the principles in this document are applicable to other smart card devices. -Keys stored on YubiKey are [non-exportable](https://support.yubico.com/support/solutions/articles/15000010242-can-i-duplicate-or-back-up-a-yubikey-) (as opposed to file-based keys that are stored on disk) and are convenient for everyday use. Instead of having to remember and enter passphrases to unlock SSH/GPG keys, YubiKey needs only a physical touch after being unlocked with a PIN code. All signing and encryption operations happen on the card, rather than in OS memory. +Keys stored on YubiKey are [non-exportable](https://support.yubico.com/support/solutions/articles/15000010242-can-i-duplicate-or-back-up-a-yubikey-) (as opposed to file-based keys that are stored on disk) and are convenient for everyday use. Instead of having to remember and enter passphrases to unlock SSH/GPG keys, YubiKey needs only a physical touch after being unlocked with a PIN. All signing and encryption operations happen on the card, rather than in OS memory. **New!** [drduh/Purse](https://github.com/drduh/Purse) is a password manager which uses GPG and YubiKey. @@ -8,15 +8,23 @@ If you have a comment or suggestion, please open an [Issue](https://github.com/d - [Purchase YubiKey](#purchase-yubikey) - [Verify YubiKey](#verify-yubikey) -- [Download OS image](#download-os-image) +- [Download OS Image](#download-os-image) - [Required software](#required-software) - * [Entropy](#entropy) + * [Debian/Ubuntu](#debian-ubuntu) + * [Arch](#arch) + * [RHEL7](#rhel7) + * [OpenBSD](#openbsd) + * [macOS](#macos) + * [Windows](#windows) +- [Entropy](#entropy) - [Creating keys](#creating-keys) - [Master key](#master-key) +- [Sign with an existing key (optional)](#sign-with-an-existing-key--optional-) - [Sub-keys](#sub-keys) * [Signing](#signing) * [Encryption](#encryption) * [Authentication](#authentication) + * [Add extra emails](#add-extra-emails) - [Verify](#verify) - [Export](#export) - [Backup](#backup) @@ -38,10 +46,11 @@ If you have a comment or suggestion, please open an [Issue](https://github.com/d * [(Optional) Save public key for identity file configuration](#-optional--save-public-key-for-identity-file-configuration) * [Connect with public key authentication](#connect-with-public-key-authentication) * [Import SSH keys](#import-ssh-keys) - * [Remote Machines (Agent Forwarding)](#remote-machines-agent-forwarding) + * [Remote Machines (Agent Forwarding)](#remote-machines--agent-forwarding-) + + [Steps for older distributions](#steps-for-older-distributions) * [GitHub](#github) - * [OpenBSD](#openbsd) - * [Windows](#windows) + * [OpenBSD](#openbsd-1) + * [Windows](#windows-1) + [WSL](#wsl) - [Prerequisites](#prerequisites) - [WSL configuration](#wsl-configuration) @@ -49,6 +58,7 @@ If you have a comment or suggestion, please open an [Issue](https://github.com/d - [Multiple Keys](#multiple-keys) - [Require touch](#require-touch) - [Email](#email) + * [Mailvelope on macOS](#mailvelope-on-macos) - [Reset](#reset) - [Notes](#notes) - [Troubleshooting](#troubleshooting) @@ -70,52 +80,54 @@ You will need several small storage devices for booting a temporary operating sy It is recommended to generate cryptographic keys and configure YubiKey from a secure operating system and using an ephemeral environment ("live image"), such as [Debian](https://www.debian.org/CD/live/), [Tails](https://tails.boum.org/index.en.html), or [OpenBSD](https://www.openbsd.org/) booted from a USB drive. -Depending on your threat model and/or level of inherent trust in your own system. It is also a valid option to run the "live image" within a VM using something like Virtualbox or VMWare +Depending on your threat model and/or level of inherent trust in your own system, it may also be a valid option to run the live image within a virtual machine using VirtualBox or VMWare software. To use Debian, download the latest image: ```console -$ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-10.1.0-amd64-xfce.iso +$ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-10.2.0-amd64-xfce.iso $ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS $ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS.sign ``` -Verify file integrity with GPG: +Verify the signature of the hashes file with GPG: ```console $ gpg --verify SHA512SUMS.sign SHA512SUMS -gpg: Signature made Sat Jul 6 18:51:32 2019 PDT +gpg: Signature made Sat Nov 16 18:49:18 2019 PST gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B gpg: Can't check signature: No public key -$ gpg --keyserver keyring.debian.org --recv DF9B9C49EAA9298432589D76DA87E80D6294BE9B -gpg: key 0xDA87E80D6294BE9B: 61 signatures not checked due to missing keys +$ gpg --keyserver hkps://keyring.debian.org --recv DF9B9C49EAA9298432589D76DA87E80D6294BE9B +gpg: key 0xDA87E80D6294BE9B: 5 signatures not checked due to missing keys gpg: key 0xDA87E80D6294BE9B: public key "Debian CD signing key " imported -gpg: marginals needed: 3 completes needed: 1 trust model: pgp -gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: Total number processed: 1 gpg: imported: 1 $ gpg --verify SHA512SUMS.sign SHA512SUMS -gpg: Signature made Sat Jul 6 18:51:32 2019 PDT +gpg: Signature made Sat Nov 16 18:49:18 2019 PST gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B gpg: Good signature from "Debian CD signing key " [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B - -$ grep $(sha512sum debian-live-10.1.0-amd64-xfce.iso) SHA512SUMS -SHA512SUMS:b40aa5a680fd560ce5bd52a874004c18a7d005865fc83e82c36af1cd01cf1cfbd177a4a212288c648f59088444c16aa2c1c52da206c27df2fa8ffadb4fc9a7fd debian-live-10.1.0-amd64-xfce.iso ``` -If the key cannot be received, try changing the DNS resolver and/or use a specific keyserver: +If the public key cannot be received, try changing the DNS resolver and/or use a different keyserver: ```console $ gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv DF9B9C49EAA9298432589D76DA87E80D6294BE9B ``` +Ensure the SHA512 hash of the live image matches the one in the signed file. + +```console +$ grep $(sha512sum debian-live-10.2.0-amd64-xfce.iso) SHA512SUMS +SHA512SUMS:b253e347bf04c4e16b4c948b88bfba58f6084717f8ca290d5ea320837f63cf69b46734b7127dabd114ad88022075020982434fcf31463b82c6225671e7116a4d debian-live-10.2.0-amd64-xfce.iso +``` + See [Verifying authenticity of Debian CDs](https://www.debian.org/CD/verify) for more information. Mount a storage device and copy the image to it: @@ -135,7 +147,7 @@ sd 2:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DP sdb: sdb1 sdb2 sd 2:0:0:0: [sdb] Attached SCSI removable disk -$ sudo dd if=debian-live-10.1.0-amd64-xfce.iso of=/dev/sdb bs=4M; sync +$ sudo dd if=debian-live-10.2.0-amd64-xfce.iso of=/dev/sdb bs=4M; sync 465+1 records in 465+1 records out 1951432704 bytes (2.0 GB, 1.8 GiB) copied, 42.8543 s, 45.5 MB/s @@ -148,72 +160,69 @@ $ dmesg | tail -n2 sd2 at scsibus4 targ 1 lun 0: SCSI4 0/direct removable serial.0000000000000 sd2: 15193MB, 512 bytes/sector, 31116288 sectors -$ doas dd if=debian-live-10.1.0-amd64-xfce.iso of=/dev/rsd2c bs=4m +$ doas dd if=debian-live-10.2.0-amd64-xfce.iso of=/dev/rsd2c bs=4m 465+1 records in 465+1 records out 1951432704 bytes transferred in 139.125 secs (14026448 bytes/sec) ``` -Shut down the computer and disconnect internal hard drives and all unnecessary peripheral devices. If being run within a VM this part can be skipped as no such devices should be attached to the VM since the image will still be run as a "live image" +Shut down the computer and disconnect internal hard drives and all unnecessary peripheral devices. If being run within a VM, this part can be skipped as no such devices should be attached to the VM since the image will still be run as a "live image". If on physical hardware consider using secure hardware like a ThinkPad X230 running [Coreboot](https://www.coreboot.org/) and [cleaned of Intel ME](https://github.com/corna/me_cleaner). # Required software -Boot the OS image and configure networking. +Boot the live image and configure networking. **Note** If the screen locks, unlock with `user`/`live`. Open the terminal and install required software packages. -**Debian/Ubuntu** +## Debian/Ubuntu **Note** Live Ubuntu images [may require modification](https://github.com/drduh/YubiKey-Guide/issues/116) to `/etc/apt/sources.list` ```console -$ sudo apt update && sudo apt install -y \ - gnupg2 gnupg-agent dirmngr \ - cryptsetup scdaemon pcscd \ - secure-delete hopenpgp-tools \ - yubikey-personalization +$ sudo apt update + +$ sudo apt install -y gnupg2 gnupg-agent dirmngr cryptsetup scdaemon pcscd secure-delete hopenpgp-tools yubikey-personalization ``` -**Arch** +## Arch ```console -$ sudo pacman -Syu \ - gnupg2 pcsclite ccid hopenpgp-tools \ - yubikey-personalization +$ sudo pacman -Syu gnupg2 pcsclite ccid hopenpgp-tools yubikey-personalization ``` -**RHEL7** +## RHEL7 ```console -$ sudo yum install -y \ - gnupg2 pinentry-curses pcsc-lite pcsc-lite-libs gnupg2-smime +$ sudo yum install -y gnupg2 pinentry-curses pcsc-lite pcsc-lite-libs gnupg2-smime ``` -**OpenBSD** +## OpenBSD ```console $ doas pkg_add gnupg pcsc-tools ``` -**macOS** +## macOS -Download and install [Homebrew](https://brew.sh/) and the following Brew packages: +Download and install [Homebrew](https://brew.sh/) and the following packages: ```console $ brew install gnupg yubikey-personalization hopenpgp-tools ykman pinentry-mac ``` -**Windows** +**Note** An additional Python package dependency may need to be installed to use `[ykman](https://support.yubico.com/support/solutions/articles/15000012643-yubikey-manager-cli-ykman-user-guide)` - `pip install yubikey-manager` + +## Windows Download and install [Gpg4Win](https://www.gpg4win.org/) and [PuTTY](https://putty.org). You may also need more recent versions of [yubikey-personalization](https://developers.yubico.com/yubikey-personalization/Releases/) and [yubico-c](https://developers.yubico.com/yubico-c/Releases/). -## Entropy +# Entropy Generating cryptographic keys requires high-quality [randomness](https://www.random.org/randomness/), measured as entropy. @@ -224,13 +233,12 @@ $ cat /proc/sys/kernel/random/entropy_avail 849 ``` -Most operating systems use software-based pseudorandom number generators. A hardware random number generator like [OneRNG](http://onerng.info/onerng/) will [increase the speed](https://lwn.net/Articles/648550/) of entropy generation and possibly the quality. +Most operating systems use software-based pseudorandom number generators. A hardware random number generator like [OneRNG](https://onerng.info/onerng/) will [increase the speed](https://lwn.net/Articles/648550/) of entropy generation and possibly the quality. Install and configure OneRNG software: ```console -$ sudo apt install -y \ - at rng-tools python-gnupg openssl +$ sudo apt install -y at rng-tools python-gnupg openssl $ wget https://github.com/OneRNG/onerng.github.io/raw/master/sw/onerng_3.6-1_all.deb @@ -422,19 +430,15 @@ $ export KEYID=0xFF3E7D88647EBCDB # Sign with an existing key (optional) -If you already have a pgp key you may want to sign your new key -with the old one to help prove that your new key is infact controlled -by you. +If you already have a PGP key, you may want to sign the new key with the old one to prove that the new key is controlled by you. -Export your existing key to move it to the working keyring. From a -different terminal do: +Export your existing key to move it to the working keyring: ```console $ gpg --export-secret-keys --armor --output /tmp/new.sec ``` -to export your old key and then - +Then sign the new key: ```console $ gpg --default-key $OLDKEY --sign-key $KEYID @@ -455,7 +459,7 @@ sec rsa4096/0xEA5DE91459B80592 [ultimate] (1). Dr Duh ``` -Use 4096-bit key sizes. +Use 4096-bit RSA keys. Use a 1 year expiration for sub-keys - they can be renewed using the offline master key. See [rotating keys](#rotating-keys). @@ -761,7 +765,7 @@ $ gpg -o \path\to\dir\sub.gpg --armor --export-secret-subkeys $KEYID # Backup -Once GPG keys are moved to YubiKey, they cannot be moved again! Create an **encrypted** backup of the keyring and consider using a [paper copy](https://www.jabberwocky.com/software/paperkey/) of the keys as an additional backup. +Once keys are moved to YubiKey, they cannot be moved again! Create an **encrypted** backup of the keyring and consider using a [paper copy](https://www.jabberwocky.com/software/paperkey/) of the keys as an additional backup measure. **Tip**: The ext2 filesystem (without encryption) can be mounted on both Linux and OpenBSD. @@ -1329,8 +1333,7 @@ Install the required packages and mount the non-encrypted volume created earlier **Linux** ```console -$ sudo apt update && sudo apt install -y \ - gnupg2 gnupg-agent gnupg-curl scdaemon pcscd +$ sudo apt update && sudo apt install -y gnupg2 gnupg-agent gnupg-curl scdaemon pcscd $ sudo mount /dev/sdb2 /mnt ``` @@ -1580,7 +1583,7 @@ pinentry-program /usr/bin/pinentry-curses **Important** The `cache-ttl` options do **NOT** apply when using a YubiKey as a smartcard as the PIN is [cached by the smartcard itself](https://dev.gnupg.org/T3362). Therefore, in order to clear the PIN from cache (smartcard equivalent to `default-cache-ttl` and `max-cache-ttl`), you need to unplug the YubiKey. -**Tip** Set `pinentry-program /usr/bin/pinentry-gnome3` for a GUI-based prompt. If the _pinentry_ graphical dialog doesn't show and you get this error: `sign_and_send_pubkey: signing failed: agent refused operation`, you probably need to install the `dbus-user-session` package and might have to restart the computer for the `dbus` user session to be fully inherited; this is because behind the scenes, `pinentry` complains about `No $DBUS_SESSION_BUS_ADDRESS found`, falls back to `curses` but doesn't find the expected `tty`. +**Tip** Set `pinentry-program /usr/bin/pinentry-gnome3` for a GUI-based prompt. If the _pinentry_ graphical dialog doesn't show and you get this error: `sign_and_send_pubkey: signing failed: agent refused operation`, you may need to install the `dbus-user-session` package and restart the computer for the `dbus` user session to be fully inherited; this is because behind the scenes, `pinentry` complains about `No $DBUS_SESSION_BUS_ADDRESS found`, falls back to `curses` but doesn't find the expected `tty`. On macOS, use `brew install pinentry-mac` and adjust the program path to suit. @@ -1604,12 +1607,12 @@ export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) gpgconf --launch gpg-agent ``` -Note that `SSH_AUTH_SOCK` normally only needs to be set on the *local* laptop (workstation), where the YubiKey is plugged in. On the *remote* server that we SSH into, `ssh` will automatically set `SSH_AUTH_SOCK` to something like `/tmp/ssh-mXzCzYT2Np/agent.7541` when we connect. We therefore do **NOT** manually set `SSH_AUTH_SOCK` on the server. (Doing so would break [SSH Agent Forwarding](#remote-machines-agent-forwarding).) +Note that `SSH_AUTH_SOCK` normally only needs to be set on the *local* laptop (workstation), where the YubiKey is plugged in. On the *remote* server that we SSH into, `ssh` will automatically set `SSH_AUTH_SOCK` to something like `/tmp/ssh-mXzCzYT2Np/agent.7541` when we connect. We therefore do **NOT** manually set `SSH_AUTH_SOCK` on the server - doing so would break [SSH Agent Forwarding](#remote-machines-agent-forwarding). ## Copy public key -**Note** It is *not* necessary to import the corresponding GPG public key in order to use SSH. +**Note** It is **not** necessary to import the corresponding GPG public key in order to use SSH. Copy and paste the output from `ssh-add` to the server's `authorized_keys` file: @@ -1938,7 +1941,7 @@ By default, YubiKey will perform encryption, signing and authentication operatio To require a touch for each key operation, install [YubiKey Manager](https://developers.yubico.com/yubikey-manager/) and recall the Admin PIN: -**Note** Older versions of the YubiKey Manager used `touch` instead of `set-touch` in the below commands. +**Note** Older versions of YubiKey Manager use `touch` instead of `set-touch` in the following commands. Authentication: @@ -1964,11 +1967,12 @@ YubiKey will blink when it is waiting for a touch. On Linux you can also use [yu GPG keys on YubiKey can be used with ease to encrypt and/or sign emails and attachments using [Thunderbird](https://www.thunderbird.net/) and [Enigmail](https://www.enigmail.net). Thunderbird supports OAuth 2 authentication and can be used with Gmail. See [this guide](https://ssd.eff.org/en/module/how-use-pgp-linux) from EFF for detailed instructions. -## mailvelope on MacOS +## Mailvelope on macOS [Mailvelope](https://www.mailvelope.com/en) allows GPG keys on YubiKey to be used with Gmail and others. -On MacOS install gpgme using homebrew: +On macOS, install gpgme using Homebrew: + ```console $ brew install gpgme ``` @@ -2056,7 +2060,7 @@ scd apdu 00 44 00 00 - If SSH authentication still fails - add up to 3 `-v` flags to the `ssh` client to increase verbosity. -- If it still fails, it may be useful to stop the background `sshd` daemon process service on the server (e.g. using `sudo systemctl stop sshd`) and instead start it in the foreground with extensive debugging output, using `sshd -eddd`. Note that (quote `man sshd`) _The server also will not fork and will only process one connection._, and therefore has to be re-started after every `ssh` test. +- If it still fails, it may be useful to stop the background `sshd` daemon process service on the server (e.g. using `sudo systemctl stop sshd`) and instead start it in the foreground with extensive debugging output, using `/usr/sbin/sshd -eddd`. Note that the server will not fork and will only process one connection, therefore has to be re-started after every `ssh` test. # Links