Running FreeBSD in a VM on Linux to run a Linux container

Linux-on-Freebsd-on-Linux

I wanted to try out FreeBSD’s recently added support for podman, the container management tool generally for linux. My computer runs NixOS (i.e Linux) though, so I decided to spin up a virtual machine to try it out in. I had some constraints though:

In the past I’d use libvirtd (gnome boxes, etc) for ad-hoc virtual machines and it fails on both counts. As far as I can tell, libvirtd tries to railroad you into using it as root, and it stores stuff in its own directory. There’s nothing wrong with that but it’s not what I want on my user system. It does support rootless usage but I couldn’t find documentation on how to do port forwarding. Finally, In rootful mode even if you don’t run as root (i.e by putting your user in the libvirtd group) my understanding is that access to the libvirtd socket should be considered implicit root access to the machine which disqualifies it from my day-to-day user account.

As far as I can tell for my usecase, all libvirt is doing is wrapping a “nicer” interface around constructing the qemu command line so I decided to cut out the middleman and run qemu manually. It’s simpler than you might think! Of course, libvirt shines more for more sophisticated usage but that’s not what this post is about.

Running the VM

To start, we need to download FreeBSD. I grabbed the qcow2 vm disk image from their website and then uncompressed it using unxz, which conveniently deletes the archive once it’s done.

unxz FreeBSD-15.0-RELEASE-amd64-zfs.qcow2.xz

Now all I need is qemu, which I don’t have installed so I will grab it with nix shell. On other distros you can use whatever your package manager is.

nix shell nixpkgs#qemu

qemu is now available in the shell to use, so we can do so.

qemu-system-x86_64 \
  -drive file=FreeBSD-15.0-RELEASE-amd64-zfs.qcow2 \
  -accel kvm \
  -smp 4 \
  -m 4G \
  -nic user,hostfwd=tcp::60022-:22

I gave it a generous amount of ram and cores (4 GB and 4 threads, respectively), but it doesn’t really matter. I originally didn’t set the ram and then I think freebsd’s pkg started swapping (there was some error printed along those lines). The important thing to include is -accel kvm—without it qemu has to actually emulate the cpu in software (very slow!), instead of asking the cpu for a hardware sandbox that it can run at ~full speed inside. Finally, we use qemu’s user networking to port forward TCP port 22 in the guest to port 60022 on the host so we can ssh into the VM. This is useful because using the VM monitor instead of an actual terminal sucks.

Making it usable with ssh

Running this should pop up a window with FreeBSD. But it’s not very usable, so let’s ssh into it from a proper terminal emulator.

First we have to configure FreeBSD a bit. We can login with username: root and no password. The first thing we should do is set a password for root. This is not an optional step: sshing into root with no password will not work, even if you explicitly configure it to be allowed (trust me, I tried).

passwd

Once that’s done, we want to configure sshd to allow password logins and root logins. So edit the sshd config file with vi /etc/ssh/sshd_config, and change the following lines to match:

PermitRootLogin yes
PasswordAuthentication yes

Then we just need to enable sshd and we’re off to the races!

service sshd enable
service sshd start

Now on the host you should be able to ssh into the freebsd VM using the port forward we did earlier.

ssh root@localhost -p 60022

podman

Finally, we can get to what I wanted to mess around with. However, I’m going to punt on that in this post and refer to the post I followed. I’ll just say that it does work, and I think it’s pretty cool.

$ ssh root@localhost -p 60022
(root@localhost) Password for root@freebsd:
Last login: Wed Jan 21 03:52:20 2026 from 10.0.2.2
FreeBSD 15.0-RELEASE (GENERIC) releng/15.0-n280995-7aedc8de6446

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List:        https://www.FreeBSD.org/lists/questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

To change this login announcement, see motd(5).
root@freebsd:~ # uname -a
FreeBSD freebsd 15.0-RELEASE FreeBSD 15.0-RELEASE releng/15.0-n280995-7aedc8de6446 GENERIC amd64
root@freebsd:~ # podman run -it --os=linux --rm docker.io/alpine sh
/ # uname -a
Linux 9a31763bdcbc 5.15.0 FreeBSD 15.0-RELEASE releng/15.0-n280995-7aedc8de6446 GENERIC x86_64 Linux