Use SSH certificates with Azure

In this tutorial, you will learn how-to log in to Linux virtual machines in Azure using certificate-based SSH authentication over suSSHi with SSH agent forwarding.

Requirements

We expect that you have successfully deployed a Linux virtual machine in Azure, based on this Microsoft article for example. Of course, a valid suSSHi user and an access rule must also exist. The profile used in the access rule must include SSH Auth Agent Forwarding as the preferred authentication method, since the SSH certificates issued by Azure exist only on the client side.

In a nutshell, the steps are:

  1. Generate a SSH RSA key pair (optional).

  2. Request a SSH certificate (sign your RSA public key).

  3. Start an SSH agent and add your SSH RSA private key.

  4. Connect to the Linux virtual machine in Azure.

  5. Renew the SSH certificate (optional).

Note

At the time of writing, Azure only supports SSH RSA key pairs.

1. Generate a SSH RSA key pair (optional)

For the following, we use an (existing) suSSHi user named wasabi and his (existing) SSH RSA key pair ~/.ssh/id_rsa_wasabi / ~/.ssh/id_rsa_wasabi.pub. We skip the optional first step because we assume that you are familiar with creating a SSH RSA public key pair. In order to simplify the setup, the wasabi user’s public key is also used for authentication at the suSSHi Gateway.

2. Request a SSH certificate (sign your RSA public key)

Next, we request an SSH certificate from Azure for the SSH RSA public key by using the Azure CLI command line tool az:

bash-5.1# az ssh cert --public-key-file ~/.ssh/id_rsa_wasabi.pub --file ~/.ssh/id_rsa_wasabi-cert.pub
~/.ssh/id_rsa_wasabi-cert.pub

As a result, we have a short-living SSH certificate stored under ~/.ssh/id_rsa_wasabi-cert.pub.

Note

We have explicitly defined the name of the SSH certificate using the --file option. Otherwise, SSH certificates generated with az are stored with a file name (<identity>-aadcert.pub) not recognized by the SSH agent and thus not added to the SSH agent.

The details of the SSH certificate can be displayed using ssh-keygen:

bash-5.1# ssh-keygen -L -f ~/.ssh/id_rsa_wasabi-cert.pub
~/.ssh/id_rsa_wasabi-cert.pub:
      Type: ssh-rsa-cert-v01@openssh.com user certificate
      Public key: RSA-CERT SHA256:niY1MNkAiW5NyOn742p9Ieevz5A9/+kXhVMnZyZUmmo
      Signing CA: RSA SHA256:A8RmMxka1+ucbhZSD48Y0rsmSwOI7pYiiny9zj5UTng (using rsa-sha2-256)
      Key ID: "c6f2fb23-da77-4459-89b9-b692cf94a5bf@626a0e6e-fdb7-4b99-b894-e53f423e5537"
      Serial: 0
      Valid: from 2021-10-29T08:56:25 to 2021-10-29T10:01:25
      Principals:
              developer@susshi.org
      Critical Options: (none)
      Extensions:
              displayname@sshservice.azure.net UNKNOWN OPTION: 00000010446576656c6f70657220737553534869 (len 20)
              oid@sshservice.azure.net UNKNOWN OPTION: 0000002463366632666232332d646137372d343435392d383962392d623639326366393461356266 (len 40)
              permit-X11-forwarding
              permit-agent-forwarding
              permit-port-forwarding
              permit-pty
              permit-user-rc
              tid@sshservice.azure.net UNKNOWN OPTION: 0000002436323661306536652d666462372d346239392d623839342d653533663432336535353337 (len 40)

3. Start an SSH agent and add your SSH RSA private key

We now check if the SSH agent is running, otherwise we fire up an instance:

bash-5.1# eval $(ssh-agent)
Agent pid 119

Next, we add the SSH RSA private key to the SSH agent:

bash-5.1# ssh-add ~/.ssh/id_rsa_wasabi
Identity added: /root/.ssh/id_rsa_wasabi (root@14d8675e3ec5)
Certificate added: /root/.ssh/id_rsa_wasabi-cert.pub (c6f2fb23-da77-4459-89b9-b692cf94a5bf@626a0e6e-fdb7-4b99-b894-e53f423e5537)

Note

Because we followed the naming convention for SSH certificates (<identity>-cert.pub), the certificate is automatically added to the SSH agent (see man ssh-add).

For the sake of completeness, here is the username and the public IP address of the Azure test VM we used in this example:

bash-5.1# az account show --query user.name --output tsv
developer@susshi.org
bash-5.1# az vm show -d -g AzureADLinuxVMPreview -n myVM --query publicIps -o tsv
13.94.136.195

Note

Please note the @ character in the Azure username developer@susshi.org. For this reason, we have to choose a different character as the separator for the suSSHi username string (e.g. %).

4. Connect to the Linux virtual machine in Azure

Finally, we connect to the Azure VM using the standard ssh command.

bash-5.1# ssh -A -l wasabi%developer@susshi.org%13.94.136.195 docker.for.mac.localhost
The authenticity of host '[docker.for.mac.localhost]:22 ([192.168.65.2]:22)' can't be established.
ED25519 key fingerprint is SHA256:qyiLsoWbIgplwN3k2jPBqasaUoBGSVxfOVhnH8+bT34.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[docker.for.mac.localhost]:22' (ED25519) to the list of known hosts.
Welcome to suSSHi2 Gateway
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1062-azure x86_64)
(...)
developer@susshi.org@myVM:~$

Note

We explicitly enable agent forwarding using the -A option, which is required for this setup.

5. Renew the SSH certificate (optional)

At the time of writing, Azure issues short-living certificates (validity about 1 hour, see certificate details above), so periodic renewal is required. After the certificate has expired, the old one should be removed from the SSH agent first:

ssh-add -d ~/.ssh/<identity>

Afterwards, a new certificate can be requested by simply using the same commands as before:

az ssh cert --public-key-file ~/.ssh/<identity>.pub --file ~/.ssh/<identity>-cert.pub
ssh-add ~/.ssh/<identity>
ssh -A -l <gateway_user>%<target_user>%<target> <susshi_gateway>