Skip to content

QEMU / KVM

For any KVM-based host, ARROW ships a QCOW2 image. It is the native QEMU format and runs unchanged across raw QEMU, KVM, libvirt/virt-manager, and Proxmox VE, so pick whichever of the three workflows below matches how you run VMs.


Install QEMU and KVM for your distribution:

Terminal window
# Debian/Ubuntu
sudo apt install qemu-system-x86 qemu-utils libvirt-daemon-system
# Fedora/RHEL
sudo dnf install qemu-kvm qemu-img libvirt
# Arch
sudo pacman -S qemu-full libvirt

Confirm hardware virtualization is available before you go further, since without it the VM will be unusably slow:

Terminal window
kvm-ok
# or
ls /dev/kvm
Terminal window
qemu-system-x86_64 \
-enable-kvm \
-m 16G \
-smp 4 \
-cpu host \
-bios /usr/share/ovmf/OVMF.fd \
-drive file=kali-arrow-client.qcow2,format=qcow2,if=virtio \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-device virtio-net-pci,netdev=net0 \
-device virtio-vga \
-display gtk

The flags that matter most: -enable-kvm gives you hardware acceleration (leave it off and the VM crawls), -bios OVMF.fd boots the image under the UEFI firmware it expects, and hostfwd=tcp::2222-:22 forwards host port 2222 to the VM’s SSH port so you can reach it. -m and -smp set RAM and cores, and -cpu host passes your CPU features through.

On a server with no display, drop the graphics and put the serial console on your terminal:

Terminal window
qemu-system-x86_64 \
-enable-kvm \
-m 16G \
-smp 4 \
-cpu host \
-bios /usr/share/ovmf/OVMF.fd \
-drive file=kali-arrow-client.qcow2,format=qcow2,if=virtio \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-device virtio-net-pci,netdev=net0 \
-nographic \
-serial mon:stdio

Then SSH in over the forwarded port:

Terminal window
ssh -p 2222 [email protected]

If you drive VMs through virt-manager, import the disk directly:

  1. Open virt-manager and click Create a new virtual machine.
  2. Choose Import existing disk image and browse to the .qcow2 file.
  3. Set the OS type to Linux > Debian 12 (or Generic Linux).
  4. Allocate resources: 16384 MB of memory and 4 CPUs is a good default.
  5. Configure networking (default NAT, or select a bridge).
  6. Check Customize configuration before install.
  7. In the configuration window, under Overview > Firmware, select UEFI x86_64: /usr/share/OVMF/OVMF_CODE.fd. This step is the one people miss, and skipping it leaves you at a UEFI shell.
  8. Click Begin Installation.

For sizing, 2 vCPU and 8 GB is the floor, 4 vCPU and 16 GB is comfortable, and 8 vCPU and 32 GB is for heavier work. Keep both the disk bus and network on virtio.


Copy the QCOW2 to the Proxmox host:

Terminal window
scp kali-arrow-client.qcow2 root@proxmox-host:/var/lib/vz/images/

Create the VM shell with a UEFI (ovmf) BIOS and a q35 machine type, then import and attach the disk. Adjust the VMID (200 here) to something free on your host:

Terminal window
qm create 200 \
--name kali-arrow-client \
--memory 16384 \
--cores 4 \
--bios ovmf \
--machine q35 \
--net0 virtio,bridge=vmbr0 \
--ostype l26 \
--agent enabled=1
# Add EFI disk
qm set 200 --efidisk0 local-lvm:1,format=qcow2
# Import the disk
qm importdisk 200 kali-arrow-client.qcow2 local-lvm
# Attach the imported disk and set boot order
qm set 200 --scsi0 local-lvm:vm-200-disk-1 \
--scsihw virtio-scsi-single \
--boot order=scsi0

From the Proxmox web UI, select the VM, click Start, and open the Console. Or from the CLI:

Terminal window
qm start 200

“KVM not available”. Hardware virtualization is off. Enable VT-x or AMD-V in your BIOS, then confirm with kvm-ok or ls /dev/kvm.

The VM boots to a UEFI shell. The UEFI firmware was not specified. Point the VM at OVMF, and install the ovmf package if it is missing.

No network inside the VM. Confirm the interface is virtio-net and that your host bridge or NAT is configured correctly.

Disk performance is slow. Use if=virtio for the disk and keep the image in QCOW2 format.

Proxmox import fails. The target storage may not support QCOW2. Import as raw instead with qm importdisk 200 image.qcow2 local-lvm --format raw.

The password does not work. Credentials are generated at build time. Retrieve them from the ARROW Portal on your device’s details page.