Multiple SSH Keys for an Azure CLI generated Linux VM
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
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
At the end of my build script I echo out the ssh command:
ssh -o StrictHostKeyChecking=no dave@davetest420.westeurope.cloudapp.azure.com
Username
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!
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
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
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!