The problem
- You are using multipass to create lightweight virtual (Ubuntu) machines.
You want to
ssh
into those machines, because you cannot or don't want to use the standard shell commandmultipass shell <name-of-vm>
.The naive approach fails with
permission denied
:
$ ssh 192.168.205.7
The authenticity of host '192.168.205.7 (192.168.205.7)' can't be established.
ED25519 key fingerprint is SHA256:lWKUbxxxx.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.205.7' (ED25519) to the list of known hosts.
gernotstarke@192.168.205.7: Permission denied (publickey).
Permission denied, although there is a route to this virtual machine available...
Different approaches
Two approaches have been documented elsewhere:
- Add an ssh-key to an existing virtual machine (explained by Josue Bustos here). Downside of this approach: You have to repeat it (more or less manually) for all new VMs you create with
multipass launch
. Therefore, let's look at a solution that will also work for new VMs... - Pass an ssh-key while creating a multipass VM (explained in detail by Ivan Krizsan here). In short: You generate a new ssh-key, and pass the public key into every new VM. I summarize the required steps below.
The solution
(I mention it again, the idea presented here have first been described by Ivan Krizsan):
- Create new ssh-key for your multipass VMs
- Create a reusable launch configuration for multipass VMs with cloud-init
- Launch new multipass VMs with this configuration
- Find out IP-address of new multipass VM
- ssh into the new VM with this IP-address
Prerequisites: You have:
- multipass installed. If not, it's well-documented on their website.
- a terminal running a decent shell (bash, zsh).
- a decent text editor (VS-Code, nano, vim or the like.)
1.: Create ssh-key
On your host machine (the one with multipass installed), change to the directory from where you will be launching multipass vms. It can be your home directory, but any other will do.
$ ssh-keygen -C vmuser -f multipass-ssh-key
-
vmuser
can be any (dummy) username, it will later be used to log into the VM. - The parameter to
-f
is the filename for the generated key. You can choose a name of your liking, but there must not be an existing key with the same name in the same directory.
You will be asked to enter a passphrase, leave that empty! I know, it's not as secure as it should be, but multipass VMs are used for development and test only...
Empty passphrases are NOT suited for production environments.
2.: Create cloud-init configuration
Cloud-init is the standardized approach for cross-platform cloud and VM configuration of instance initialization.
Multipass can handle such configuration, we use it to pass the ssh key into the vm.
In the directory where you generated the ssh-key, execute the following:
$ touch cloud-init.yaml
$ code cloud-init.yaml
You can obviously use any text editor of your choice. Nowadays I use VS-Code for most of my edits.
Put the following content into this file:
users:
- default
- name: vmuser
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- <content of YOUR public key>
- The
<content of YOUR public key>
starts with the lettersssh-rsa
and ends with the username you supplied in step 1. Both have to be included! - Remember, it's yaml: Sensitive to spaces and dashes.
- In case you generated an
ed25519
type of key, it starts withssh-ed25519
. If you don't know what I'm talking about, ignore this last line.
3.: Launch multipass VM with ssh configuration
You will use a slightly different launch command for your VM, by adding the cloud-init parameter:
$ multipass launch -n testvm --cloud-init cloud-init.yaml
-
testvm
is the name of your new vm, you can choose any name or even leave it blank. In the latter case, multipass will create a random name for you. -
cloud-init.yaml
is the name of the configuration file we created in step 2.
4.: Find IP address of new VM
$ multipass info testvm
Name: testvm
State: Running
IPv4: 192.168.205.4
Release: Ubuntu 20.04.4 LTS
Image hash: 692406940d6a (Ubuntu 20.04 LTS)
Load: 0.00 0.00 0.00
Disk usage: 1.5G out of 4.7G
Memory usage: 140.5M out of 976.9M
Mounts: --
-
testvm
is the name of the VM you were using in step 3 (launch VM). - The output of the info command contains the IPv4 address of this VM, you need that in the next step.
5.: ssh into new VM
$ ssh vmuser@192.168.205.4 -i multipass-ssh-key -o StrictHostKeyChecking=no
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-122-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
-
vmuser
is the username for which you created the ssh key - Please replace the IP address by the one you found out in step 4.
And voilá - you made it.
The command itself should be obvious... you pass the name of the ssh-key with the -i
commend (short for identity). In addition, you turn strict host checking off.
You might see additional messages, depending on your host machine ssh configuration - but you should be logged in your multipass VM by now.
May the power of the shell be with you.
Acknowledgements
Thanx to Ivan Krizsan) for providing the initial solution and his nice writeup. I took me a while to cut through numerous web-searches to find his post, therefore I decided to write it up again under a slightly different title.
All credits and kudos to him! All faults a clearly mine.
Top comments (8)
You can also enable password login to multipass vm:
Login to your multipass VM
Create user
sudo adduser YOUR_USERNAME
Add user to sudos
sudo usermod -aG sudo YOUR_USERNAME
Enable password login
sudo nano /etc/ssh/sshd_config
find and change PasswordAuthentication no to PasswordAuthentication yes
SSH to your VM using user and password
ssh YOUR_USERNAME@IP_OF_VM
By doing this, you can always SSH to your VM using multipass shell YOUR_VM, but also with the username and password that you created. This can be useful when you need to use your VM with other services like CI/CD.
P.S. I added this comment in case someone needs a quick and clean solution for this.
thanx for this helpful "abbreviation" :-)
This here is a lot quicker.
Small typo in The Problem: 3rd bullet. Naive should be changed to native. Thanks for sharing this, I learned a lot as I've been playing more and more with cloud-init and just stumbled on multipass.
hhm - actually I meant "naive" in the sense of "overly simple".
Simple :
nano /etc/ssh/sshd_config.d/60-cloudimg-settings.conf
Change to:
PasswordAuthentication Yes
Save File
service ssh restart
Voilá !
Hi Gernot,
This is great!
I didn't know this method existed when I first learned about Multipass!
Thanks for the kudos too!
This is the only method that worked which allowed me to ssh in to multipass VMs
Thanks a lot & Much Appreciated