Securing SSH Authentication with FIDO2

Background and Scope

SSH (Secure Shell) is vital for secure remote connections over unsecured networks. Choosing a robust authentication mechanism is crucial. FIDO2 security keys introduce a strong, user-friendly option for SSH authentication, offering multi-factor authentication (MFA) via hardware tokens.

This guide provides instructions for integrating FIDO2 with SSH, focusing on resident keys (also known as passkeys). It covers client and server configuration, key generation, and usage across Linux, macOS, and Windows platforms, ensuring a secure and streamlined SSH authentication experience.

Prerequisites

  • OpenSSH 8.3 or newer

  • FIDO2 security key (with ed25519 support)

  • YubiKey Manager (for setting the FIDO2 PIN)

About Using FIDO2 Security Keys for SSH

Why use FIDO2?

  • Enhanced Security: The private key is securely generated and stored on the YubiKey and cannot be exported.

  • User Presence and Verification: Offers user verification via PIN and user presence through physical touch.

  • User Preference or Policy: Extends existing FIDO2 usage when a security key is also being used for web app and desktop sign in.

How FIDO2 works with SSH:

  • Credential Files:

    • Public key file (.pub) shared with the remote host.

    • Private key file in this case doesn’t actually contain the private key. Instead in contains a key handle (Credential ID) which references the private key on the security key.

Cryptographic Algorithm Options:

  • ecdsa-sk and ed25519-sk: Both are ECC-based algorithms, with ed25519-sk recommended for better security and performance.

SSH Key Generation Options:

  • resident: Store the key handle on the FIDO2 authenticator itself. A PIN should be set on the authenticator prior to generation.

  • verify-required: Indicates the private key should require user verification for each signature.

Configuring the SSH Client

Linux

  1. Insert the security key.

  2. Open a terminal.

  3. Generate the ssh credential files:

    ssh-keygen -t ed25519-sk -O resident -O verify-required -C "Your Comment"
    
  4. Enter the PIN and touch the key when prompted.

  5. Save the files (id_ed25519_sk and id_ed25519_sk.pub) in the ~/.ssh directory.

macOS

  1. Install OpenSSH via Homebrew:

    brew install openssh
    source ~/.profile
    
  2. Insert the security key.

  3. Open a terminal and generate the key:

    sudo ssh-keygen -t ed25519-sk -O resident -O verify-required -C "Your Comment"
    
  4. Enter the PIN and touch the key when prompted.

  5. Save the files in the ~/.ssh directory.

Windows 10/11

  1. Verify OpenSSH is installed. Get started with OpenSSH for Windows.

  2. Insert the security key.

  3. Open PowerShell (as administrator) and generate the key:

    ssh-keygen -t ed25519-sk -O resident -O verify-required -C "Your Comment"
    
  4. Enter the PIN and touch the key when prompted.

  5. Save the files in the ~/.ssh directory.

Configuring Additional SSH Clients

To use the security key on a new system:

  1. Insert the key and open a terminal.

  2. Change to the SSH directory:

    cd ~/.ssh
    
  3. Regenerate key files from the security key:

    ssh-keygen -K
    

Configuring the SSH Server

Update the SSH server to enforce user verification.

  1. Edit sshd_config:

    1. Open the file (usually at /etc/ssh/sshd_config).

    2. Add:

      PubkeyAuthOptions verify-required
      
.Save and exit.
  1. Restart SSH:

    sudo systemctl restart sshd
    

Example sshd_config to disable passwords altogether (optional, enhanced security):

# Support public key cryptography (includes FIDO2)
PubkeyAuthentication yes
# Enforce User Verification
PubkeyAuthOptions verify-required
# Public keys location
AuthorizedKeysFile .ssh/authorized_keys
# Allow root only with MFA
PermitRootLogin prohibit-password
# Disable password authentication
PasswordAuthentication no
PermitEmptyPasswords no

Sharing the Public Key

Using ssh-copy-id

  1. Open a terminal and use:

    ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub user@host
    

Manual Editing

  1. Copy the public key content.

  2. Log in to the server.

  3. Open the authorized_keys file:

    nano ~/.ssh/authorized_keys
    
  4. Paste the public key and save.

Using SSSD (Optional)

  • For centralized management, store public keys in LDAP (for instance Active Directory) using SSSD.

Using Multiple SSH Credentials

To generate multiple credentials on the same security key:

ssh-keygen -t ed25519-sk -O resident -O application=ssh:Description -C "Comment"

Replace Description with a unique identifier for each credential.

SSH to remote host using FIDO2

  1. . Open a terminal and use:

    ssh -T git@github.com
    
  2. Enter the PIN and touch the key when prompted.

Troubleshooting

Password Prompts Instead of YubiKey:

  • Restart or log out/in.

  • Verify OpenSSH version (ssh -V).

  • Check system logs for errors:

    • Ubuntu/Debian:

      tail /var/log/syslog | grep sshd
      
    • Fedora:

      journalctl -r /usr/sbin/sshd
      
  • Run SSH in debug mode:

    ssh -vvv user@host
    

Permission Issues:

  • Ensure correct file permissions:

    chmod 600 ~/.ssh/id_ed25519_sk
    

Unsure which security key holds the credential

Regenerate key files from the security key and compare public keys.

  1. Open a terminal and use:

    ssh-keygen -K
    
  2. Enter the PIN and touch the key when prompted.

  3. Compare the newly generated public key to the public key in question