alt text

An SSH Key (public/private key pair) is the preferred way to connect to a Linux VM. The benefits are:

  • Don’t need a password
  • Can use an alias eg ssh blc
  • More secure as can’t brute force

MS Documentation

Here are my build scripts for spinning up a Linux VM, deploying a web app and updating DNS, which inspired me to learn about SSH.

Manually Generate Keys

It is good practise to have separate keys for each machine you connect from

Quite often you’ll have generated keys from something else, however if you don’t then:

ssh-keygen -m PEM -t rsa -b 4096

Then look in ~/.ssh or c:\Users\djhma\.ssh where the id_rsa.pub is the public key

Azure CLI generate-ssh-keys

A handy way to create or use existing ssh keys when creating a new vm on Azure:

az vm create --name davetest110 --resource-group rg --generate-ssh-keys

## connect to VM
ssh dave@davetest110.westeurope.cloudapp.azure.com

## connect to the VM ignoring initial do you trust prompt
ssh -o StrictHostKeyChecking=no dave@davetest110.westeurope.cloudapp.azure.com

Inside WSL which I run my bash Azure CLI scripts from, this will create or use keys inside ~/.ssh

  • id_rsa.pub - public key
  • id_rsa - private key

StrictHostKeyChecking

Command is useful to ignore the fingerprint check and add the host to the known_hosts file in ~/.ssh

alt text

At the end of my build script I echo out the ssh command:

alt text

ssh -o StrictHostKeyChecking=no dave@davetest420.westeurope.cloudapp.azure.com

Username

alt text

I used the above to figure out the username dave to connect with. This is the username of the WSL user on my Windows machine.

Connect from Multiple Machines to the VM

I use 3 machines to develop on on a regular basis:

  • Work desktop machine
  • Home laptop
  • Home desktop machine

So do I share the public/private keys among these 3 machines to connect to my Azure Linux VM’s? No!

It is better to create separate public/private keys for each of the 3 host machines and let the newly created servers know about the 3 machines

az vm create \
    --resource-group ${rg} \
    --name ${vmname} \
    --location ${region} \
    --nics ${nicName} \
    --image ${image} \
    --ssh-key-values sshkey-work.pub sshkey-homelenovo.pub  \
    --custom-data cloud-init.txt \
    --size Standard_B1ms

Above I am passing multiple public keys via the CLI. This is what gave me a the clue and the Microsoft docs here

As an example the sshkey-work.pub file is

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkOmk7KC89RMQQJ2nnbhTHdbrixtgU7MAvKNjWZPU2MPwmJU1sSdNuIZjdfxA13bZyZ4GaHih9O3zD8gsnIzmer3G3dWRV2AfIWPmUzujmB+yEFIGne/PHb/cnkyYnEhxd5ra4sjYmtL8u+FiP1cnuyn9x4byrdY1OUi4H14uVHAVOeBz050IIaeNodJViRm8RL4w1CFiFj80+3FkDR1IrccWI6MZXCwtq3jd1PwjeEGlW8I3xpA7xgaTO5wwUTVYUwLEoYAq+22pQAl7QXGmHqLh4+IVgNv9MSK69MXDEcIGdj/iypYIeZindZI7lQvQ/TUf5BS3Y8Q1FY0i8mfzR

Connect from Windows

The above works fine connecting from WSL but I like to connect from Windows too

  • Windows uses c:\users\djhma\.ssh\id_rsa
  • WSL uses ~/.ssh/id_rsa

So how do we share the key between WSL and Windows? Florian has a good solution and a good explanation of permissions on SuperUser

I couldn’t get this to work, so a simple workaround is to copy the keys from WSL to Windows side:

 cp ~/.ssh/* /mnt/c/Users/djhma/.ssh/

Warning: Unprotected Private Key File

If you get this error after copying keys from WSL to Windows

alt text

Give minimum permissions to get rid of the error. More information

Config file for an Alias

In a new text file called config c:\Users\djhma\.ssh\config I have this alias setup:

Host blc
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    User dave
    HostName hmsoftware.uk

Strangely after installing a newer version of Git for Windows this file was deleted, so I recreated it fine.

Notice here I’m linking to a domain name which my build script updates the DNS record automatically.

With more detail here on not adding the key to known hosts

alt text

You may have to set permissions on this file as above, then simply type:

ssh blc

Conclusion

I use SSH keys like this all the time. Thanks to @tbbuck who finally made me dig into this and figure it out. Nice!