nixpulvis

Keep It To Yourself 1360 words drafted on April 02, 2020.

Keeping yourself secure in the modern age of digital computers and the internet is a daunting task. While I like to think I’m somewhat sophisticated in this regard, surely there are flaws in my approach, begging to be exploited and abused. This is somewhat unavoidable, so as a general rule of thumb, don’t be malicious. The following is my current best practices for things that involve information security.


Table of Contents

Section 1
First we define our master password(s), then we build up a GPG key structure, finally we use the GPG keys to secure a secret database of other passwords, keys, and anything else.

  1. The Master Password(s)
  2. Key Management
  3. Password Management

Section 2
Next, we look at best practices for common kinds of personal information.

  1. General Backups
  2. Personal Private Information
  3. Secure Online Communication

The Master Password(s)

Key Management

Key management through PGP is the main security concern, from which we can build the rest somewhat easily. Luckily SmartCards can be purchased easily these days, and make some of this much more trustworthy than it may have been in the past.

GPG Keys

At the heart of my setup lies PGP (Pretty Good Privacy), a suite of encryption technology with well supported CLI and hardware applications. PGP allows creating key-pairs with sub-keys (more on this later). GPG (the GNU implementation of PGP) is used to encrypt data and manage authentication. We’ll create a new key-pair with 4096 bits. Entropy will be generated by doing the most unusual of things to my computer in the process, you know, for security.

The primary private GPG key itself must be stored safely somewhere, like on a keychain, and rotated from time to time.

NOTE: Rotating keys requires syncing gpg data, which requires all machines to receive a copy of the local data. This is cumbersome, but seemingly needed.

Smart Cards / Security Tokens

I own both a YubiKey 5C and 5C Nano, each with a distinct physical use case. The traditional 5C fits onto my keychain (like with my house keys), and I can use it to plug in and out of computers to authenticate. Meanwhile, the 5C Nano is small enough to stay in a device, making it good for removable secure enclave for your private keys. If you host a personal server, or simply don’t want to think about plugging in your keys then this may be your primary key. I personally feel like the primary key shouldn’t be left in the device, but rather carried on your person. So, I keep the YubiKey 5C around as my primary key, and leave my 5C Nano in a safe place, as a backup. They are each distinct keys, so care must be taken to ensure data allows either key as needed.

Subkeys

In addition to SmartCard keys, conventional GPG keys can be generated and used.

SSH (Secure Shell) Keys

SSH keys should named, with the following format: nixpulvis@<hostname>. Each key will be saved by name in a pass directory called SSH. This way we can control access to individual hosts.

Password Management

Once we have our key management taken care of and our master password(s) / PIN(s) are memorized, we can rely on pass for managing various other passwords and other secret data. Both our primary GPG key, and a backup will be used for this password store. These passwords are generally generated, and therefor not memorized. Some kinds of accounts may be best to memorize still, just make sure they aren’t the same password as the master passwords from our key management.

pass stores it’s data in a plain ol’ folder, making it work perfectly with git. In fact pass git ... can be used to perform arbitrary commands from anywhere on the system. We currently store user ids in the folder name, so the repo must be private. I’m currently only storing this repo on devices and syncing with either SSH, or a USB drive.

pass shows each record like a file within the directory tree (~/.password-store by default).

accounts/<url>/<username> -> <password>

├── accounts
│   ├── accounts.adafruit.com
│   │   └── nixpulvis
│   ├── aur.archlinux.org
│   │   └── nathan@nixpulvis.com
│   ├── bbs.archlinux.org
│   │   └── nixpulvis
│   ├── cloud.digitalocean.com
│   │   ├── sever1
│   │   │   ├── nixpulvis
│   │   │   └── root
│   │   └── nathan@nixpulvis.com

# Copy Adafruit password into your clipboard.
pass -c accounts/accounts.adafruit.com/nixpulvis

Storage

The .password-store data will live on each machine, an encrypted USB drive and a private repo hosted somewhere good and encrypted.

Remember that the contents of pass are in an unprotected git repository. So, while the data under each entry is protected with our keys, someone with access to the repo can, for example, run git log on the changes made to the password store. Bee careful to avoid manual commit messages that leak information, or other non-standard pass practices. It’s best to simply avoid storing the password store anywhere in the clear.


Backups

I’ll be using borg to backup my machines, this data is encrypted using a key and password that should live in pass. There are a few types of Borg backups to support:

backup/<device> -> <password>
backup/<device>/key -> <borg_key>

├── backup
│   ├── wd2T
│   │   └── key
│   └── wd2T

Blue-ray Disk Drive Backup

Local HDD/SSD Backup

Remote Backup (Digital Ocean?)

Personal Private Information

PII (Personally Identifiable Information) like my SSN, healthcare IDs and other various sensitive information should be included in pass and nowhere else… well, at least digitally, of course the original documents should be stored in a safe/wallet or something.

In a system of cryptographically ensured ownership semantics (QM?), it’d be very cool to ensure these values “lived”, for lack of a better word, in my pass repo. I have no idea what an implementation of this would look like though.

Other things can be saved in pass too, like tax, healthcare, finance, or any other sensitive information.

<note>/* -> <note>

├── health
│   └── ...
└── taxes
    ├── 2017
    └── 2018

Other people’s contact information is private. We can store both public names with their fingerprints (or other potentially private information):

contacts/<name> -> <gpg_fingerprint>

├── contacts
│   ├── Nathan Lilienthal
│   ├── Bob Smith
│   │   ├── Personal
│   │   └── Work
│   ├── Jane Doe