SSH with security keys

This tutorial covers how to connect to a Ubuntu 20.04 LTS VM using OpenSSH with security keys on Compute Engine. Security keys provide an extra layer of security that can help reduce the impact of attacks.

Support for the FIDO2/U2F protocol that is needed by U2F security keys was introduced in OpenSSH 8.2.

To use security keys on Compute Engine, both your local client and VM must support OpenSSH 8.2 or later.

SSH with security keys overview

To generate SSH keys that are linked to a security key, use the ssh-keygen command with the -t ecdsa-sk flag. This command creates a public key, private key, and a U2F key handle (or FIDO2 credential ID). These items are stored as follows:

  • The private key is stored on the security key.
  • The key handle and public key are stored locally in the traditional SSH key files. The key handle can be optionally encrypted with a passphrase.

After the SSH key is generated, you configure your user account to use the generated SSH public key.

Then, you can SSH to the VM. If the VM accepts one of your ecdsa-sk keys, your client prompts you to touch your security key to verify the connection.

Objectives

This tutorial shows how to complete the following steps:

  1. Create a VM. On Compute Engine, Ubuntu 20.04 contains the latest OpenSSH 8.2 installation which can be used to verify a security key. This tutorial uses a VM that runs on Ubuntu 20.04.
  2. On a client, install OpenSSH 8.2 and generate SSH public keys. This tutorial uses a client that runs on Ubuntu 16.04.
  3. Add the generated SSH public key to the VM.
  4. Connect to the VM from the client by using OpenSSH with security keys.

Costs

This tutorial uses billable components of Google Cloud including Compute Engine.

You can estimate your daily or monthly costs by using the pricing calculator.

New Google Cloud users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. In the Google Cloud Console, on the project selector page, select or create a Google Cloud project.

    Go to the project selector page

  3. Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.

  4. Learn how to use Cloud Shell to run gcloud command-line tool commands.
  5. On your client, install or update to the latest version of the gcloud command-line tool.
  6. Optional: Set a default region and zone.

Set up the VM

  1. In the Google Cloud Console, go to Cloud Shell.

    Go to Cloud Shell

  2. Create a VM using the latest Ubuntu 20.04 LTS image. Also enable OS Login on the VM. OS Login is used to manage access to the VM.

    To create this VM, run the following command:

    gcloud compute instances create VM_NAME \
       --project PROJECT_ID \
       --zone ZONE \
       --image-family ubuntu-2004-lts \
       --image-project ubuntu-os-cloud \
       --metadata enable-oslogin=true
    

    Replace the following:

    • VM_NAME: the name of the VM.
    • PROJECT_ID: your project ID.
    • ZONE: the zone that you want to create the VM in.
  3. Generate keys for the VM. When you connect to a VM using the gcloud compute ssh command, Compute Engine automatically generates an RSA SSH key pair for the VM.

    gcloud compute ssh VM_NAME
    

    Replace VM_NAME with the name of your VM.

Set up local workstation (client)

A local workstation or client is the device used to connect to the cloud network.

The following instructions are for local workstations that are running Ubuntu operating systems only.

  1. On your local Ubuntu workstation, install OpenSSH 8.2. Currently, the best option is to compile from source because OpenSSH 8.2 is not yet available for all distributions. To compile from source, on your Ubuntu workstation, complete the following steps:

    1. Install dependencies.

      sudo apt update
      sudo apt install build-essential
      sudo apt-add-repository ppa:yubico/stable
      sudo apt update
      sudo apt install libz-dev libcurl4-openssl-dev libssl-dev libcbor-dev libfido2-dev
    2. Setup a working directory.

      mkdir openssh-8
      cd openssh-8
    3. Download the Openssh 8.2 package.

      wget http://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.2p1.tar.gz
      tar xvzf openssh-8.2p1.tar.gz
      cd openssh-8.2p1
      
    4. Install OpenSSH 8.2 with security key support.

      ./configure --with-security-key-builtin
      make
      sudo make install
    5. Verify the install.

      ssh -V

      The output should resemble the following.

      OpenSSH_8.2p1, OpenSSL 1.0.2g  1 Mar 2016
    6. Run the ssh-keygen command with the -t ecdsa-sk flag.

      The output should resemble the following.

      Generating public/private ecdsa-sk key pair.
      You may need to touch your authenticator to authorize key generation.
      Key enrollment failed: device not found
      
    7. To allow your local workstation to access the FIDO device, setup a udev rule. This udev rule is used by libfido2-dev to allow communication between your security key and the local workstation.

      To setup access, complete the following steps:

      1. Create a rules file.

        touch /etc/udev/rules.d/50-fidodev.rules
      2. Add the access rules for your security key type to the rules file. For a list of access rules by secuity key type, see Yubico libu2f-host repository.

        For example, if you are using a Yubico Yubikey, add the following content to the file.

        #udev rule for enabling HID access to Yubico devices for FIDO support.
        
        KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
         MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050" # 1050 is Yubico's vendor ID.
        
      3. For the new rule to take effect, reload udev.

        sudo udevadm control --reload
  2. Plug the security key into the local workstation.

  3. Run the ssh-keygen command with the -t ecdsa-sk flag.

    ssh-keygen -t ecdsa-sk

    The output should resemble the following.

    Generating public/private ecdsa-sk key pair.
    You may need to touch your authenticator to authorize key generation.Enter file in which to save the key (/home/$USER/.ssh/id_ecdsa_sk):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/$USER/.ssh/id_ecdsa_sk
    Your public key has been saved in /home/$USER/.ssh/id_ecdsa_sk.pub
    The key fingerprint is:
    SHA256:esvq6KPZ5FGttkaYUUeUcf/Oo0hhsRAaB6NKN48kkeo ubuntu-17-02-2020-4432343
    The key's randomart image is:
    +-[ECDSA-SK 256]--+
    |  ..  ++*o.      |
    |  .. ..=oo .     |
    | .o =.... . .    |
    |.. =.+ . . o .   |
    |. . .+o S +   .  |
    | E  o..o . . o   |
    |    o.+ . .   +  |
    |   =.+.+ o . . . |
    |  oo=++.o . .    |
    +----[SHA256]-----+
    
  4. On your local workstation, install or update to the latest version of the gcloud command-line tool.

  5. Use the gcloud command-line tool to configure the security key for use by your VMs. OS Login is enabled on the VM, so you can use the gcloud compute os-login ssh-keys add command to configure the public SSH keys.

    gcloud compute os-login ssh-keys add \
        --project PROJECT_ID \
        --key-file /home/$USER/.ssh/id_ecdsa_sk.pub
    

    Replace PROJECT_ID with your project ID.

    For more information, see Adding SSH keys to a user account.

Connect to the VM

You can now connect to the VM from your local workstation using OpenSSH with security keys.

To connect, run the following command:

gcloud compute ssh VM_NAME --ssh-key-file=/home/$USER/.ssh/id_ecdsa_sk

# Prompt for user to touch security key
Confirm user presence for key ECDSA-SK SHA256:...
Welcome to Ubuntu Focal Fossa...

Replace VM_NAME with the name of your VM.

If your setup was successfully completed, when you SSH, you are prompted to authenticate access by touching your security key. The VM then verifies the key and grants access.

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

  1. In the Google Cloud Console, go to Cloud Shell.

    Go to Cloud Shell

  2. Delete the VM:

    gcloud compute instances delete VM_NAME \
       --project PROJECT_ID \
       --zone ZONE

    Replace the following:

    • VM_NAME: the name of the VM.
    • PROJECT_ID: your project ID.
    • ZONE: the zone that you want to create the VM in.

What's next