This is an update of my original guide for macOS 10.3 High Sierra
This guide was tested on my current development setup:
- Local: macOS Monterey 12.13.1 on a Mac Studio M1 Max (Mac13,1)
- Remote: AWS EC2 Ubuntu 18.04 LTS (Server, Bionic Beaver)
And for the hardware, I'm using a couple of YubiKey 5. I highly recommended that you get at least a pair of them. Throughout the guide and in the GnuPG references, the YubiKey is referred to as a card, while key refers to a RSA Key.
Do note that macOS has changed a bit in the past releases, and it has introduced some variations between Intel and Apple Silicon installations. For example, in Intel the default path for binaries is /usr/local/bin
, while in Apple Silicon /opt/homebrew/bin
is used. Also, this guide is written for zsh, as this shell has been shipping as the default in macOS for a while now.
1. Configure your Local Machine
We need to install some utilities in the local machine provide the basic functionality to interfase with the YubiKey. We'll be using GnuPG:
GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available. GnuPG also provides support for S/MIME and Secure Shell (ssh).
The easiest way to install GnuPG in macOS is by using Homebrew, and it might be a good idea to install the Rosetta 2 translation layer before installing anything else:
softwareupdate --install-rosetta
If your shell profile does not specify a language with LANG
, then gnupg2
will try to guess the best language for you. For some unknown reason, my installation decided that it'd be better in spanish and while the intention is appreciated, the command line utilities are a bit wonky in languages other than english.
However, this is a very quick fix. We'll set the appropiate LANG
environment variable in the bash profile to en
.
echo 'export LANG=en' >> ~/.zshrc
echo 'export LC_ALL=en_US.UTF-8' >> ~/.zshrc
Finally, install the required packages for GnuPG (gnupg2
now ships with its own built-in gpg-agent
):
brew install gnupg2 pinentry-mac
We will need to adjust some permissions to the files and directories created by the installer.
mkdir -p ~/.gnupg
chown -R $(whoami) ~/.gnupg/
chmod 600 ~/.gnupg/*
chmod 700 ~/.gnupg
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*
Along with GnuPG, we've installed a utility called gpg-agent
which operates as a link between the YubiKey and the underlying GPG libraries. In order to improve the compatibility between macOS and the YubiKey, we need to add the following lines to the gpg-agent
configuration file located in ~/.gnupg/gpg-agent.conf
Create a new file and add the following lines with nano ~/.gnupg/gpg-agent.conf
:
pinentry-program /opt/homebrew/bin/pinentry-mac
default-cache-ttl 3600
default-cache-ttl-ssh 3600
max-cache-ttl 7200
max-cache-ttl-ssh 7200
enable-ssh-support
We also need to update the shell environment to allow ssh
to use gpg-agent
as an authentication service.
(Note: the single quote ('
) and double quotes ("
) behave differently in shell/bash)
echo 'export GPG_TTY=$(tty)' >> ~/.zshrc
echo 'export SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh' >> ~/.zshrc
Close all your current terminal windows and restart the Terminal application.
Restart the gpg-agent
service and update its settings:
gpg-connect-agent killagent /bye
gpg-connect-agent updatestartuptty /bye
gpg-connect-agent /bye
The 3 lines above are incredibly helpful becase gpg
is a bit unstable in macOS and you might need to restart it from time to time. I recommend you register this alias:
echo "alias gpgreset='gpg-connect-agent killagent /bye; gpg-connect-agent updatestartuptty /bye; gpg-connect-agent /bye'" >> ~/.zshrc
This way, whenever you have any funkiness with your cards and your ssh sessions, you can simply write gpgreset
and retry. That will fix the issues most of the time.
Finally, insert your YubiKey in a USB port and check if it is being correctly detected by running the command:
gpg --card-status
You should see the details of your YubiKey (card) in the console. Take note of the Serial Number of the card, it might be of use later in the setup.
Troubleshooting
If you cannot see the details of your card or you are getting other errors, first try a gpgreset
and if that doesn't fix it, then carefully re-read this guide.
If you are getting this specific error:
gpg: selecting card failed: Operation not supported by device
gpg: OpenPGP card not available: Operation not supported by device
Try to add the following line to the file ~/.gnupg/scdaemon.conf
:
disable-ccid
2. YubiKey configuration
Please follow my previous guide (from section 2 onwards) to initialize your YubiKey in case it's new, and to generate its key pairs to be used with ssh.