DEV Community

Dr. Gernot Starke for arc42

Posted on • Edited on

Enable ssh access to multipass vms

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 command multipass 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).

Enter fullscreen mode Exit fullscreen mode

Permission denied, although there is a route to this virtual machine available...

Different approaches

Two approaches have been documented elsewhere:

  1. 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...
  2. 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):

  1. Create new ssh-key for your multipass VMs
  2. Create a reusable launch configuration for multipass VMs with cloud-init
  3. Launch new multipass VMs with this configuration
  4. Find out IP-address of new multipass VM
  5. 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
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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> 
Enter fullscreen mode Exit fullscreen mode
  • The <content of YOUR public key> starts with the letters ssh-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 with ssh-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
Enter fullscreen mode Exit fullscreen mode
  • 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:         --
Enter fullscreen mode Exit fullscreen mode
  • 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

Enter fullscreen mode Exit fullscreen mode
  • 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)

Collapse
 
corysus profile image
Almir • Edited

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.

Collapse
 
gernotstarke profile image
Dr. Gernot Starke

thanx for this helpful "abbreviation" :-)

Collapse
 
jovylle profile image
Jovylle B

This here is a lot quicker.

Collapse
 
itnet7 profile image
Chris Crisafulli

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.

Collapse
 
gernotstarke profile image
Dr. Gernot Starke

hhm - actually I meant "naive" in the sense of "overly simple".

Collapse
 
rfiedler profile image
Rafael Fernando Fiedler

Simple :

nano /etc/ssh/sshd_config.d/60-cloudimg-settings.conf

Change to: PasswordAuthentication Yes

Save File

service ssh restart

Voilá !

Collapse
 
josuebustos profile image
Josue Bustos

Hi Gernot,

This is great!

I didn't know this method existed when I first learned about Multipass!

Thanks for the kudos too!

Collapse
 
gayan_ranasinghe_7e437c89 profile image
gayan ranasinghe

This is the only method that worked which allowed me to ssh in to multipass VMs
Thanks a lot & Much Appreciated