This page looks best with JavaScript enabled

CBSD Jails Manager, Bhyve, Qemu and Xen

 ·  ūüéÉ kr0m

CBSD is a management software for Jails, Bhyve virtual machines, Qemu virtual machines of other architectures, and Xen under FreeBSD. The project offers a single CLI to quickly and easily build and manage virtual environments. In addition, it is possible to install a web interface called Clonos, which may be attractive to some, but you know that the CLI will always be more powerful since it is possible to automate all kinds of tasks.

The article is composed of different parts:

Initial Configuration:

Before starting, it should be mentioned that in this manual we will not use Xen since it would imply replacing our operating system with the Xen hypervisor and installing FreeBSD as DOM0. In this link we can see FreeBSD as DOM0 managing the DOMU from CBSD.

The CBSD versions are composed of several parts, the first two numbers indicate the version of FreeBSD in which it was tested during its development, the third number indicates the version of CBSD. For example, with the CBSD v.12.1.13 version, it is the version of CBSD 13 that was tested on FreeBSD 12.1.

We install the necessary software from binary packages, we will use Vinagre as a VNC client since it is very easy to use:

pkg install -y cbsd tmux vinagre

To use Bhyve, we need to load the vmm (Virtual Machine Monitor) module, which we load at boot time:

vi /boot/loader.conf


To provide network to Jails, we will use aliases, and for Bhyve VMs, we will use tap interfaces and bridges. For TTY access to jails, we will use nmdm (null modem terminal driver).
We load the corresponding modules:

vi /etc/rc.conf

kld_list="vmm if_tap if_bridge nmdm"

We restart to apply the configuration:


We initialize the node:

env workdir="/usr/jails" /usr/local/cbsd/sudoexec/initenv

In most cases, the default values are acceptable, so we simply press ENTER if we agree with them. If we want to modify any parameter later on, we can execute the commands cbsd initenv-tui, bsdconfig cbsd, modify the sqlite database ${workdir}/var/db/local.sqlite, or load the values from a configuration file.

-------[CBSD v.12.1.13]-------
 This is install/upgrade scripts for CBSD.
 Don't forget to backup.
Do you want prepare or upgrade hier environment for CBSD now?
[yes(1) or no(0)]

Shall i add cbsd user into /usr/local/etc/sudoers.d/cbsd_sudoers sudo file to obtain root privileges for the most cbsd commands?
[yes(1) or no(0)]

Shall i modify the /etc/rc.conf to sets cbsd_workdir="/usr/jails"?: 
[yes(1) or no(0)]

nat_enable: Enable NAT for RFC1918 networks?
[yes(1) or no(0)]

fbsdrepo: Use official FreeBSD repository? When no (0) the repository of CBSD is preferred (useful for stable=1) for fetching base/kernel?
[yes(1) or no(0)]

zfsfeat: You are running on a ZFS-based system. Enable ZFS feature?
[yes(1) or no(0)]

stable: Use STABLE branch instead of RELEASE by default? Attention: only the CBSD repository has a binary base for STABLE branch ?
(STABLE_X instead of RELEASE_X_Y branch for base/kernel will be used), e.g.: 0 (use release)

sqlreplica: Enable sqlite3 replication to remote nodes ?
(0 - no replica, 1 - try to replicate all local events to remote nodes) e.g: 1

statsd_bhyve_enable: Configure CBSD statsd services for collect RACCT bhyve statistics? ?

statsd_jail_enable: Configure CBSD statsd services for collect RACCT jail statistics? ?

statsd_hoster_enable: Configure CBSD statsd services for collect RACCT hoster statistics? ?

Configure RSYNC services for jail migration?
[yes(1) or no(0)]

Do you want to enable RACCT feature for resource accounting?
[yes(1) or no(0)]

Shall i modify the /etc/rc.conf to sets cbsdd_enable=YES ?
[yes(1) or no(0)]

Shall i modify the /etc/rc.conf to sets rcshutdown_timeout="900"?
[yes(1) or no(0)]

Shall i modify the /etc/sysctl.conf to sets kern.init_shutdown_timeout="900"?
[yes(1) or no(0)]

NOTE: To know which version of FreeBSD we want to use, we can consult this previous article .

The added RC parameters should be:

vi /etc/rc.conf

# kld_list="vmm if_tap if_bridge nmdm"
# /boot/loader.conf: kern.racct.enable=1 vmm_load="YES"

We start the service:

service cbsdd start

CBSD stores the entered data in a SQLite database, but it is also saved in a plain text file for quick reference.

cat ~cbsd/nc.inventory

If we want to change any of the configured parameters, we can execute one of the existing wizards:

cbsd initenv-tui
bsdconfig cbsd

NOTE: There are parameters that cannot be modified from the wizards, but we can configure the parameters in a file and load them.

The complete list of parameters can be found here:


The best way to do it is by merging our current configuration with the parameters of the generic file:

cat ~cbsd/nc.inventory > customConfig.txt
echo “#——————-” » customConfig.txt
cat /usr/local/cbsd/share/initenv.conf » customConfig.txt

Now we edit the file to our liking:

vi customConfig.txt

Finally, we load the parameters:

/usr/local/cbsd/sudoexec/initenv /root/customConfig.txt

We must keep in mind that every time the cbsd version is updated, we will have to execute:

cbsd initenv

If we install CBSD from precompiled packages, it may come with an outdated version of the templates, which are used to launch Bhyve virtual machines. If these are not updated, the template may refer to an old ISO that is no longer available on the image servers, and the download will fail.

We can update the templates from the assistant itself:

cbsd bconstruct-tui

If a message appears warning us that our git configuration is incomplete and complains about the way to merge git changes, we will have to go to the repository directory and execute the configuration commands:

cd /usr/jails/etc
git config pull.rebase false

Now we can launch the assistant and it won’t complain.

If we prefer, we can do a direct pull, obtaining the same result as with the assistant:

cd /usr/jails/etc/
git pull

The default configuration of CBSD is located in the directory: /usr/jails/etc/defaults/

If we want to modify any value, we will do it in the FreeBSD style, that is, generating the same file in a directory higher than the directory where the default file is located, this new file will contain only the parameters that we want to overwrite.

To change the domain name, we will edit the following files:

vi /usr/jails/etc/bhyve-default-default.conf

vi /usr/jails/etc/jail-freebsd-default.conf
vi /usr/jails/etc/jail-freebsd-vnet.conf
vi /usr/jails/etc/jail-freebsd-trusted.conf

A very useful functionality if we are testing CBSD on our desktop PC is the blogin command, which allows us to specify the command to execute to log in to the Bhyve VM. In my case, I want to launch Vinagre against the loopback IP on the VNC port assigned to the VM. However, to do this from root, we will have to export the DISPLAY variable, define the path of the Xauthority file of the user who started the current graphical session, and finally launch Vinagre as that user.

vi /usr/jails/etc/blogin.conf

login_cmd="export DISPLAY=:0.0 && export XAUTHORITY=/home/kr0m/.Xauthority && su -m kr0m -c \"xhost si:kr0m:root\" && su -m kr0m -c \"vinagre${vnc_port}\""

NOTE: If we need to modify the login command for a specific VM, we must edit the file: /usr/jails/jails-system/VM_NAME/etc/blogin.conf

Of course, if the CBSD installation was done on a remote server, the blogin command is completely useless. We will have to configure the VNC parameters of the VM to be able to access it from the outside or bind VNC to the loopback and each VM on a different port. Access from outside would be done through SSH tunnels. Both procedures are detailed later in this same manual.

By default, the network of the jails is managed through aliases in the parent, while in Bhyve it is done through tap devices and a bridge. Let’s give an example of Jail and Bhyve to make it clearer.

Jail Management:

We start the construction assistant of a Jail:

cbsd jconstruct-tui

Starting the Jail:

cbsd jstart jail1
cbsd jls

JNAME  JID  IP4_ADDR       HOST_HOSTNAME    PATH                    STATUS
jail1  4  /usr/jails/jails/jail1  On       

If we leave the IP address in DHCP, it will give us one from the range: If we want to assign IPs by DHCP to Jails, we will have to use the VNET network mode, not alias.

