While I have been using Jails (a built in capability of FreeBSD) to obtain some of the functionalities of virtualization (and I love the simplicity and well as the low memory and hardware footprint that come with this solution) there are cases in which an actual virtualization is preferred or required.
Virtual Box might be the solution, here i will report on my attempts, problems, etc… I’m focusing on creating virtual headless servers running an OS independent (and likely different) than the host machine.
Installing Virtual Box
The installation of Virtual Box itself is pretty simple. FreeBSD Handbook has a page dedicated to it: https://docs.freebsd.org/en/books/handbook/virtualization/#virtualization-host-virtualbox .
However the handbook stops at the installation of the software without getting into the actual creation, installation, configuration and running of an actual virtual machine.
The actual installation steps are as below at time of writing:
Do the actual install
# cd /usr/ports/emulators/virtualbox-ose
# make install clean
Load the kernel module needed:
# kldload vboxdrv
Edit the boot loader “/boot/loader.conf” to maintain the kernel module loaded in case of restart, add this line:
vboxdrv_load="YES"
Edit the file “/etc/rc.conf” to enable virtual box by adding this line:
vboxnet_enable="YES"
Add any user that will use Virtual Box to the group “vboxusers
“
# pw groupmod vboxusers -m yourusername
Change permissions for “vboxnetctl” which is the bridged network device that will be used to provide network connectivity to the virtual machines
# chown root:vboxusers /dev/vboxnetctl
# chmod 0660 /dev/vboxnetctl
Edit the “/etc/devfs.conf” to make these permission changes permanent by adding these lines:
own vboxnetctl root:vboxusers
perm vboxnetctl 0660
Done.
Configurations
Now the tricky part is that virtual box has a command line interface but for certain operations, like installing the OS, you need to operate it in a “windowed” mode. Which means Xorg in a *nix system.
I have tried a few options, installing https://www.xquartz.org on my mac and making a few configuration changes to allow a Xorg connection tunneled via ssh. Ultimately i was no successful.
I then opted for a different solution. Given that Xorg is only needed for installation, I installed the system in a VM created on my local computer, then exported the resulting VM and imported it via the VBoxManage (the CLI provided with Virtual Box).
I’ll skip here the steps of installing the OS on the local machine, only thing to notice, is that I set it up with NAT as the networking configuration option and added a rule to allow ssh through a different port (I used 2201, but any port unused by the server the virtual machine will be moved into, will work. Also better not to use any the “known port” used for various services, even if they are not running on the target machine).
The network configuration step is important, as i will need a way to log into the VM once it is moved and running in headless mode.
The NAT method is the default for Virtual Box, to access the “rules” section you’ll need to go to settings of the VM (in my case, on a Mac, I access it by right clicking on the VM from the VM manager). From there choose Network, click on “Advanced” to expose more options then port forwarding.
What I did is to write ssh as the name, select TCP and the protocol, leave host IP empty, set 2201 as the Host port, leave Guest IP empty and insert 22 into Guest port.
This effectively creates a rule that forwards traffic going to port 2201 of the host system (my Mac now and the Server later once i transferred the VM into it) to port 22 of the guest system (port 22 is the default for ssh).
Exporting and Importing the VM
Once the new OS is installed in the Virtual Machine, the resulting VM can be moved to the target server. The only configuration change that i did in the Guest VM after the regular installation is to enable ssh. All other configuration changes will be done once it is installed on the server.
To export the VM is simple, Virtual Box has an option to “Export Appliance” you select the VM you want to export, select the format (I used Open Virtualization Format 1.0, which was the default). Let the default to include only NAT network adapter and saved the resulting file (which will have a .ova extension).
I then transferred the file to the server and imported it using the VBoxManage commands.
# VBoxManage import /pathto/vmfilename.ova
Is that simple! Next if i run the command to list the VM I will have my VM listed.
# VBoxManage list vms
Last i can run it headless:
# VBoxManage startvm NameOfTheVM --type headless
From the server i can now ssh into it:
# ssh -l username localhost -p2201
If there are no firewalls in place i can also ssh into the VM remotely by using the main IP of the Host server and port 2201.
Next step will be for this VM to actually take over a static IP available and consequently be directly connected to the internet without using NAT.
Virtual Box Bridged Mode confuguration
Configuring and modifying a VM only using the VBoxManage CLI to make changes is a delicate matter. We don’t have a easy way to interact directly with it should we make a mistake.In any event, after a few tries, here is how to configure the created VM into bridged mode.
Bridged mode is effectively a way in which the VM gets direct access to the server nic. This is called access in promiscuous mode (because the host server and the guest(s) both access it).
For someone like me that comes from a FreeBSD jails history there are a few things to understand. First, the guest will get its own IP, this IP cannot be configured on the Host server (but must be available to use in the network). Second the mask applied to this configuration is the same as the main IP configured in the Host server. In jails i got used to configure aliases with a /32 mask (broadcast is the same as the IP) but this is not the case for a VM guest.
First thing to do is to log into the guest VM and change the configuration. If the IP that i was going to use was 1.2.3.4 and the router 1.2.3.1 (with a net mask of /24 or 2.55.255.255.0) this is how i would configure a freebsd Guest:
ifconfig_em0="inet 1.2.3.4 netmask 255.255.255.0"
defaultrouter="1.2.3.1"
This is assuming em0 is how the guest sees the nic, this is the most common case, i guess it depends on the emulation used by VirtualBox.
We then shutdown the guest.
# VBoxManage controlvm vmguestname poweroff
Now we modify the nic configuration of the VM
# VBoxManage modifyvm vmguestname --nic1 bridged --bridgeadapter1 igb0
This is assuming igb0 is the name of the public ethernet adapter used by the host server.
At this point all we need to do is to start the VM, it should now be reachable via 1.2.3.4.
Done, from this moment forward the guest VM acts like an independent server on the network and the proper configurations and installations can be made. Including, if needed, setup jails in the guest FreeBSD system.