Enable ssh access to multipass vms
Tags: cloud, vm, ubuntu
Published: 2022-08-01 15:03:00


#### The problem

- You are using [multipass](https://multpass.run) 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`:

```nohighlight
$ 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:

1. Add an ssh-key to an existing virtual machine (explained by [Josue Bustos here](https://dev.to/josuebustos/vs-code-remote-ssh-multipass-dn8)). 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](https://www.ivankrizsan.se/2020/12/23/multipass-key-based-authentication/)). 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](https://www.ivankrizsan.se/2020/12/23/multipass-key-based-authentication/)):

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](https://multipass.run/install).
- 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.

```bash
$ 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](https://cloudinit.readthedocs.io/en/latest/) 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:

```nohighlight
$ 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:

```yaml
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 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:

```bash
$ 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

```nohighlight
$ 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

```nohighlight
$ 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](https://www.ivankrizsan.se/2020/12/23/multipass-key-based-authentication/)) 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.