FreeBSD & Bhyve
TLDR;
bhyve (“bee-hive”) is BSD’s builtin hypervisor, on Intel and AMD processors that allows the users to create virtual machines.
bhyve supports any version of FreeBSD i386/amd64 with VirtIO support. OpenBSD, NetBSD and GNU/Linux are supported using the sysutils/grub2-bhyve port. UEFI support is available for FreeBSD, OpenBSD, GNU/Linux, SmartOS and Windows:
- FreeBSD 8.4-RELEASE and newer, including CURRENT
- OpenBSD amd64/i386 5.2 and newer
- GNU/Linux amd64/i386 (Many distributions)
- NetBSD amd64 6.1 and newer
- SmartOS 20151001 and newer
- Windows x64 Vista, 7, 8, 10
- Windows Server 2008r2, 2012r2, 2016
In the office we encourage our staff to rotate different Operating Systems periodically. We find this encouragement helps expand and enhance their knowledge, familiarity and system adminsitration skills of the available and different OS’s to date. It also helps them produce more compatiable code when writing/developing open-source code in support of public projects or small inhouse projects that help improve their day-2-day pentesting or incident response roles.
This post is a quick walkthrough, of preparing and installing virtual machines natively on FreeBSD utilising bhyve.
Setup
Networking - Manual
Setup tap0
echo "net.link.tap.up_on_open=1" >> /etc/sysctl.conf
sysctl net.inet.ipforwarding=1
For users utlising a wired connection, you can create a bridged interface:
ifconfig bridge create
ifconfig bridge0 name em0bridge
ifconfig em0bridge up
ifconfig tap0 create
ifconfig em0bridge addm tap0
For users utlising a wireless connection, bridge will not work as wireless interfaces can only have 1x MAC address. Instead we can use a NAT’ed interface:
ifconfig tap0 create
ifconfig tap0 inet 172.16.1.1/24
Networking - Automated
For auto-bridge setup add these to /etc/rc.conf
cloned_interfaces="bridge0 tap0"
ifconfig_bridge0_name="em0bridge"
ifconfig_em0bridge="addm em0 addm tap0 up"
gateway_enable="yes"
For our wireless and NAT’ed interface, add the following to /etc/rc.conf
cloned_interfaces="lo1 tap0"
ifconfig_tap0="inet 172.16.1.1/24"
pf_enable="YES"
natd_enable="YES"
natd_interface="wlan0"
natd_flags="-u -m -dynamic"
gateway_enable="yes"
NAT and PF firewall
You will need to add the following lines into pf.conf, for the pf firewall to correctly route your NAT’ed interfaces traffic
virt_net="172.16.1.1/24"
nat on $ext_if from $virt_net to any -> ($ext_if)
block in all
pass in on tap0
Loading Kernel Modules - Manual
load kernel modules
kldload vmm
kldload nmdm
Loading Kernel Modules - Automatic
Run the following in a shell, to add these to your boot.conf:
echo 'vmm_load="YES"' >> /boot/loader.conf
echo 'nmdm_load="YES"' >> /boot/loader.conf
echo 'if_tap_load="YES"' >> /boot/loader.conf
echo 'if_bridge_load="YES"' >> /boot/loader.conf
Installation
Assuming your using pkg manager, installing bhyve is as simple as:
pkg install bhyve grub2-bhyve uefi-edk2-bhyve tigervnc-viewer
Creating our first Virtual Machine
Preparing a Virtual Disk
Zfs volume creation; the following command creates a 20GB ZFS volume for our virtual machine:
zfs create -V20G -o volmode=dev zroot/kalivm
Booting a Linux Distro
Booting a Debian/Kali iso (we assume you know how to download an appropriate install ISO, we temporarily download ours to /tmp)
bhyve -c 2 -m 2G -w -H \
-s 0,hostbridge \
-s 3,ahci-cd,/tmp/kali.iso \
-s 4,virtio-blk,/dev/zvol/zroot/kalivm \
-s 5,virtio-net,tap0 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
kalivm
Next use tigervnc viewer to view the virtual machine’s console and complete the installtion:
vncviewer :5900
IMPORTANT: AT END OF DEBIAN INSTALL DROP TO SHELL
mkdir /target/boot/efi/EFI/BOOT/
# copy file - workaround for bhyve grub package #
# Pay attention to destination file bootx64.efi #
cp /target/boot/efi/EFI/debian/grubx64.efi /target/boot/efi/EFI/BOOT/bootx64.efi
Freeing resources
After powering down the VM we need to dispose of its resources before we can reboot, this is as simple as:
bhyvectl --destroy --vm=kalivm
Booting our Linux VM
bhyve -c 2 -m 2G -w -H \
-s 0,hostbridge \
-s 4,virtio-blk,/dev/zvol/zroot/kalivm \
-s 5,virtio-net,tap0 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=1024,h=768,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
kalivm
Other
Converting ESX/VirtualBox virtualised disks to bhyve
bhyve uses the same disk format as Qemu, converting a disk image is as simple as following the next few steps:
Don’t forget to install the qemu tools first:
pkg install qemu-devel
then:
qemu-img convert -f vmdk -O raw virtual_box_image.vmdk bhyve_raw_image.img
Conclusion
Creating virtual machines natively in BSDs hypervisor is relativly straightforward. We have brought networking differences to attention, NAT vs bridging for those that utilise wireless networks over desk-wired ethernet. However, the creation of virtual machines can still be quite techncial; There are a few differnet packages that can make this process easier, they tend to use of pre-built templates, and wizards to guide the user through the setup and installation processes. If the above walkthrough is too daunting we suggest you try cbsd instead of manual creation.
References
Share on: