Managing networks VirtualBox inside LXC

Hello,

My use case is for a Molecule pipeline (Ansible) that will create my test platform with Vagrant/VirtualBox. It works well with the default configuration of VB networks for a standalone instance, but not in the case where I want to test a DBMS replication or a NoSQL cluster on several nodes: the network communication with the default IP does not pass, it is an isolated network. So I try to activate the private_network but it seems that VirtualBox lacks any authorization allowing it to create the vboxnetX network card.

Do you have an idea ?

My error:

root@lxd-host:~# lxc shell c1
root@c1:~# cd ~/vagrant/d11/Vagrantfile && vagrant up
Bringing machine 'debian11-vbox1' up with 'virtualbox' provider...
Bringing machine 'debian11-vbox2' up with 'virtualbox' provider...
Bringing machine 'debian11-vbox3' up with 'virtualbox' provider...
==> debian11-vbox1: Checking if box 'bento/debian-11' version '202206.03.0' is up to date...
==> debian11-vbox1: Clearing any previously set network interfaces...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["hostonlyif", "ipconfig", "vboxnet1", "--ip", "192.168.56.1", "--netmask", "255.255.255.0"]

Stderr: VBoxManage: error: The host network interface named 'vboxnet1' could not be found
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component HostWrap, interface IHost, callee nsISupports
VBoxManage: error: Context: "FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam())" at line 232 of file VBoxManageHostonly.cpp

and manually:

root@lxd-host:~# lxc exec c1 -- VBoxManage list hostonlyifs
root@lxd-host:~# 
root@lxd-host:~# lxc exec c1 -- VBoxManage hostonlyif create
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interface 'vboxnet2' was successfully created

root@lxd-host:~# lxc exec c1 -- VBoxManage hostonlyif create
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interface 'vboxnet3' was successfully created

root@lxd-host:~# lxc exec c1 -- VBoxManage list hostonlyifs
root@lxd-host:~# 

root@lxd-host:~# lxc exec c1 -- VBoxManage hostonlyif ipconfig vboxnet1
VBoxManage: error: The host network interface named 'vboxnet1' could not be found
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component HostWrap, interface IHost, callee nsISupports
VBoxManage: error: Context: "FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam())" at line 232 of file VBoxManageHostonly.cpp

root@lxd-host:~# lxc exec c1 -- VBoxManage hostonlyif ipconfig vboxnet2
VBoxManage: error: The host network interface named 'vboxnet2' could not be found
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component HostWrap, interface IHost, callee nsISupports
VBoxManage: error: Context: "FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam())" at line 232 of file VBoxManageHostonly.cpp

root@lxd-host:~# lxc exec c1 -- VBoxManage hostonlyif ipconfig vboxnet3
VBoxManage: error: The host network interface named 'vboxnet3' could not be found
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component HostWrap, interface IHost, callee nsISupports
VBoxManage: error: Context: "FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam())" at line 232 of file VBoxManageHostonly.cpp

Through the container, the /dev/vboxnetctl driver is used to create the vboxnetX network cards and this creates them not in the container but on the host … How to have them in the container?

root@lxd-host:~# ip a
----8<----8<----8<----8<----8<----8<----8<----8<----8<----
55: vboxnet0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:00 brd ff:ff:ff:ff:ff:ff
56: vboxnet1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:01 brd ff:ff:ff:ff:ff:ff
57: vboxnet2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:02 brd ff:ff:ff:ff:ff:ff
58: vboxnet3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:03 brd ff:ff:ff:ff:ff:ff


root@lxd-host:~# VBoxManage list hostonlyifs
Name:            vboxnet0
GUID:            786f6276-656e-4074-8000-0a0027000000
DHCP:            Disabled
IPAddress:       192.168.56.1
NetworkMask:     255.255.255.0
IPV6Address:     
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:00
MediumType:      Ethernet
Wireless:        No
Status:          Down
VBoxNetworkName: HostInterfaceNetworking-vboxnet0

Name:            vboxnet1
GUID:            786f6276-656e-4174-8000-0a0027000001
DHCP:            Disabled
IPAddress:       192.168.57.1
NetworkMask:     255.255.255.0
IPV6Address:     
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:01
MediumType:      Ethernet
Wireless:        No
Status:          Down
VBoxNetworkName: HostInterfaceNetworking-vboxnet1

