How to add network interfaces

[since version 1.6.0]

Multipass can launch instances with additional network interfaces, via the --network option. That is complemented by the networks command, to find available host networks to bridge with.

This is supported only for images with cloud-init support for Version 2 network config, which in turn requires netplan to be installed (inside the instance). So, from 17.10 and core 16 onward, except for snapcraft:core16. And then only in the following scenarios:

  • on Linux, with LXD
  • on Windows, with both Hyper-V and VirtualBox
  • on macOS, with both QEMU and VirtualBox

Contents:

Network specification

The --network option can be given multiple times, each one requesting an additional network interface (beyond the default one, which is always present). Each use takes an argument specifying the properties of the desired interface:

  • name — the only required value, it identifies the host network to connect the instance’s device to (see networks for possible values)
  • mode — either auto (the default) or manual; with auto, the instance will attempt automatic network configuration
  • mac — a custom MAC address to use for the device

These properties can be specified in the format <key>=<value>,…. but a simpler form with only <name> is available for the most common use-case. Here is an example:

$ multipass launch --network en0 --network name=bridge0,mode=manual
Launched: upbeat-whipsnake

$ multipass exec upbeat-whipsnake -- ip -br address show scope global
enp0s3           UP             10.0.2.15/24
enp0s8           UP             192.168.1.146/24
enp0s9           DOWN

$ ping -c1 192.168.1.146  # elsewhere in the same network
PING 192.168.1.146 (192.168.1.146): 56 data bytes
64 bytes from 192.168.1.146: icmp_seq=0 ttl=64 time=0.378 ms
[...]

In the example above, we got the following interfaces inside the instance:

  • enp0s3 — the default interface, that the instance can use to reach the outside world and which Multipass uses to communicate with the instance;
  • enp0s8 — the interface that is connected to en0 on the host and which is automatically configured;
  • enp0s9 — the interface that is connected to bridge0 on the host, ready for manual configuration.

Routing

Extra interfaces are configured with a higher metric (200) than the default one (100). So, by default the instance will only route through them if they’re a better match for the destination IP:

$ multipass exec upbeat-whipsnake -- ip route
default via 10.0.2.2 dev enp0s3 proto dhcp src 10.0.2.15 metric 100
default via 192.168.1.1 dev enp0s8 proto dhcp src 192.168.1.146 metric 200
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15
10.0.2.2 dev enp0s3 proto dhcp scope link src 10.0.2.15 metric 100
192.168.1.0/24 dev enp0s8 proto kernel scope link src 192.168.1.146
192.168.1.1 dev enp0s8 proto dhcp scope link src 192.168.1.146 metric 200

$ multipass exec upbeat-whipsnake -- ip route get 91.189.88.181
91.189.88.181 via 10.0.2.2 dev enp0s3 src 10.0.2.15 uid 1000
    cache

$ multipass exec upbeat-whipsnake -- ip route get 192.168.1.13
192.168.1.13 dev enp0s8 src 192.168.1.146 uid 1000
    cache

Bridging


Connecting to a host network is done by creating a bridge to it. Although we will not get into details in this document, it is important to remark that each platform has a different behavior under the hood that Multipass hides. However, there are some differences between platforms.

WiFi

When bridging a new MAC address is generated. Unfortunately, most access points will reject packets with a MAC address different to that used for authentication. macOS solves this problem at low level, but it is not possible to bridge WiFi networks on Linux and Windows at the moment. That is the reason why some of the network adapters are not listed in multipass networks.

Bridging request


On Linux and Windows, when trying to connect an instance network to an Ethernet device on the host, Multipass will offer to create the required bridge:
$ multipass networks
Name             Type      Description
eth0             ethernet  Ethernet device
lxdbr0           bridge    Network bridge
mpbr0            bridge    Network bridge for Multipass
virbr0           bridge    Network bridge

$ multipass launch --network eth0
Multipass needs to create a bridge to connect to eth0.
This will temporarily disrupt connectivity on that interface.

Do you want to continue (yes/no)?

On Linux, Multipass requires NetworkManager to achieve this. On installations that do not have NetworkManager installed (e.g. Ubuntu Server), the user can still create a bridge by other means and pass that to Multipass. For instance, this configuration snippet achieves that with netplan:

bridges:
    mybridge:
        dhcp4: true
        interfaces:
            - eth0

That goes somewhere in /etc/netplan/ (e.g. /etc/netplan/50-custom.yaml). After a successful netplan try or netplan apply, Multipass will show the new bridge with the networks command and instances can be connected to it:

