Abhay Rana aka Nemo

My Setup: Passwords, 2FA, and Yubikeys

I upgraded my encryption setup recently, so I thought I should write about it, just in case it is helpful to someone else. As a security professional, I have a different threat model from most folks, and as such my setup does involve a bit more complexity than what I’d recommend to everyone. But if you are an at-risk individual (journalist, person holding hundreds of bitcoins or other digital assets, activist) or if you are a linux user with a lot of free time - you might consider duplicating some of this.

Header Image of my keychain, with a Tile, Yubikey, USB Disk, and house keys

I’ll discuss some of the other approaches I’ve considered, and my thought process around each choice I made. There are general recommendations at the bottom of the post.

Passwords

I used to be on LastPass till 20171, when I migrated to pass (“the standard unix password manager”). With pass, each password lives inside of a gpg encrypted file whose filename is the title of the website or resource that requires the password.

pass automatically manages a git repository for you, which I sync against GitLab. The one downside of using pass is that the list of my domains is visible to my hosting provider. 2 In the past, I’ve set this up against Keybase Encrypted Git (Keybase doesn’t get to see even the file list), and my own git-server (only I get to see it).

I don’t push it to GitHub, since most of my stuff lives on GitHub anyway, and I didn’t want to add my passwords there as well. GitLab uptime is decent enough for my usecase3. Finally, my GitLab account is fairly locked down with:

  • zero integrations or third-party apps
  • no active personal tokens
  • social signin disabled
  • only yubikey SSH key configured

Mobile Passwords

There are 2 primary considerations I have:

  1. Using pass involves GPG keys, and I can’t use hardware GPG keys on my current device (iPhone SE).
  2. I don’t want to sync all my passwords to my phone. I have a limited number of applications on my device, and syncing all passwords doesn’t make sense.

For the first issue, I am forced to use a PGP key in software on passforios. If you are on Android, take a look at OpenKeychain, and Fidesmo/Yubikey NFC.

For the second issue, I use pass cp, and the .gpg-id file, which allows me to maintain a mobile-sync directory inside my pass git repository encrypted against a different key. From the pass documentation:

~/.password-store/.gpg-id

Contains the default gpg key identification used for encryption and decryption. Multiple gpg keys may be specified in this file, one per line. If this file exists in any sub directories, passwords inside those sub directories are encrypted using those keys. This should be set using the init command.

My ~/.password-store/mobile-sync/.gpg-id file holds 2 keys: My main encryption key, and the key I’ve configured on my phone.

Unfortunately, I haven’t gotten it working well as a git submodule, so I have a helper script that copies the encrypted password files from mobile-sync subdirectory to a different repository (mobile-passwords.git). The script is just 2 lines:

