Best Practices: Using SSH keys to access Linux VMs on Azure

When deploying Linux workloads on Azure, Microsoft highly recommends using SSH keys since they provide a more secure way of logging on to a Linux instance using SSH than using normal passwords. Most of the time passwords can be cracked with for example a brute force attack whereas SSH keys are nearly impossible to decipher by brute force.

Generating SSH key pairs is easy and it will provide you two long string of characters which basically will mean a private key and a public key.

The public key is the one that you are going to place on any Linux server that you need access to and then the client that you are connecting from you will have your private key stored. In some cases or tasks (for example automation or moving data from one server to another) you might use a private key without a password set, that means that it won't ask for a password when the private key and the public key matches; however it is a best practice to add a password to it if you are going to be using them for interactive access.

Here we will show the required steps to generate an SSH (RSA) key pair and how to use it in Azure.

1) Create the SSH RSA key pair (You will need OpenSSL to be installed, these steps were tested on Mac and Linux):

ssh-keygen -t rsa

You will be asked for a couple of questions:

 Enter file in which to save the key (/home/<your-user-name>/.ssh/id_rsa):<br>You can press enter here, saving the file to the user home (in this case, the example user is called azureuser).<br>Enter passphrase (empty for no passphrase):<br>NOTE: If you DO NOT type a password, you will never need to type one when logging in to other hosts, it is a recommended security practice to use a password

All the steps together should look similar to this:

 ssh-keygen -t rsa<br>Generating public/private rsa key pair.<br>Enter file in which to save the key (/home/azureuser/.ssh/id_rsa):<br>Enter passphrase (empty for no passphrase):<br>Enter same passphrase again:<br>Your identification has been saved in /home/azureuser/.ssh/id_rsa.<br>Your public key has been saved in /home/azureuser/.ssh/id_rsa.pub.<br>The key fingerprint is:<br>4a:dd:0a:c6:35:4e:3f:ed:27:38:8c:74:44:4d:93:67 azureuser@a<br>The key's randomart image is:<br>+--[ RSA 2048]----+<br>|          .oo.   |<br>|         .  o.E  |<br>|        + .  o   |<br>|     . = = .     |<br>|      = S = .    |<br>|     o + = +     |<br>|      . o + o .  |<br>|           . o   |<br>|                 |<br>+-----------------+<br>The public key is now located in /home/azureuser/.ssh/id_rsa.pub The private key (identification) is now located in /home/azureuser/.ssh/id_rsa

2) Copying the public key

Once the key pair is created, it is time to place the public key on the Linux server that you want to use.

You can copy the public key into the new machine's authorized_keys file with the ssh-copy-id command.

Make sure to replace the example username and IP address below.
ssh-copy-id azureuser@192.168.1.2/

Alternatively, you can paste in the keys using SSH:
cat ~/.ssh/id_rsa.pub | ssh azureuser@192.168.1.2 "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"

No matter which command you chose, you should see something like:

 The authenticity of host '12.34.56.78 (12.34.56.78)' can't be established.<br>RSA key fingerprint is b1:2d:33:67:ce:35:4d:5f:f3:a8:cd:c0:c4:48:86:12.<br>Are you sure you want to continue connecting (yes/no)? yes<br>Warning: Permanently added '12.34.56.78' (RSA) to the list of known hosts.<br>azureuser@192.168.1.2's password: 

Now, try logging into the machine with "ssh 'azureuser@192.168.1.2'", and check in: ~/.ssh/authorized_keys to make sure you haven't added extra keys that you weren't expecting.

You can go ahead and log into azureuser@192.168.1.2 and you will be asked for a password which is the one that you set when creating the key pair, if you have not added a password you will login directly.

In the future when deploying Linux virtual machines on Azure you can then copy and paste the contents of your public key, in this example /home/azureuser/.ssh/id_rsa.pub on the portal when you choose the SSH Key option when creating a new virtual machine or you can also use the file when deploying using azure vm create , available in our Azure CLI tools by specifying the option -M.

Some useful tips when working with SSH keys

1) For OSX users:

If you are deploying virtual machines in Azure using public keys, you can just copy and paste the contents of your id_rsa.pub file, if you are using OSX, a good way of making this process easier and faster is by adding an alias that will automatically copy the contents of your public key so all you have to do when deploying from the portal is paste it, in this example I created an alias in my .bash_profile that is called azuressh:

alias azuressh="cat ~/.ssh/idrsa_rsa.pub | pbcopy

So every time I need my SSH public key I just open a terminal, type azuressh then I just hit COMMAND+V on the azure portal and get my key pasted in there.

2) Using the SSH "config" file:

A great way of customizing and making your SSH work for you is by using its config file, usually located under ~/.ssh

This is an example of a config file, it basically adds the ServerAliveInterval 60 to ALL hosts (*) that I connect to:
Host *
ServerAliveInterval 60

This other line, defines a host called "myhost" which I can connect just using "ssh myhost", with my own user defined, ssh key and hostname:
host myhost
Hostname myhostname.example.com
User admin
IdentityFile ~/.ssh/mypublickey_rsa

Other useful examples:

# Here I apply these settings to any host under the cloudapp.azure.com domain, meaning I always login with that user and key:
host *.cloudapp.azure.com
User myuser
IdentityFile ~/.ssh/mypublickey_rsa

# Here I apply a different SSH port automatically when connecting to this specific host
host securehost
Hostname www.myserver.com
User myuser
Port 50000
IdentifyFile ~/.ssh/mypublickey_rsa

For more details about available options, you can always read more at The Linux Documentation Project link.

References:
https://linux.die.net/man/1/ssh-keygen https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-mac-create-ssh-keys/