Name:            vboxnet2
GUID:            786f6276-656e-4274-8000-0a0027000002
DHCP:            Disabled
IPAddress:       192.168.58.1
NetworkMask:     255.255.255.0
IPV6Address:     
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:02
MediumType:      Ethernet
Wireless:        No
Status:          Down
VBoxNetworkName: HostInterfaceNetworking-vboxnet2

Name:            vboxnet3
GUID:            786f6276-656e-4374-8000-0a0027000003
DHCP:            Disabled
IPAddress:       192.168.59.1
NetworkMask:     255.255.255.0
IPV6Address:     
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:03
MediumType:      Ethernet
Wireless:        No
Status:          Down
VBoxNetworkName: HostInterfaceNetworking-vboxnet3

Reference documentation: Networking - VirtualBox Provider | Vagrant by HashiCorp

My setup:

root@lxd-host:~# lsb_release -ds
Ubuntu 20.04.4 LTS
root@lxd-host:~# uname -a
Linux lxd-host 5.13.0-41-generic #46~20.04.1-Ubuntu SMP Wed Apr 20 13:16:21 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
root@lxd-host:~# lxd version
5.2
root@lxd-host:~# dpkg -l | grep virtualbox
ii  virtualbox                            6.1.32-dfsg-1~ubuntu1.20.04.1         amd64        x86 virtualization solution - base binaries
ii  virtualbox-dkms                       6.1.32-dfsg-1~ubuntu1.20.04.1         amd64        x86 virtualization solution - kernel module sources for dkms
ii  virtualbox-ext-pack                   6.1.32-1~ubuntu1.20.04.1              all          extra capabilities for VirtualBox, downloader.
ii  virtualbox-guest-additions-iso        6.1.32-1~ubuntu1.20.04.1              all          guest additions iso image for VirtualBox
ii  virtualbox-guest-dkms-hwe             6.1.32-dfsg-2~ubuntu1.20.04.1         all          x86 virtualization solution - guest addition module source for dkms
ii  virtualbox-guest-utils-hwe            6.1.32-dfsg-2~ubuntu1.20.04.1         amd64        x86 virtualization solution - non-X11 guest utilities

root@lxd-host:~# lxc exec c1 -- dpkg -l | grep -E 'virtualbox|vagrant'
ii  ruby-vagrant-cloud                   3.0.5-1                                 all          Vagrant Cloud API Library
ii  vagrant                              2.2.19+dfsg-1ubuntu1                    all          Tool for building and distributing virtualized development environments
ii  virtualbox                           6.1.32-dfsg-1build1                     amd64        x86 virtualization solution - base binaries
ii  virtualbox-dkms                      6.1.32-dfsg-1build1                     amd64        x86 virtualization solution - kernel module sources for dkms
ii  virtualbox-ext-pack                  6.1.32-1                                all          extra capabilities for VirtualBox, downloader.


root@lxd-host:~# lxc exec c1 -- VBoxManage list extpacks
Extension Packs: 2
Pack no. 0:   Oracle VM VirtualBox Extension Pack
Version:      6.1.32
Revision:     149290
Edition:      
Description:  Oracle Cloud Infrastructure integration, USB 2.0 and USB 3.0 Host Controller, Host Webcam, VirtualBox RDP, PXE ROM, Disk Encryption, NVMe.
VRDE Module:  VBoxVRDP
Usable:       true 
Why unusable: 

Pack no. 1:   VNC
Version:      6.1.32
Revision:     149290
Edition:      
Description:  VNC plugin module
VRDE Module:  VBoxVNC
Usable:       true 
Why unusable:
root@lxd-host:~# lxc config show c1
architecture: x86_64
config:
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20220607_07:42)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20220607_07:42"
  image.type: squashfs
  image.variant: cloud
  volatile.base_image: c178ca6f9098a2389fbb65c27f1b9247a297ea4567593a2b96088e6a2961f64b
  volatile.cloud-init.instance-id: c6cb215d-f818-45d1-ba71-512a6f50fc98
  volatile.eth0.host_name: vethfefee49e
  volatile.eth0.hwaddr: 00:16:3e:8c:3c:d8
  volatile.idmap.base: "0"
  volatile.idmap.current: '[]'
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
  volatile.uuid: 44913f27-f523-4edb-a2e8-6085c2bc5980
devices: {}
ephemeral: false
profiles:
- default
- gitlab-runner
stateful: false
description: ""
root@lxd-host:~# lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: default
root@lxd-host:~# lxc profile show gitlab-runner
config:
  limits.memory.swap: "false"
  linux.kernel_modules: ip_tables,ip6_tables,netlink_diag,nf_nat,overlay,br_netfilter
  raw.lxc: |
    lxc.apparmor.profile=unconfined
    lxc.mount.auto=proc:rw sys:rw
    lxc.cap.drop=
    lxc.cgroup.devices.allow=a
  security.nesting: "true"
  security.privileged: "true"
  security.protection.delete: "true"
  security.syscalls.intercept.mknod: "true"
  security.syscalls.intercept.setxattr: "true"
  user.network-config: |
    version: 1
    config:
      - type: physical
        name: eth0
        subnets:
           - type: manual
             control: auto
      - type: bridge
        name: br0
        subnets:
           - type: dhcp
             control: auto
        bridge_interfaces:
          - eth0
        params:
          bridge_stp: 'off'
          bridge_fd: 1
  user.user-data: |
    #cloud-config
    runcmd:
    - dhclient eth0
    - ip addr flush eth0
    - ifup -a
    - echo 'blacklist kvm-intel' >> /etc/modprobe.d/blacklist.conf
    
    - DEBIAN_FRONTEND=noninteractive apt -yqq update
    - DEBIAN_FRONTEND=noninteractive apt install -yqq --no-install-recommends bridge-utils qemu-kvm curl sudo kmod gawk ca-certificates gnupg gnupg-agent apt-transport-https software-properties-common lsb-release cpu-checker snapd

    - echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs) main restricted universe multiverse" > /etc/apt/sources.list
    - echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs)-updates main restricted universe multiverse" >> /etc/apt/sources.list
    - echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs)-backports main restricted universe multiverse" >> /etc/apt/sources.list
    - echo "deb http://security.ubuntu.com/ubuntu $(lsb_release -cs)-security main restricted universe multiverse" >> /etc/apt/sources.list

    - curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
    - curl -fsSL https://apt.releases.hashicorp.com/gpg | gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list
    - chmod -c a+r /usr/share/keyrings/*.{gpg,asc}

    - DEBIAN_FRONTEND=noninteractive apt -yqq update
    - echo virtualbox-ext-pack virtualbox-ext-pack/license select true | sudo debconf-set-selections
    - DEBIAN_FRONTEND=noninteractive apt install -yqq --no-install-recommends virtualbox virtualbox-ext-pack vagrant  gitlab-runner virt-what bridge-utils virtinst qemu-utils libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev ruby-libvirt make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev ssl-cert
    - snap install lxd
    - printenv PATH | grep -qE "/snap/bin($|:)" || export PATH="/snap/bin:${PATH}"
    - echo 'Y29uZmlnOiB7fQpuZXR3b3JrczoKLSBjb25maWc6CiAgICBpcHY0LmFkZHJlc3M6IDEwLjE3NS4yNC4xLzI0CiAgICBpcHY0Lm5hdDogInRydWUiCiAgICBpcHY2LmFkZHJlc3M6IG5vbmUKICBkZXNjcmlwdGlvbjogIiIKICBuYW1lOiBseGRicjAKICB0eXBlOiBicmlkZ2UKICBwcm9qZWN0OiBkZWZhdWx0CnN0b3JhZ2VfcG9vbHM6Ci0gY29uZmlnOgogICAgc291cmNlOiAvdmFyL3NuYXAvbHhkL2NvbW1vbi9seGQvc3RvcmFnZS1wb29scy9kZWZhdWx0CiAgZGVzY3JpcHRpb246ICIiCiAgbmFtZTogZGVmYXVsdAogIGRyaXZlcjogZGlyCnByb2ZpbGVzOgotIGNvbmZpZzoge30KICBkZXNjcmlwdGlvbjogRGVmYXVsdCBMWEQgcHJvZmlsZQogIGRldmljZXM6CiAgICBldGgwOgogICAgICBuYW1lOiBldGgwCiAgICAgIG5ldHdvcms6IGx4ZGJyMAogICAgICB0eXBlOiBuaWMKICAgIHJvb3Q6CiAgICAgIHBhdGg6IC8KICAgICAgcG9vbDogZGVmYXVsdAogICAgICB0eXBlOiBkaXNrCiAgbmFtZTogZGVmYXVsdApwcm9qZWN0czoKLSBjb25maWc6CiAgICBmZWF0dXJlcy5pbWFnZXM6ICJ0cnVlIgogICAgZmVhdHVyZXMubmV0d29ya3M6ICJ0cnVlIgogICAgZmVhdHVyZXMucHJvZmlsZXM6ICJ0cnVlIgogICAgZmVhdHVyZXMuc3RvcmFnZS52b2x1bWVzOiAidHJ1ZSIKICBkZXNjcmlwdGlvbjogRGVmYXVsdCBMWEQgcHJvamVjdAogIG5hbWU6IGRlZmF1bHQ=' | base64 -d | lxd init --preseed

    - usermod -aG kvm,lxd,ssl-cert,vboxsf,vboxusers gitlab-runner
    - DEBIAN_FRONTEND=noninteractive apt -yqq upgrade
    - systemctl reboot
description: Profile supporting gitlab-runner in containers
devices:
  aadisable:
    path: /sys/module/apparmor/parameters/enabled
    source: /dev/null
    type: unix-char
  aadisable2:
    source: /dev/kmsg
    type: unix-char
  kvm:
    source: /dev/kvm
    type: unix-char
  vboxdrv:
    source: /dev/vboxdrv
    type: unix-char
  vboxdrvu:
    source: /dev/vboxdrvu
    type: unix-char
  vboxnetctl:
    source: /dev/vboxnetctl
    type: unix-char
  vhost-net:
    source: /dev/vhost-net
    type: unix-char
  vhost-vsock:
    source: /dev/vhost-vsock
    type: unix-char
name: gitlab-runner
root@lxd-host:~# lxc exec c1 -- cat /root/vagrant/d11/Vagrantfile
Vagrant.configure('2') do |config|
  if Vagrant.has_plugin?('vagrant-cachier')
    config.cache.scope = 'machine'
  end

  config.vm.define "debian11-vbox1" do |c|
    ##
    # Box definition
    ##
    c.vm.box = "bento/debian-11"

    ##
    # Config options
    ##
    c.vm.synced_folder ".", "/vagrant", disabled: true
    c.ssh.insert_key = true
    c.vm.hostname = "debian11-vbox1"

    ##
    # instance_raw_config_args
    ##
    c.vm.network 'private_network', type: 'dhcp'

    ##
    # Provider
    ##
    c.vm.provider "virtualbox" do |virtualbox, override|
      virtualbox.memory = 512
      virtualbox.cpus = 1
      virtualbox.linked_clone = true
    end
  end

  config.vm.define "debian11-vbox2" do |c|
    ##
    # Box definition
    ##
    c.vm.box = "bento/debian-11"

    ##
    # Config options
    ##
    c.vm.synced_folder ".", "/vagrant", disabled: true
    c.ssh.insert_key = true
    c.vm.hostname = "debian11-vbox2"

    ##
    # instance_raw_config_args
    ##
    c.vm.network 'private_network', type: 'dhcp'

    ##
    # Provider
    ##
    c.vm.provider "virtualbox" do |virtualbox, override|
      virtualbox.memory = 512
      virtualbox.cpus = 1
      virtualbox.linked_clone = true
    end
  end

  config.vm.define "debian11-vbox3" do |c|
    ##
    # Box definition
    ##
    c.vm.box = "bento/debian-11"

    ##
    # Config options
    ##
    c.vm.synced_folder ".", "/vagrant", disabled: true
    c.ssh.insert_key = true
    c.vm.hostname = "debian11-vbox3"

    ##
    # instance_raw_config_args
    ##
    c.vm.network 'private_network', type: 'dhcp'

    ##
    # Provider
    ##
    c.vm.provider "virtualbox" do |virtualbox, override|
      virtualbox.memory = 512
      virtualbox.cpus = 1
      virtualbox.linked_clone = true
    end
  end
end

In the meantime, my workaround is to go under Vagrant/Libvirt where there is not this network problem: the ephemeral VMs can communicate with each other inside LXC.