If we assign an IP from our network range ( to the parent, an alias will be created automatically:


em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
 ether 34:97:f6:36:bf:45
 inet netmask 0xffffff00 broadcast
 inet netmask 0xffffffff broadcast
 media: Ethernet autoselect (1000baseT <full-duplex>)
 status: active

We enter the Jail:

cbsd jlogin jail1
uname -a

FreeBSD 12.1-RELEASE-p10 FreeBSD 12.1-RELEASE-p10 GENERIC  amd64
ifconfig em0
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
 ether 34:97:f6:36:bf:45
 inet netmask 0xffffffff broadcast
 media: Ethernet autoselect (1000baseT <full-duplex>)
 status: active

To provide network to Jails, aliases are used on the parent interface. Since these are aliases, they are IPs of the parent and the Jail simultaneously, which implies certain problems if we bind the parent’s services to all available addresses. For example, if we do this with the Ssh service while the Jail has the service started, the Ssh of the Jail will be served on that IP. If the Ssh of the Jail is turned off, the Ssh of the parent will be served, which can be confusing.

Any service of the parent must be bound exclusively to its IP address. In the Jail, there is no problem since it only sees the assigned IP, and with a wildcard, it is bound to this single existing IP.

In the parent, we must avoid generic bindings like these:

listen *

This could be avoided by using the VNET network technology, which will provide a complete TCP/IP stack to the Jail, but this is another story that I will explain in a future article.

We access the Jail via SSH:

ssh root@
jail1:/root@[19:04] #

If we are testing CBSD on a desktop computer, it is likely that the gvfs process is running, which can cause problems when we delete jails since the gvfs Trash process may be accessing the filesystem.

We check if any filesystem belongs to a deleted jail:

zfs list

zroot/ROOT/default/jail1                88K  17.6G    88K  /usr/jails/jails-data/jail1-data

To locate the problematic process, we will run lsof in a similar way to the following:

lsof +f – /usr/jails/jails-data/jail1-data

gvfsd-tra 71064 kr0m   31r  VDIR 2588486123,3870875304        2    4 /usr/jails/jails-data/jail1-data

We kill the process:

kill PID

We unmount the filesystem and destroy it:

umount /usr/jails/jails-data/jail1-data
zfs destroy zroot/ROOT/default/jail1

Bhyve VM Management:

We start the Bhyve VM construction wizard:

cbsd bconstruct-tui

In the case of Bhyve, the network configuration will be governed by the configuration made through the guest OS installer, ignoring the parameters of the wizard. These parameters are simply stored in the SQLite database in case integration with an external service such as a DHCP server is necessary. In this way, we could run a DHCP configuration script based on the indicated IP and the VM’s MAC address just before starting it. In this article we can see a complete example.

When creating the VM, two tap interfaces are created in the parent, one for the VM and one for the parent, these two interfaces along with the physical interface are put into a bridge.

If we are creating a Linux machine, we must change the disk boot firmware to refind, in other systems such as DragonFlyBSD, it seems that the Bhyve firmware works without problems:

Now we must decide whether to sacrifice a network IP address for VNC access or bind the service to the loopback and access via Ssh tunnel. By using the loopback, access will be more secure since it will only be exposed when we mount the tunnel and we will not waste IP addresses, but we will have to configure a different VNC port for each VM.

Bhyve VNC-loopback:
We access the VNC options of the wizard:

We configure a different port for each VM:

Bhyve VNC-Ip:
We access the VNC options of the wizard:

We configure an IP address:

Resulting in the following:

We configure the IP as an alias in the parent, we will leave it configured in the rc.conf and manually so that in case of a restart, the configuration will not be lost:

sysrc ifconfig_nfe0_alias0="inet IP_VM netmask NETMASK"


ifconfig INTERFACE IP_VM netmask NETMASK alias

We finish creating the VM:

If we want to modify any parameter, we just have to execute the bconfig command:

cbsd bconfig jname=kali1

When we start the VM, it will ask us if we want to boot from the cdrom:

cbsd bstart kali1

May be you want to boot from CD?   
[yes(1) or no(0)]  
Temporary boot device: cd  
vm_iso_path: iso-kali-linux-mate-2020.2-amd64  
No such media: /usr/jails/src/iso/cbsd-iso-kali-linux-2020.2-installer-amd64.iso in /usr/jails/src/iso

If the installation ISO image of the distro is not found, it will ask us if it should be downloaded from the mirrors:

Shall i download it from: ?  
[yes(1) or no(0)]  

We check the available VMs, depending on how we configured the VNC access, we will get different outputs:

cbsd bls

kali1  75966  2048    25         1        0     linux       DHCP      On  


cbsd bls

kali1  75903  2048    264        1        0     linux       DHCP      On

We log in via VNC and proceed with the installation.

We mount the Ssh tunnel to access the VNC from outside:

ssh -L 5900: -A -g kr0m@HOST_PADRE

We access through the tunnel:




In the bridge we can see an interface for the parent, another for the VM, and the physical interface:


bridge1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500  
 description: em0  
 ether 02:89:af:f3:c6:01  
 id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15  
 maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200  
 root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0  
         ifmaxaddr 0 port 5 priority 128 path cost 2000000  
         ifmaxaddr 0 port 4 priority 128 path cost 2000000  
         ifmaxaddr 0 port 1 priority 128 path cost 20000  
 groups: bridge  
tap1: flags=8903<UP,BROADCAST,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500  
 description: CBSDSYSTEM0  
 ether 00:bd:3a:47:f7:01  
 groups: tap  
 media: Ethernet autoselect  
 status: no carrier  
tap2: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500  
 description: kali1-nic0  
 ether 00:bd:15:46:c5:02  
 groups: tap vm-port  
 media: Ethernet autoselect  
 status: active  
 Opened by PID 43480

If the X’s have been installed, they are buggy ( 1 , 2 ). The bug in question presents the following window when trying to start the X:

To solve it, we will have to enter through Ssh and uninstall the xserver-xorg-video-vesa package. The problem is that when we start the graphical environment, it hangs due to the bug, and when we press Ctrl+Alt+F1, we are sending the keystrokes to our FreeBSD. To be able to do this within the VNC client, we must first disable the keys in our OS.

setxkbmap -option srvrkeys:none

Now we can log in from the non-graphical tty and start the Ssh service to uninstall the conflicting package:

service ssh start

We access the VM via Ssh:

We uninstall the package:

apt remove xserver-xorg-video-vesa

We re-enable Ctrl+Alt+FX:

setxkbmap -option

As we can see, Kali starts X normally, and if we log in, we will see that the graphical environment works without problems:

Another way to have X working is to install the OS through CBSD’s VNC and then access the VM via SSH to install a VNC server inside it, so we would no longer depend on Bhyve’s VNC.

As a final note, if we only want to start certain graphical applications, we can do so through ssh-xforward without the need to start the entire X.

We authorize the Kali IP to launch applications locally over the network, connect via SSH, and remotely launch the application:

xhost +inet:
ssh -vYC kr0m@ burpsuite

If you liked the article, you can treat me to a RedBull here