Installing OpenBSD on a headless KVM machine

So you want to install OpenBSD in a KVM-based virtual machine on a headless Linux box? Here is a way that gives you access to the serial console from the get-go, and hence can be done purely from the command line, no GUI needed.

You'll need the following:

  • A amd64-based Linux box, with a working libvirt setup, i.e. a working virsh. Other architectures may work as well, but you'll (at least) need to adapt the OpenBSD bootloader configuration to the architecture.
  • I'll use virt-install command, in Debian included in the virtinst package, to install from the ISO. Installing from an ISO should also be possible by setting up the VM, also known as "domain" in libvirt parlance, appropriately, including its disk and network, and then booting it into the installation ISO. However, using virt-install makes this more convenient, allowing for installation in a single step.

The commands were run on a Debian 10 "Buster" amd64 system, which comes with the following relevant software:

  • libvirt 5.6.0 (packages libvirt-clients, libvirt-daemon, libvirt-daemon-system)
  • qemu 3.1 (package qemu-system-x86)

The first step is to obtain the OpenBSD installer ISO, and the release checksum and signature files:

% wget{install66.iso,SHA256,SHA256.sig}

Unfortunately, the OpenBSD 6.6 signing key is not available in Debian Buster's signify-openbsd-keys package at the time of writing, so I obtained a newer version of the package from Debian testing, and checked the downloaded files:

% signify-openbsd -C -p /usr/share/signify-openbsd-keys/ -x SHA256.sig install66.iso
Signature Verified
install66.iso: OK

Now that we've verified the integrity and authenticity of the downloaded ISO, we can patch it to make the OpenBSD bootloader use the serial console, which is the crucial step to being able to avoid the use use of a GUI such as virt-manager:

% echo 'set tty com0' > boot.conf
% growisofs -M install66.iso -l -R -graft-points /etc/boot.conf=boot.conf

This will modify the ISO in place, so you may want to keep the original somewhere else for reference purposes.

Now it's time to fire up virt-install:

virt-install --name openbsd66 --ram=512 --vcpus=2 --cpu host --hvm \
  --disk path=/var/lib/libvirt/images/openbsd66,size=40 \
  --cdrom /var/lib/libvirt/boot/openbsd-6.6-amd64.iso \
  --graphics none --os-variant openbsd6.3 \
  --network bridge=vmbr0m

You will most certainly want to adjust the above command line; here are some things of note:

  • Obviously, the machine name, number of CPUs and size of RAM.
  • The disk path and size; the above creates a 40GiB qcow2 image; you may prefer another storage method, such as an LVM logical volume.
  • I prefer to configure the network manually, and do not want to have any automachinery messing with my firewall rules and the like, hence I attach the VM to a bridge I created via appropriate systemd-networkd configuration, and got rid of the pre-defined default network.
  • Debian Buster's libvirt, or rather, the libosinfo it relies upon, unfortunately only knows about OpenBSD 6.3. I'm not sure if the openbsd6.5 variant shipped in newer libosinfo releases really change VM settings, though.

Once you decided on the appropriate parameters, and started virt-install, you should have the OpenBSD installer running, using the serial console.

After the installation procedure, you may notice that your VM uses an inappropriate amount of CPU when idle; on a modern machine less than 10% should be achievable in my experience. Adjusting your VM definition using virsh edit may help to reduce CPU usage and increase performance:

  • Remove all the USB devices, such as keyboard and mouse, such that the only USB-related entry in the XML description is a "none" model controller:

    <controller type='usb' index='0' model='none'/>
  • Switch your hard disk and network devices to use virtio instead of emulating real hardware. My entries for these devices ended up like this:

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/var/lib/libvirt/images/openbsd66'/>
  <target dev='vda' bus='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
 <interface type='bridge'>
  <mac address='52:54:00:de:ad:ff'/>
  <source bridge='vmbr0'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
  • Set the hpet timer availability to yes, or just remove the XML element, as yes should be the default.

This article was mostly based on the following sources, besides the usual frantic web searching and experimentation: