Multipass Key-Based Authentication

By | December 23, 2020
Multipass and Cloud Init logos.
Copyright by Canonical Ltd.
Licensed under the Creative Commons Attribution-Share Alike 3.0 license.

In this article I will show how to create a Multipass virtual machine that has an additional user which can connect to the virtual machine authenticating using a private key. To accomplish this I will use cloud-init when creating the virtual machine. The cause for this is to allow creation and provisioning of Multipass virtual machines using tools like Ansible.

Prerequisites

In order to be able to create Multipass virtual machines, you will need to have Multipass installed.

The public and private keys used in the example in this article will be generated using ssh-keygen, though any tool that produce an equivalent result, such as for example PuTTYgen for Windows, Linux or Mac, may be used.

Generate Keys

I will settle for generating a key-pair using the default public key algorithm and key-size. If you have different requirements, please refer to the ssh-keygen documentation on how to customize key-pair creation.

  • Open a terminal window.
  • Navigate to a desired directory or create a new directory and navigate to it.
  • Create a key-pair using the following command, where vmadmin is the name of the user for which the key-pair is generated and user_key is the name that will be used to create the two files in which the private and public keys will be stored:
ssh-keygen -C vmadmin -f user_key
  • When asked for a password and for a password confirmation, just press return.
    This in order to create a key-pair that does not require entering a password when logging in.

If the key creation was successful, there should be two files in the directory; one named “user_key” and one named “user_key.pub”. The former contain the private key and the latter contain the public key.

Cloud Init File

Before going on to create a Multipass virtual machine, I will configure a cloud-init file that will be used in the process.

  • In the same directory as the key-files, create a file named “cloud-init.yaml” with the following contents:
users:
  - default
  - name: vmadmin
    sudo:  ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - [insert content of public key file here]
  • Replace the “[insert content of public key file here]” with the contents of the user_key.pub file.

Note that:

  • There is a “- default” user entry.
    This entry ensures that the default (named “ubuntu” in Multipass) user is preserved when creating virtual machines with this cloud-init file.
  • The next entry is a user named “vmadmin”.
    This will cause a new user with the name vmadmin to be created in the virtual machine.
  • The sudo-configuration of the vmadmin user will allow the vmadmin user to use sudo without having to enter a password.
  • The ssh_authorized_keys set the authorized key for the vmadmin user to the public key generated earlier.
    This will allow the vmadmin user to connect to the virtual machine using ssh and the private key.
  • No default user is specified.
    A default user must not be specified, otherwise creating virtual machines using this cloud-init file will never complete and eventually time out, with an incomplete result. If no default user is specified, then the default user will be the ubuntu user which will allow for the creation of the virtual machine to complete and, later, for us to be able to connect to the virtual machine using ‘multipass shell’.

Create a Virtual Machine

With the cloud-init configuration file in place, a virtual machine can now be created using the command below. I will keep it simple for the sake of this article, but you are of course free to add whatever configuration parameters you wish.

multipass launch -n testvm --cloud-init cloud-init.yaml

The creation process may be somewhat lengthy, so please have patience.
If the creation of the virtual machine completed successfully, the following should be logged to the console:

Launched: testvm

SSH-ing Into the Virtual Machine

In order to be able to SSH into the virtual machine created earlier, its IP address is necessary. Find the IP address using, for instance, the following command:

multipass info testvm

Output similar to this should appear in the console:

Name:           testvm
State:          Running
IPv4:           192.168.64.20
Release:        Ubuntu 20.04.1 LTS
Image hash:     36403f956294 (Ubuntu 20.04 LTS)
Load:           0.02 0.20 0.14
Disk usage:     1.2G out of 4.7G
Memory usage:   127.4M out of 981.4M

Using the above IP address, I can now SSH into the virtual machine using the ssh command:

ssh vmadmin@192.168.64.20 -i user_key

If you haven’t connected to this virtual machine using ssh earlier, the above will issue a prompt asking you whether you want to continue or not. When automating, such a prompt may be undesirable and it can be bypassed adding an option to the ssh command:

ssh vmadmin@192.168.64.20 -o StrictHostKeyChecking=no -i user_key

You should not be prompted for a password.
This is of course less secure but good enough for my use case. There are other alternatives available but I will not go into further detail in this article.
Having successfully logged into the virtual machine, I see something like this being output to the console:

Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-54-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Dec 21 22:08:58 CET 2020

  System load:  0.0               Processes:               106
  Usage of /:   26.7% of 4.67GB   Users logged in:         0
  Memory usage: 18%               IPv4 address for enp0s2: 192.168.64.20
  Swap usage:   0%

The Ubuntu version 20.04.1 LTS is the current default version at the time of writing and will likely change over time. There is more output, but the above suffices to tell me that I have been successful in my endeavour.

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *