# How to Configure Multiple VM Backends in CAPEv2: KVM, VirtualBox, and VMware

> Learn to configure multiple VM backends including KVM VirtualBox and VMware in CAPEv2. Effortlessly switch hypervisors by setting machinery to multi and defining VM tags for efficient task routing.

- Repository: [Kevin O'Reilly/capev2](https://github.com/kevoreilly/capev2)
- Tags: how-to-guide
- Published: 2026-03-05

---

**CAPEv2 uses a pluggable "machinery" architecture that lets you run KVM, VirtualBox, and VMware simultaneously by setting `machinery = multi` in [`cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/cuckoo.conf) and defining per-VM tags to route tasks to the correct hypervisor.**

The open-source malware analysis sandbox CAPEv2 (kevoreilly/capev2) abstracts hypervisor interactions through a dedicated machinery layer. Whether you are migrating from a single-backend setup or building a heterogeneous lab with mixed hypervisors, understanding how to configure multiple VM backends in CAPEv2 allows you to leverage the strengths of each platform—such as KVM’s performance, VirtualBox’s snapshot flexibility, or VMware’s enterprise management—within a single analysis cluster.

## Understanding CAPEv2's Machinery Architecture

CAPEv2 implements each hypervisor as a standalone Python module under `modules/machinery/`. The core orchestrator, [`lib/cuckoo/core/machinery_manager.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/core/machinery_manager.py), loads the selected backend at runtime based on the `machinery` key in [`cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/cuckoo.conf).

Each machinery module exposes a consistent API for starting, stopping, and reverting VMs, but reads hypervisor-specific settings from its own configuration file:

- **KVM/QEMU**: [`modules/machinery/kvm.py`](https://github.com/kevoreilly/capev2/blob/main/modules/machinery/kvm.py) → `conf/default/kvm.conf.default`
- **VirtualBox**: [`modules/machinery/virtualbox.py`](https://github.com/kevoreilly/capev2/blob/main/modules/machinery/virtualbox.py) → `conf/default/virtualbox.conf.default`
- **VMware**: [`modules/machinery/vmware.py`](https://github.com/kevoreilly/capev2/blob/main/modules/machinery/vmware.py) → `conf/default/vmware.conf.default`

## Selecting a Single VM Backend

To use only one hypervisor, set the `machinery` value in the `[cuckoo]` section of `conf/default/cuckoo.conf.default` (or your custom copy in [`custom/conf/cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/custom/conf/cuckoo.conf)):

```ini
[cuckoo]
machinery = kvm

```

Valid options are `kvm`, `virtualbox`, or `vmware`. When the CAPE scheduler starts, `MachineryManager` instantiates the corresponding class from `modules/machinery/<name>.py` and routes all tasks to that backend.

## Configuring Multiple VM Backends Simultaneously

CAPEv2 ships with a pseudo-machinery called **`multi`** that enables concurrent operation of several hypervisors. This is the recommended approach when you need to configure multiple VM backends in CAPEv2—such as running 64-bit samples on KVM while isolating 32-bit legacy malware in VirtualBox.

Activate the multi-backend mode by setting:

```ini

# custom/conf/cuckoo.conf

[cuckoo]
machinery = multi

[multi]
machinery = kvm, virtualbox, vmware

```

The `multi` module ([`modules/machinery/multi.py`](https://github.com/kevoreilly/capev2/blob/main/modules/machinery/multi.py)) parses the comma-separated list and loads each specified machinery in order. When a task arrives, it queries each backend for an available VM whose **tags** match the task requirements, selecting the first suitable candidate.

## Defining VM Sections and Tags for Backend Selection

Each hypervisor configuration file contains machine-specific sections that map CAPE labels to actual VM instances. To enable intelligent routing when using the `multi` machinery, you must define **`tags`** in each VM section.

### KVM Configuration Example

```ini

# custom/conf/kvm.conf

[win10_kvm]
platform = windows
arch = x64
tags = win10, x64, office
machines = win10_kvm
interface = virbr0
snapshot = clean_snapshot

```

### VirtualBox Configuration Example

```ini

# custom/conf/virtualbox.conf

[win7_vbox]
platform = windows
arch = x86
tags = win7, x86, legacy
name = Win7_Analysis_VM
snapshot = base_snapshot

```

### VMware Configuration Example

```ini

# custom/conf/vmware.conf

[win10_vmware]
platform = windows
arch = x64
tags = win10, x64, vmware
host = 192.168.0.50
port = 443
username = admin
password = secret
vmx_path = "/vmfs/volumes/datastore1/Win10/Win10.vmx"
snapshot = clean

```

When a task is submitted with specific tags—such as `win10,x64`—the `multi` machinery iterates through KVM, VirtualBox, and VMware in the order defined in [`cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/cuckoo.conf), selecting the first available VM whose tags are a superset of the requested tags.

## Runtime Backend Selection Process

Understanding the internal flow helps troubleshoot multi-backend deployments:

1. **Task Submission**: The web UI or API ([`utils/submit.py`](https://github.com/kevoreilly/capev2/blob/main/utils/submit.py)) receives a sample and optional `--tags` argument.
2. **Scheduler Evaluation**: [`lib/cuckoo/core/machinery_manager.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/core/machinery_manager.py) loads the configured machinery class. If `machinery = multi`, it instantiates [`modules/machinery/multi.py`](https://github.com/kevoreilly/capev2/blob/main/modules/machinery/multi.py).
3. **Machine Selection**: The `Multi` class's `prepare_task_and_machine_to_start()` method loops through the comma-separated machinery list (e.g., `kvm, virtualbox, vmware`). For each backend, it calls `availables()` to find VMs whose tags match the task requirements.
4. **VM Startup**: Once a match is found, the selected machinery's `start(label)` method boots the VM, reverts to the specified snapshot, and injects the CAPE agent.

Enable `debug = on` in [`cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/cuckoo.conf) to trace this selection logic in `cuckoo.log`.

## Summary

- CAPEv2 abstracts hypervisors through **machinery modules** located in `modules/machinery/`.
- Set `machinery = kvm`, `virtualbox`, or `vmware` in [`cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/cuckoo.conf) to use a single backend.
- Set `machinery = multi` and list multiple backends in the `[multi]` section to run **KVM, VirtualBox, and VMware simultaneously**.
- Use **tags** in per-VM configuration files ([`kvm.conf`](https://github.com/kevoreilly/capev2/blob/main/kvm.conf), [`virtualbox.conf`](https://github.com/kevoreilly/capev2/blob/main/virtualbox.conf), [`vmware.conf`](https://github.com/kevoreilly/capev2/blob/main/vmware.conf)) to route tasks to specific hypervisors based on architecture or OS requirements.
- The `MachineryManager` in [`lib/cuckoo/core/machinery_manager.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/core/machinery_manager.py) orchestrates runtime selection, logging all decisions to `cuckoo.log`.

## Frequently Asked Questions

### How do I switch from KVM to VirtualBox without reinstalling CAPEv2?

Change the `machinery` value in your [`custom/conf/cuckoo.conf`](https://github.com/kevoreilly/capev2/blob/main/custom/conf/cuckoo.conf) from `kvm` to `virtualbox`, then copy `conf/default/virtualbox.conf.default` to [`custom/conf/virtualbox.conf`](https://github.com/kevoreilly/capev2/blob/main/custom/conf/virtualbox.conf) and define your VM sections. Restart the CAPE service with `systemctl restart cape`. No reinstallation is required because CAPEv2 loads machinery modules dynamically at startup.

### Can I run KVM and VirtualBox on the same physical host simultaneously?

Yes, but with caveats. KVM requires hardware virtualization extensions (Intel VT-x/AMD-V) and loads kernel modules that may conflict with VirtualBox's kernel driver. You can unload the KVM kernel modules (`rmmod kvm_intel kvm`) before starting VirtualBox VMs, or use the `multi` machinery to keep both configured but ensure only one hypervisor's VMs are active at any given time. For production stability, dedicate separate analysis hosts to each hypervisor.

### What happens if no VM tags match the submitted sample's requirements?

If the `multi` machinery cannot find a VM whose tags satisfy the task requirements, the task enters a **pending** state and retries periodically. The scheduler logs the mismatch in `cuckoo.log` with details about the requested tags. To resolve this, ensure your VM definitions include the necessary tags (e.g., `win10`, `x64`, `office`) or submit the sample without specific tags to allow any available VM to be selected.

### Where does CAPEv2 store the machinery configuration after I edit the default files?

CAPEv2 uses a layered configuration system. Default templates reside in `conf/default/`. To persist your changes across upgrades, copy the relevant `.default` files to `custom/conf/` (creating the directory if necessary) and edit them there. The loader in [`lib/cuckoo/core/startup.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/core/startup.py) prioritizes `custom/conf/` over `conf/default/`, ensuring your machinery settings for KVM, VirtualBox, or VMware remain intact when you pull new CAPEv2 versions.