cp -r ~/.password-store/mobile-sync/*.gpg .
git-sync

It updates the git repository, and runs a sync to push any local changes to my mobile-passwords repository. I can pull that on my passforios application. I could also clone the entire repo, but the iOS app doesn’t work nicely with a single-subdirectory approach.

GPG

pass relies on GPG, and as such I require a strong key setup. I have the following:

  1. 2xYubikey 4 (Doesn’t have NFC)
  2. Fidesmo Smartcard, currently unused

Both the Yubikeys are configured against my GPG Encryption key. I carry one of the Yubikeys on my keyring with me. The backup Yubikey stays at my home.

I followed this guide while configuring the same. As of now, switching between keys is not very user-friendly, but future GnuPG versions plan to fix it. The Yubikey holds:

  • An encryption key
  • A signing key
  • An authentication key

I keep a copy of all these keys using paperkey as per the same guide. I have a subkey backup as well, since Yubikeys are known to fail4.

SSH

The Authentication key in my Yubikey is configured for SSH. I just need to ensure that my GPG agent is configured for SSH as well:

export GPG_TTY="$(tty)"
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent

U2F

U2F lets me use a physical key as my second-factor on supported websites (as an alternative to SMS/TOTP). I configure both of my Yubikeys for U2F wherever possible (Twitter/AWS are notable exceptions and only support a single key). U2F support for OpenSSH is coming soon. So you can soon authenticate to your server with the Yubikey+PIN, and finish the 2FA with U2F by tapping the key5.

Root-of-Identity

For most people, the root of identity comes down to ownership of their email address. As such, it is very often the juiciest target for most attackers. I run my mail against Migadu, a privacy friendly swiss email-hosting service. They provide me a management layer for managing my domains which uses my GMail account. (See FAQ for why). I also have 2FA (TOTP only) configured on the Migadu management setup.

The domain is currently registered at a Indian registrar (which doesn’t offer U2F, but I do have TOTP configured). I would have moved this to CloudFlare, but CloudFlare doesn’t support the .in TLD yet.6

The email address used for registring the domain again is my GMail. My DNS is configured on CloudFlare, which again uses my GMail and has appropriate 2FA configured. (It doesn’t support U2F). So here’s the list of critical providers:

Provider What can an attacker do Auth 2FA
Regisrar/Mitsu Change my nameserver, read any future email, reset passwords GMail/Password TOTP
DNS/CloudFlare Change my MX records, read any future emails, reset passwords GMail/Password TOTP
Email/Migadu Reset my email password, read my current emails, reset passwords GMail/Password TOTP
GMail Reset passwords for the above 3 accounts Email/Password U2F

As you can see, I end up trusting GMail a lot here.

Recovery/Backup codes and Security Questions

I use randomly generated UUIDs as answers to security questions. Currently, I’m storing these for various services within the same password store. As it stands, I can’t get access to my password OR recovery token without my Yubikey and PIN. The access Matrix looks like this:

What Physical Access Additional Authentication
Password Yubikey PIN
U2F-2FA Yubikey Physical touch
TOTP Phone TouchID
Recovery Code Yubikey PIN
Security Question answers Yubikey PIN

Failure Scenarios

There are lots of failure scenarios with such a setup, and while I’ve got a pretty spotless record of not getting hacked - I’m not immune to screwups. Here’s all the bad things that can happen:

Yubikey failures

If my Yubikey fails (or if I forget its PIN), I can’t access passwords on my device. I still have access to commonly used passwords and my mail on my phone. My backup Yubikey is kept safely at my home. If I lose both, I have the paperkey backup at home (which I should store elsewhere).

Device failures

I have a current version of the password repository against 3 PCs, and a partial version in my mobile. If all these 4 devices fail at once, I can still clone a fresh version of the repository with my YubiKey (I would still have GitLab SSH access). I might need to prepare better for this though, since configuring GPG-SSH might not always be easy during an incident.

As a alternate scenario, my phone GPG key does have my GitLab password, so I can clone the repo over HTTPS (with password) if needed.

Circular dependency against GitLab

My GitLab password is randomly generated and stored in the same password store on GitLab. That is not too big of an issue, because I don’t need the GitLab password anymore to clone my passwords repo, just my Yubikey (for SSH).

Lost Key

If I lose my key, the GPG card contains public info, including my email address, which can be used to contact me. I have a Tile bluetooth tracker on my keychain to make it easier for me to find it.

Malware

A hardware key doesn’t protect you from all attacks. At the end of the day, my passwords must be decrypted by the key and passed unencrypted back to my browser (or editor). pass for eg, doesn’t protect against memory scraping attacks. If I edit a password on an infected machine, it gets that password.

If my browser has a malicious extension, it already has keys to the kingdom. But if I then log into a website, it does get access to that password additionaly.

xkcd 1200 famously illustrates this:

xkcd 1200

A password vault protected by a hardware key protects against some attacks:

  • A malicious extension can’t sniff my vault passphrase, since I don’t have one
  • The key can’t be exfiltrated from hardware.

However, a malware can connect to my authenticated GPG socket, and start decrypting things. To prevent against that, I run my Yubikey in “touch-only” mode, so it requires a “physical touch” before it actually does anything, even if the PIN is cached. Customizability is dependent on your Yubikey model. But remember the xkcd warning - if I have a malware running on my device, it is pretty much game over anyway. pass doesn’t prevent against memory scraping attacks, and actually uses /dev/shm to store the temporary plain-text files containing passwords. Ultimately, your identity is as secure as the device you trust it with.

Improvements

If you have any suggestions for any of the below, I’m happy to hear them.

Travel Plans

Since my backup key stays at home, how do I deal with long-term travel? This is something I’m still figuring out. Do I take my backup Yubikey on my longer-travels? Or should I setup a third-key before I do that? Chances of me losing both the keys together are quite high, so I’m trying to avoid that.

Domain Ownership

I’d like to transfer my domain to a registrar that supports U2F, likely Namecheap since I already own some domains there7. If you use CloudFlare, they should roll out U2F support soon.

2FA Recovery Guides

I wish more organizations published what they consider as valid 2FA recovery mechanisms. GitHub supports 2FA recovery by proof of SSH keys or Personal Tokens; Migadu just needs a few domain names from your account, and lots of services require proof-of-identity.

A lot of this is undocumented, and I wish organizations were more public about this so users can take appropriate measures and understand their risk better.

Fidesmo Card

I’m planning to configure my Fidesmo card against my existing GPG/SSH key, so it stays in my wallet to improve redundancy. Unfortunately, it is not supported on iOS, so I plan to get a NFC reader/writer and test that out. This also helps with travel plans a bit, since I’m less likely to lose my wallet anecdotally(which also has a bluetooth tracker).

U2F on iPhone

U2F support on Mobile Safari is non-existent. Brave recently added support for the upcoming Yubikey 5Ci, which supports both USB-C and lightning. However, this requires a special Yubikey SDK, which breaks the idea of U2F being interoperable. The 5Ci is also quite costly at $70. I don’t know of any application that is actually supporting GPG-over-Yubikey-over-lightning.

Compare this to Android where NFC based smartcards or Yubikeys just work. I’d like that to happen with iPhones.

Full Disk Encryption using a Yubikey

It is possible to configure Full Disk Encryption with Yubikeys, but I haven’t tried it yet.

2FA on my email account

Migadu currently does not support 2FA on webmail access, just on manage.migadu.com. This is very unfortunate, but I’m told this is planned soon (January 2020).

Recovery/Backup codes and Security Questions

My current setup of saving recovery codes alongside passwords isn’t optimal, but I don’t have a better way either. I’ve considered keeping my recovery codes on a alternate password store (such as bitwarden, or keypassX), but I’ll have to memorize the password, and setup a separate 2FA for it to be truly fault-tolerant.

FAQ

Why do you have stuff configured on your GMail? Aren’t you anti-Google?

Despite all the flak that Google gets for privacy, their security team is pretty awesome. Your account is pretty much unhackable once you are enrolled into their Advanced Protection Program. The few security-sensitive places where I use it are:

  1. Domain Registration
  2. Email Management
  3. DNS Configuration

Everywhere else, I use my actual domain (captnemo.in) to ensure nothing else routes over GMail. Using GMail for the above 3 ensures that I don’t have a circular dependency. If I were to lose my main email password, I can recover via multiple ways:

  1. Change DNS to another email provider.
  2. Reset password via migadu admin panel.

Ensuring that either of these workflows do not rely on the same email account I’ve just lost access to is vital. Another alternative is to use a trusted-friend (ideally someone more paranoid than me) as a proxy for these emails, and use their domain for managing these 2 services. Might get around to it someday.

My GMail recovery email is set to my main account, so it creates a circular dependency, but one that I actually want.

What do you recommend I use?

  • Bitwarden for password management.
  • 2xHyperFIDO Mini U2F Keys configured for second factor against as many accounts as possible. U2F is not only safer, but much more convenient than TOTP/SMS based 2FA. For iPhone/USB-C users, see the Yubico website. If you don’t like to pay the USB-C tax, there are cheap USB-C to miniUSB adapters that can work with the HyperFIDO key and fit on your keychain. If you aren’t convinced on why this is a good idea, see this guide. The second key is just a backup key, and could be the primary key used by your spouse, friends or co-workers.
  • A PIN configured on all your SIMs. Instructions for iPhone, Android.
  • Full-Disk-Encryption on all your devices. Instructions for Windows, Mac, ArchLinux, Fedora, Ubuntu.
  • Use randomly generated passwords everywhere. Trust your password manager on this.
  • Setup a PIN on your WhatsApp.
  • If you own a lot of cryptocurrency, use a hardware wallet and put it in a bank safe. Have a backup one, in another safe. You can put the PIN for those in your password store. I haven’t researched enough to suggest you which wallet(s).
  • Get a SIM without an Aadhaar, to make SIM-Jacking attackes harder (applies in India).
  • Go through securityplanner.org, which gives you personalized recommendations customized for our risk profile. I agree with most of their recommendations8
  • Signup for breach notifications against your email at https://haveibeenpwned.com/.
  • If you’d like to get off GMail, pay for FastMail. Alternatively, if I know you in real-life, I’m happy to host your mail in my Migadu account. (Only works if you know me well enough to trust me)

Why are you so paranoid?

I work in infosec. Breaking things comes naturally to me, and I plan for defense-in-depth. Plus, I’d be a terrible security person if I got hacked.

Why not recommend open source keys instead?

Availability is a pain point, especially if you aren’t in the US. Even getting my hands on a SoloKey was hard, despite backing it on KickStarter.

The HyperFIDO keys are compliant to the U2F/FIDO standards, and I’ve not faced any issues while using them. They’re cheap and widely available. Unless you need GPG, go for it.


Thanks to Giridharan, Santosh, and Akshay for reviewing drafts of this and offering valuable suggesions. If you have any suggestions, happy to hear them on Twitter or elsewhere


  1. I moved away from Lastpass after Tavis Ormandy reported a RCE vulnerability on their browser extension. Their wikipedia page mentions 2 breaches, and 3 security incidents. It has never undergone a security audit (unlike bitwarden) and is not something I recommend anymore. 

  2. The pass-tomb extension bypasses this limit and encrypts your filenames as well. 

  3. I have my own git server configured as a fallback if it goes down. I ensure the same controls on my Git server as Gitea, and it runs in my living room. 

  4. I lost my previous GPG key because my Yubikey stopped working 

  5. The jury is still out on whether this counts as an “independent second factor”. 

  6. The domain is stuck in a legal limbo, because of an ongoing case between my registrar and NIXI (which runs the .in registry). If you have any suggestions/ideas, please reach out

  7. Namecheap announced U2F support in April 2019, and while it was buggy at first, it has definitely improved. 

  8. The one major exception is lastpass, which I no longer recommend. 

Downgrading my iPad 2 to iOS 8

I own a iPad 2 (GSM), which is rarely used these days because it is too slow with the latest iOS 9 upgrades. It is a 8 year old device, but I can’t just install Linux on it and make it usable, which is what I do with most other devices.

The next best thing was to downgrade the iOS version. The device is anyway un-supported at this point, so I might as well go there. Apple has restrictions on which iOS releases are installable at any point on any device, but thankfully they are still signing iOS6 for my device for some legal reasons.

Steps:

  1. Download the iOS firmware for your device from https://ipsw.me/#platform
  2. Launch iTunes
  3. Option+Click on the Restore button in iTunes
  4. Select the file you just downloaded.
  5. Disable iCloud on the device
  6. Upgrade to iOS8

This is possible as long as Apple is signing the IPSW for your device. The case of iOS6 being signed seems to be true for:

  • iPhone 4S
  • iPad 2

Security Notes

Running an unsupported OS is not something I take lightly. Here’s a list of defensive measures I took to ensure that I’m not at risk while doing so:

  1. Try to keep the device always in Airplane mode.
  2. Keep sensitive data off the device. No photos/keychain sync for eg. Don’t enable Calendar/Contact/Media sync.
  3. Enable Restrictions on the device:
    • Restrict Safari to limited websites.
    • Disable application installs.
    • Disable iTunes store/iBooks store etc.
    • Disable GPS/Bluetooth.
    • Limit Background Refresh to very few trusted applications.
  4. Limit number of applications (I only have Kybooks installed).
  5. Disable Javascript on Safari.

If possible, I’d recommend using a separate Apple Account on the device.

Cleaning up Google Purchases

The Google Purchase History feature has been doing rounds in the news recently. In case you missed it, go to https://myaccount.google.com/purchases right now and make sure you are logged in with your personal gmail account to see what all Google thinks you’ve bought.

For me it lists purchases going as far back as 2013, which include:

  1. All of my Amazon Purchases (including Kindle and Audible)
  2. Flipkart/Sneapdeal purchases
  3. Gifts I’ve bought for others on various platforms
  4. All my iCloud purchases
  5. Purchases on Steam
  6. BigBasket purchases
  7. Google Playstore purchases as well, of course
  8. And much, much more.

For each of the purchases, it remembers the price, the taxes, as well as the delivery address used.

While this isn’t shocking in the least, I was surprised, because as a Infosec professional, I’ve disabled all of google’s invasive tracking features:

  1. All my Activity Controls are paused.
  2. Google Location history is disabled for my account.
  3. I have Shared endorsements turned off.
  4. Ad personalization is turned off.
  5. I used to run with the Protect my Choices extension till a while back to avoid targeted advertising.

Regardless, the Google purchases page had hundreds of results, going back half a decade. Google currently does not offer a way to delete collected purchases directly, or to pause this collection in any way. The only way is to find the emails that Google scanned, and delete them.

I ended up deleting everything from the following email addresses:

auto-confirm@amazon.com
auto-confirm@amazon.in
cs@flipkart.com
digital-no-reply@amazon.com
do_not_reply@audible.com
do_not_reply@gog.comorders@services.target.com
ebay@ebay.in
googleplay-noreply@google.com
help@stickermule.com
mail@info.fabfurnish.com
no-reply@flipkart.com
no-reply@paytm.com
no_reply@email.apple.com
noreply@flipkart.com
noreply@pizzahut.co.in
noreply@snapdeals.co.in
noreply@steampowered.com
notification@wish.com
order-update@amazon.in
orders@services.target.com
payments-messages@amazon.in
return@amazon.in
ship-confirm@amazon.com
ship-confirm@amazon.in
shipment-tracking@amazon.com
shipment-tracking@amazon.in
updates@myntra.com

Note that deleting the email doesn’t seem to be sufficient either, you need to clear your Trash, and then wait for a while (almost 2 days for me) before the system refreshes. After 3 days of just deleting mails, I finally got this screen:

screenshot of google purchases dashboard showing "You don't have any purchases"

Google seems to be picking up all kinds of emails, including:

  1. Invoices
  2. Shipment Confirmations / Updates
  3. Return confirmations
  4. Payment Confirmations
  5. Order Cancellations
  6. Payment Failures (gasp!)

Warning about Deletions

I’ve already switched away from Amazon/Flipkart emails from my Gmail. But deleting invoices from your inbox isn’t always the best idea. Most websites will let you re-download invoices (Amazon/Flipkart do), but take care not to delete any necessary emails that you might need for warranty claims or any other purpose later.