From b29020a3149806e2bc9e67a4c9ade726f716b3a3 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Fri, 7 Sep 2018 14:57:27 +0200 Subject: Add "Securing your Workstation" --- _posts/2018-09-04-securing-your-workstation.adoc | 458 +++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 _posts/2018-09-04-securing-your-workstation.adoc (limited to '_posts') diff --git a/_posts/2018-09-04-securing-your-workstation.adoc b/_posts/2018-09-04-securing-your-workstation.adoc new file mode 100644 index 0000000..84b0d22 --- /dev/null +++ b/_posts/2018-09-04-securing-your-workstation.adoc @@ -0,0 +1,458 @@ +--- +date: 2018-09-04 +tags: security yubikey pgp gpg +description: > + An introduction to decent security using the Yubikey as your physical + security card. +--- += Securing Your Workstation +:toc: preamble + +I've recently started a job where I am required to have above-average security +practices in place on my machine. I already had some standard security in +place, such as full disk encryption and PGP encrypted email, but I thought that +this would be a good time to up my game. To accomplish this, I purchased a +Yubikey to act as my physical security token. Additionally, I have a USB device +which is also encrypted to hold backups of the keys. + +In this blogpost, I will detail how I set up my security policies in the hopes +it will be able to help out other people looking to improve their security, and +to get feedback to improve my set up as well. + +[NOTE] +==== +I am using the Yubikey 4. If you're using another version, some steps may +differ. +==== + +== Installing required software + +You'll need some software to set all of this up. Depending on your +distribution, some of it might already be installed. Everything not installed +yet should be installed with your distribution's package manager. + +For encrypting the disk and the USB key, you will need `cryptsetup`. To +generate and use the PGP keys, you will need `gpg`, at least version 2.0.12. + +To securely remove the temporary data we need, you should make sure you have +`secure-delete` available on your system as well. + +== Personalizing the Yubikey + +The Yubikey can be personalized. Some of this personalization is completely +optional, such as setting personal information. However, setting new PIN codes +is strongly advised, as the default values are publicly known. + +=== PIN codes + +The PIN codes are short combinations of numbers, letters and symbols to grant +permission to write to or retrieve data from the Yubikey. The default value for +the user PIN is `123456`. The admin PIN is `12345678` by default. These should +be changed, as they're publicly known and allow the usage of your private keys. +To change these, use the `gpg` program and enter admin mode: + +[source] +---- +gpg --card-edit + +gpg/card> admin +Admin commands are allowed +---- + +You'll notice it immediately says that admin commands are now allowed to be +used. The admin PIN (`12345678`) will be asked whenever an admin command is +executed. It will then be stored for this session, so you won't have to enter +it right away. To update the PIN values, run the following commands: + +[source] +---- +gpg/card> passwd +gpg/card> 3 +---- + +This will change the admin PIN first. This PIN is required for managing the +keys and user PIN on the Yubikey. To set the user PIN, pick `1` instead of `3`: + +[source] +---- +gpg/card> 1 +---- + +Once this is done, you can quit the `passwd` submenu using `q`: + +[source] +---- +gpg/card> q +---- + +You may have noticed we skipped the reset code. Resetting the device will wipe +existing keys, so it's not a serious risk to keep this at the default. The +private keys will be backed up to an encrypted USB drive, so we can always +retrieve them and put them back on the Yubikey if ever needed. + +=== Personal information + +The personal information is optional, but could be used by a friendly person to +find out who a found Yubikey belongs to. They can contact the owner, and send +the key back. You can set as many of the personally identifying fields as you +want. If you're interested in setting this information, plug in your Yubikey +and edit the card information with `gpg`: + +[source] +---- +gpg --card-edit +---- + +Once you're back in the GPG shell, you can update your personal information. +There are 5 attributes that you can set in this way: + +- `name`, which is your real name; +- `lang`, which is your preferred contact language; +- `sex`, which is your real sex; +- `url`, which indicates a location to retrieve your public key from; +- `login`, which indicates your email address. + +Each of these attributes can be updated by running the command in the GPG +shell. For instance, to update your real name, run the following: + +[source] +---- +gpg/card> name +---- + +You do not need to explicitly save once you're done. You can run `quit` to quit +the GPG shell and return to your regular shell. + +== Creating PGP keys + +To create the PGP keys, we'll create a temporary directory which will function +as our working directory to store the keys in. This way you can't accidentally +break existing keys if you have them, and ensure that the private keys don't +accidentally linger on in your filesystem. + +=== Preparing a clean environment + +To create such a temporary directory, we'll use `mktemp`, and store the result +in an environment variable so we can easily re-use it: + +[source,sh] +---- +export GNUPGHOME="$(mktemp -d)" +---- + +Now you can switch to that directory using `cd "$GNUPGHOME"`. Additionally, +`$GNUPGHOME` is also the directory `gpg` uses as its working directory, if it +is set. This means you can use a temporary custom configuration for `gpg` as +well, without it affecting your normal setup. The following configuration is +recommended to set in `$GNUPGHOME/gpg.conf` before starting: + +[source,conf] +---- +use agent +charset utf-8 +no-comments +keyid-format 0xlong +list-options show-uid-validity +verify-options show-uid-validity +with-fingerprint +---- + +If you have a `gpg-agent` running, it is recommended to stop it before +continuing with `killall gpg-agent`. + +=== Creating the master key + +For our master key, we'll go for a 4096 bytes RSA key. 2048 would be plenty as +well, if you want the generation to be a tad quicker. `gpg` will ask you a +couple questions to establish your identity, which is required for a PGP key. +You can add more identities later, in case you're using multiple email +addresses, for instance. + +Start the key generation process with `gpg`: + +[source] +---- +gpg --full-generate-key +---- + +When asked what kind of key you want, choose `4` (RSA (sign only)). Next is the +key size, which should be `4096`. + +The key's expiration is optional, though highly recommended. It will be more +effort to maintain the keys, as you'll occasionally need the private master +keys to extend the validity, but you can also guarantee that your keys won't +stay valid in case you ever lose them. If you don't want to bother with +refreshing your keys from time to time, just press enter here to continue. + +When prompted on whether the data is correct, doublecheck whether the data is +really correct, and then enter `y` and press enter to accept the current +values. `gpg` will continue with your identity information, which you should +fill out with your real information. The comment field can be left empty, this +is an optional field to add a comment to your identity, such as "School", or +"Work keys". `gpg` will ask your confirmation one final time. Enter an `o` +(it's not case sensitive) and press enter again. The final step before it will +generate a key is to enter a passphrase. This is technically optional, but +highly recommended. If anyone ever gets their hands on your private master key, +they will need the passphrase in order to use it. Adding one is yet another +layer against malicious use of your key. + +Once you've chosen a passphrase, it will generate they key and output some +information about the key. Verify whether this information is correct one more +time, and if it is, you can continue to the next step. If it is not, redo the +whole PGP section of this post. + +Take note of the line starting with `pub`. It shows that the key is an +`rsa4096` key, followed by a `/`, and then the key ID. You'll need this key ID +throughout the rest of this post. For convenience, you can store this ID in +a variable, and just refer to the variable when you need it's value again: + +[source,sh] +---- +export KEYID=0x27F53A16486878C7 +---- + +This post will use the `$KEYID` variable from now on, to make it easier to +follow. + +=== Creating a revocation certificate + +The revocation certificate can be used to invalidate your newly created key. +You should store it seperately from the private master key, preferably printed +on a sheet of paper. If you want to be able to easily read it back in, consider +printing it as a QR code. + +To create the certificate, run the following: + +[source] +---- +gpg --gen-revoke $KEYID > $GNUPGHOME/revoke.txt +---- + +This will prompt you to specify a reason, for which you'll want to use `1`. +This way you can easily revoke the key's validity if you ever lose it. If you +want to revoke your keys in the future for any other reason, you can always +generate a new revocation certificate for that specific purpose. You don't have +to supply an additional description, so just hit enter. A revocation +certificate will be written to `$GNUPGHOME/revoke.txt`. + +=== Creating the subkeys + +Now that you have your master key and the ability to revoke it in case anything +goes wrong in the future, it's time to create a couple of subkeys which can be +stored on the Yubikey, and used in your daily life. We'll create seperate keys +for _encryption_, _signing_ and _authentication_, and store each of them in +their own dedicated slot on the Yubikey. + +To add subkeys to your master key, enter a GPG shell to edit your existing +key with `gpg --expert --edit-key $KEYID`. The `--expert` is required to show +all the options we're going to need. Once the GPG shell has started, run +`addkey` to add a new key. + +Just like with the master key, a number of questions will be asked. Expiration +for subkeys is generally not advised, as the subkeys will be considered invalid +whenever the master key has expired. The key sizes for the subkeys can be left +at 2048 as well, which is also the maximum size for keys for the older Yubikey +models. The key type is different for all 3 subkeys. + +You will want to select type `4` (RSA (sign only)) for your signing key, type +`6` (RSA (encrypt only)) for the encryption key, and type `8` (RSA (set your +own capabilities)) for the authentication key. With the final key, it will ask +you what capabilities you want to enable. The only capability you want it to +have is *Authentication*. + +Once you've created the subkeys, you can check `gpg --list-secret-keys` to look +at your newly created keys. You should have 1 `sec` key, which is the master +key, and 3 `ssb` keys, which are the subkeys. One line should end with `[S]`, +one with `[E]` and one with `[A]`. These denote the capabilities of the +subkeys, _Sign_, _Encrypt_ and _Authenticate_, respectively. + +=== Export the keys + +Now that you have your keys generated, you should export them, allowing you to +easily import them in another environment in case you ever need to generate +more keys, invalidate some keys, or extend the validity of the keys in case you +set an expiry date. This can be done with the following commands: + +[source,sh] +---- +gpg --armor --export-secret-keys $KEYID > masterkey.asc +gpg --armor --export-secret-subkeys $KEYID > subkeys.asc +---- + +== Creating a backup USB + +For the backup of the private keys, I'm using an encrypted USB device. You can +also opt to print the keys to paper, and retype them if you ever need them. Or +print a QR code that you can scan. But for convenience sake, I went with a USB +device. I encrypted it, and stored it in a safe and sealed location, so it's +easy to detect unwanted attempted access. + +=== Encrypting the USB + +For the encryption, I went with full device encryption using LUKS. You will +need the `cryptsetup` utility to apply the encryption, and to unlock the drive. +You can find out the device name from `dmesg` or `lsblk`. Once you know it, +encrypt the drive with the `luksFormat` subcommand. + +[WARNING] +==== +Using the wrong name for the device can irrecoverably destroy data from another +drive! +==== + +[source,sh] +---- +cryptsetup luksFormat /dev/sdb +---- + +It will prompt you whether you want to continue, and ask twice for a passphrase +to ensure it is correct. Make sure you don't forget the passphrase, or you'll +lose access to your backup keys. + +Once it has been encrypted, unlock the device. + +[source,sh] +---- +cryptsetup luksOpen /dev/sdb crypt +---- + +This will open the device as `/dev/mapper/crypt`. Format it with your favourite +filesystem. I used `ext4`. + +[source,sh] +---- +mkfs.ext4 /dev/mapper/crypt +---- + +Once it has been formatted, you can mount it as a regular device. + +[source,sh] +---- +mount /dev/mapper/crypt /mnt/usb +---- + +=== Copying the keys + +Copying the keys is as straightforward as copying other files. You can use +`$GNUPGHOME` to target the source directory. + +[source,sh] +---- +cp -arv "$GNUPGHOME"/* /mnt/usb/. +---- + +Once the files are copied, you can unmount the drive, lock it and unplug the +USB. + +[source,sh] +---- +sync +umount /mnt/usb +cryptsetup luksClose crypt +---- + +Store the USB in a safe location, because these private keys can give someone +full control of your identity. + +== Storing the private keys on the Yubikey + +The Yubikey has key slots for encryption, signing and authentication. +These need to be set individually, which can be done using `gpg`. First, you +need to select a key using the `key` command, then store it on the card using +`keytocard` and finally deselect the key by using the `key` command again. + +[source] +---- +gpg --edit-key $KEYID + +> key 1 +> keytocard +> key 1 + +> key 2 +> keytocard +> key 2 + +> key 3 +> keytocard + +> save +---- + +You can verify whether the keys are available on the Yubikey now using `gpg +--card-status`. It will show the key fingerprints for the `Signature key`, +`Encryption key` and `Authentication key`. + +=== Sharing your public key + +You can share your public keys in many ways. Mine is hosted link:/pubkey.txt[on +my own site], for instance. There are also https://sks-keyservers.net/[public +keyservers] on which you can upload your keys. `gpg` has the `--send-keys` and +`--recv-keys` switches to interact with these public keyservers. For ease of +use, I would recommend uploading them to a public keyserver, so that other +people can easily import it. For instance, my key can be imported using `gpg`: + +[source] +---- +gpg --recv-keys 0x7A6AC285E2D98827 +---- + +== Clean up + +The keys are on the Yubikey, and you probably do not want to leave traces on +your local system of these new keys, so you should clean up the `$GNUPGHOME` +directory. There's a utility for securely removing a directory with all its +contents, called `secure-delete`, which provides the `srm` program. You can use +it just like the regular `rm` on the temporary directory. + +[source,sh] +---- +srm -r "$GNUPGHOME" +---- + +You can also `unset` the `$GNUPGHOME` variable at this point, so `gpg` will use +it's default configuration again. + +[source,sh] +---- +unset GNUPGHOME +---- + +== Configure GPG + +Finally, you have your keys on the Yubikey and the traces that might have been +left on your device are wiped clean. Now you should configure `gpg` for regular +use as well, however, this is completely optional. All this configuration does +is ensure you have good defaults for the current day and age. + +[source] +---- +auto-key-locate keyserver +keyserver hkps://hkps.pool.sks-keyservers.net +keyserver-options no-honor-keyserver-url +personal-cipher-preferences AES256 AES192 AES CAST5 +personal-digest-preferences SHA512 SHA384 SHA256 SHA224 +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 +ZLIB BZIP2 ZIP Uncompressed +cert-digest-algo SHA512 +s2k-cipher-algo AES256 +s2k-digest-algo SHA512 +charset utf-8 +fixed-list-mode +no-comments +no-emit-version +keyid-format 0xlong +list-options show-uid-validity +verify-options show-uid-validity +with-fingerprint +use-agent +require-cross-certification +---- + +== Conclusion + +You now have PGP keys available on your Yubikey. These keys are only available +to your system if the Yubikey is inserted, and the user PIN is given. You can +use these keys for authentication, signing and encrypting/decrypting messages. +In a future post, I'll detail how to set up a number of services to use these +keys as well. -- cgit v1.1