multipass launch --network mybridge

Another option is to install NetworkManager, but other network handlers need to be deactivated to avoid conflicts and make the new bridges permanent.

Specifying a default interface


[since version 1.7.0]

In case the same interface needs to be used many times across successive launchs, a shortcut can be used, via the settings interface. For example, to use the interface eth0 as default bridging interface, it must be specified with:

multipass set local.bridged-network=eth0

Then, the default can be used at launch with

multipass launch --bridged

or

multipass launch --network bridged

These two commands are exactly the same as multipass launch --network name=eth0.

3 Likes

I’m excited about --network option. My setup is Windows 10 machine with Hyper-V enabled. Currently, whenever I start a VM using Multipass it attaches to a private network, and when I change that to an external network I cannot open the shell again. When will version 1.6.0 be released? Do I have to wait for the release or is there another way to accomplish changing the default network?

Thank you for your efforts,
Burak

I’ve played with the rc on Windows 10 Pro a bit.

I love where this is going, but I noticed two things that need to be addressed in documentation.

  1. When adding network interfaces using the new option, this is ON TOP OF the always implicitly created default interface. The documentation does not clarify this. E.g. when adding two interfaces with --network, the VM ends up with three interfaces, like in the example. It’s easy to overlook in the example, so adding a sentence explaining that the default interface is always there implicitly is worth the effort.

  2. I know how to pass a user-data.yml for cloud-init. How do I pass the network configuration which in cloud-init goes into a separate file? I see two improvement options here:

a) add more key=value properties to --network to allow for specifying what goes into netplan for manual config, with multipass generating the network config file for cloud-init from that.

b) add an additional command line option to multipass that allows to pass the cloud-init network config file.

Did I miss anything?

thanks for all the work on this, it’s getting more useful release by release.

Tobias

Hi @polarapfel, thanks for the feedback. I have added a sentence to emphasize that the “additional network interfaces” are added on top of the default one.

As for the special network configurations, there is a balance to be struck between how much functionality we provide and simplicity of use, which is one of the features we aim for with Multipass. That said, we offer a way for manual network configuration that you can use to customize to your liking (e.g. via netplan inside). We’re also tracking a couple of issues related to this.

I’m not clear if one can add additional network interfaces after the instance has been created?

Further, I’m missing detailed instructions on how to do a “manual configuration” for an interface.

  • enp0s9 — the interface that is connected to bridge0 on the host, ready for manual configuration.
1 Like

Hi @thomasberger2001,

I’m not clear if one can add additional network interfaces after the instance has been created?

At the moment, Multipass does not allow adding network interfaces to created instances.

Further, I’m missing detailed instructions on how to do a “manual configuration” for an interface.

With “manual configuration”, we mean that the interface was not configured automatically at initialization. You will need to set it up from inside the instance. For that, you can use for instance netplan in the instance.

1 Like

I realize this topic is a little old, but it answers a couple questions I had that were unclear in the multipass docs. For that, a big thank you! I’d suggest adding the information in the latter part of your tutorial to the multipass docs.

One question @ricab. When editing the netplan yaml file, is that done within the multipass instance or within the host? I would assume the latter, but wasn’t too certain.

Hi @tenkaravt, thanks for the feedback! This was part of the documentation in the past, but got replaced during a big documentation rework. The contents were relocated here. If you find there is anything missing/incorrect in that newer version, please let us know.

And you are right, that netplan example applies to hosts that have that tool instead of NetworkManager (e.g. Ubuntu Server). That file could be used on those hosts to create a bridge “manually”. If you have NetworkManager, Multipass tries to create the bridge itself.

Hi @ricab … I have been hovering around the issue these past days… and seeing you in various places… so I wanted to ask about my comment here:

https://github.com/canonical/multipass/issues/309#issuecomment-1503982062

it seems that on my Ventura Mac OS M1 when I use the --network XX flag to bridge over, all of the VMs that I see from the outside have the same MAC address. my router is giving them all different IP addresses, which is fine, but I can’t use the “IP reservation” tooling without different MAC addresses. it doesn’t seem to matter if I pass in the mac=xxxx… the VM’s mac gets set, but from outside my host they all look the same (see .112 and .115 below in the screenshot). am I doing something wrong?

I’m attempting to change to static IP for now so I can get the ports forwarded… but I’m no expert at any of this stuff

Screenshot 2023-04-12 at 12.59.55

Hey @franceschina, I had replied on the issue you linked and just added a new comment there, to try to keep the discussion in one place.