Using a hardware key for better security

From HPCwiki
Revision as of 12:39, 3 March 2026 by Haars0011 (talk | contribs)
Jump to navigation Jump to search

Employees can get a Yubikey hardware key for free at the servicedesk in Forum.

With that key, you can implement multifactor authentication for your SSH connections.

Depending on you choices and setup, you can make it very secure, so that without the key, pin and password your SSH key won't be able to be used.

The steps below are adaptations of https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html

Different levels of security/annoyance

There are different levels of security you can apply, each being more secure, but also introducing an extra step before you have an active session.

There a three "interactions" that can be used:

  1. Enforce/use a password to unlock your SSH key
  2. Enforce/use a PIN to unlock the hardware key
  3. Enforce/use touching the hardware key to get access


This then leads to the following 4 scenarios:

  1. Use SSH key password, pin and touch for each new SSH session (no SSH agent)
  2. Use pin and touch for each new SSH session (use SSH agent for password)
  3. Use touch for each new SSH session (use SSH agent for password, but no PIN enforcement in key)
  4. Use SSH key password and touch for first SSH session (pass in SSH agent, no PIN and touch enforcement in key)

The last one is the least intrusive, and as an attacker would need physical access to your device to circumvent your security, this is probably fine for most people.

This is thus the scenario that we'll describe below in detail.

For scenario 1 & 2, add -O verify-required to the ssh-keygen command to enforce PIN enforcement in key.

For scenarios 1, 2 & 3, do not add -O no-touch-required to the ssh-keygen command to enforce touch enforcement in key.

Linux

Create your key:

(do this on your laptop or desktop)

ssh-keygen -t ed25519-sk -O resident -O no-touch-required -O application=ssh:anunna.wur.nl -C "[Your comment to identify this key on the server]"

The options are:

  • -t ed25519-sk : Type of key, this is the more secure option
  • -O resident : Store the SSH key on your hardware key, makes it easier to use on another machine
  • -O no-touch-required : No need to touch the hardware key every time
  • -O application=ssh:anunna.wur.nl : identifier for the key on your hardware key
  • -C "[Your comment to identify this key on the server]" : identifier for the key on the server

An example exchange looks like this:

haars001@L0160372:~ % ssh-keygen -t ed25519-sk -O resident -O no-touch-required -O application=ssh:anunna.wur.nl -C "jan.vanhaarst@wur.nl"
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter PIN for authenticator:
You may need to touch your authenticator again to authorize key generation.
Enter file in which to save the key (/Users/haars001/.ssh/id_ed25519_sk):
Enter passphrase for "/Users/haars001/.ssh/id_ed25519_sk" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/haars001/.ssh/id_ed25519_sk
Your public key has been saved in /Users/haars001/.ssh/id_ed25519_sk.pub

Copy your key:

To be able to log in, the server will have to have the public part of your key.

For that, copy the contents of your public key, in my case /Users/haars001/.ssh/id_ed25519_sk.pub to $HOME/.ssh/authorized_keys

To allow touchless entry, we'll need to tell the SSH daemon to allow that:

# Copy over key
ssh login.anunna.wur.nl "umask 0077; mkdir -p ~/.ssh; echo 'no-touch-required $(cat ~/.ssh/id_ed25519_sk.pub)' >> ~/.ssh/authorized_keys"
# Check for key
ssh login.anunna.wur.nl 'tail -1 .ssh/authorized_keys'

MacOS

For MacOS, we can mostly do the same as for Linux, except that we will have to install openssh, as the default SSH stack doesn't work with hardware keys.

So:

brew install openssh

Besides that, you will have to add this snippet to your .zshrc file, otherwise the default ssh-agent will be used:

# Use Homebrew's ssh-agent instead of Apple's
if [ -z "$SSH_AGENT_PID" ] || ! ps -p "$SSH_AGENT_PID" > /dev/null 2>&1; then
    # Kill Apple's agent
    pkill -u $USER /usr/bin/ssh-agent 2>/dev/null
    # Start Homebrew's
    eval "$($(brew --prefix openssh)/bin/ssh-agent -s)"
fi

After this, open a new terminal , and follow the Linux flow.

Windows

(needs to be filled by a Windows user)