Two years ago I wrote a blog post named “VoidLinux in FreeBSD Jail; with init”, where we installed and “booted” VoidLinux in a FreeBSD Jail. I think it’s time to revise that post.
This time we will be using Devuan GNU+Linux, boot things using OpenRC and put some native FreeBSD binaries inside the Linux Jail.
Here’s what I’m running at the moment
root@srv0:~ # uname -v
FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC
To bootstrap the Devuan system, we need debootstrap. Specifically, debootstrap that ships with Devuan Chimaera. We can start by installing debootstrap from ports/packages, and then we can modify the rest.
pkg install -y debootstrap
Now we need to fetch Devuan’s debootstrap, extract it, put some files into our debootstrap and set some symbolic links.
# Path might change over time, check https://pkginfo.devuan.org/ for the exact link
fetch http://deb.devuan.org/merged/pool/DEVUAN/main/d/debootstrap/debootstrap_1.0.123+devuan3_all.deb
# .deb files are messy, make a directory
mkdir debootstrap_devuan
mv debootstrap_1.0.123+devuan3_all.deb debootstrap_devuan/
cd debootstrap_devuan/
tar xf debootstrap_1.0.123+devuan3_all.deb
tar xf data.tar.gz
# We need chimaera (latest, symlink) and ceres (origin)
cp usr/share/debootstrap/scripts/ceres usr/share/debootstrap/scripts/chimaera /usr/local/share/debootstrap/scripts/
Now we can bootstrap our system. I will be using a ZFS filesystem, but this can be done without ZFS as well.
Keep in mind that my Jail’s path is going to be /usr/local/jails/devuan0
, modify this path as needed 🙂
zfs create zroot/jails/devuan0
debootstrap --no-check-gpg --arch=amd64 chimaera /usr/local/jails/devuan0/ http://pkgmaster.devuan.org/merged/
The installation should start now but at some point there, we’ll get the following error:
I: Configuring libpam-runtime...
I: Configuring login...
I: Configuring util-linux...
I: Configuring mount...
I: Configuring sysvinit-core...
W: Failure while configuring required packages.
W: See /usr/local/jails/devuan0/debootstrap/debootstrap.log for details (possibly the package package is at fault)
DON’T PANIC! This is fine 🙂 We just need to chroot
inside, fix this manually and install OpenRC
chroot /usr/local/jails/devuan0 /bin/bash
# Fix base packages
dpkg --force-depends -i /var/cache/apt/archives/*.deb
# Set Cache-Start
echo "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00chroot
# Install OpenRC
apt update
apt install openrc
We have almost everything ready. We just need to create a password database file that the jail(8)
command uses internally.
cd /usr/local/jails/devuan0/etc/
echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > master.passwd
pwd_mkdb -d ./ -p master.passwd
# Restore the Linux passwd file
cp passwd- passwd
We can also move our statically linked FreeBSD binaries into the Linux Jail so we can use them when needed
cp -a /rescue /usr/local/jails/devuan0/native
Now we just need our Jail configuration file. We can put that at /etc/jail.conf.d/devuan0.conf
(This assumes that you’re network is configured similar to “VNET Jail HowTo Part 2: Networking”
# vim: set syntax=sh:
exec.clean;
allow.raw_sockets;
mount.devfs;
devuan0 {
# ID == epair index :)
$id = "0";
$bridge = "bridge0";
# Set a domain :)
$domain = "bsd.am";
vnet;
vnet.interface = "epair${id}b";
mount.fstab = "/etc/jail.conf.d/${name}.fstab";
exec.prestart = "ifconfig epair${id} create up";
exec.prestart += "ifconfig epair${id}a up descr vnet-${name}";
exec.prestart += "ifconfig ${bridge} addm epair${id}a up";
exec.start = "/sbin/openrc default";
exec.stop = "/sbin/openrc shutdown";
exec.poststop = "ifconfig ${bridge} deletem epair${id}a";
exec.poststop += "ifconfig epair${id}a destroy";
host.hostname = "${name}.${domain}";
path = "/usr/local/jails/devuan0";
# Maybe mkdir this path :)
exec.consolelog = "/var/log/jail/${name}.log";
persist;
allow.socket_af;
}
As you have guessed, we also need an fstab
file, that should go into /etc/jail.conf.d/devuan0.fstab
devfs /usr/local/jails/devuan0/dev devfs rw 0 0
tmpfs /usr/local/jails/devuan0/dev/shm tmpfs rw,size=1g,mode=1777 0 0
fdescfs /usr/local/jails/devuan0/dev/fd fdescfs rw,linrdlnk 0 0
linprocfs /usr/local/jails/devuan0/proc linprocfs rw 0 0
linsysfs /usr/local/jails/devuan0/sys linsysfs rw 0 0
tmpfs /usr/local/jails/devuan0/tmp tmpfs rw,mode=1777 0 0
Finally, let’s load some kernel modules (in case they haven’t yet)
service linux enable
service linux start
kldload netlink
Let’s start our Jail!
jail -c -f /etc/jail.conf.d/devuan0.conf
Is it running?
# jls -N
JID IP Address Hostname Path
devuan0 devuan0.bsd.am /usr/local/jails/devuan0
Yes it is!
Now we can jexec
into it and run things!
root@srv0:~ # jexec -l devuan0 /bin/bash
root@devuan0:~# uname -a
Linux devuan0.bsd.am 4.4.0 FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC x86_64 GNU/Linux
The process tree looks neat as well!
root@devuan0:~# ps f
PID TTY STAT TIME COMMAND
74682 pts/1 S 0:00 /bin/bash
78212 pts/1 R+ 0:00 \_ ps f
48412 ? Ss 0:00 /usr/sbin/cron
41190 ? Ss 0:00 /usr/sbin/rsyslogd
Let’s do some networking things! Let’s setup networking and install OpenSSH.
(This assumes that you’re network is configured similar to “VNET Jail HowTo Part 2: Networking”)
# Setup network interfaces
/native/ifconfig lo0 inet 127.0.0.1/8 up
/native/ifconfig epair0b inet 10.0.0.10/24 up
/native/route add default 10.0.0.1
# Install and start OpenSSH server
apt-get --no-install-recommends install openssh-server
rc-service ssh start
You should be able to ping things now
~# ping -n -c 1 bsd.am
ping: WARNING: setsockopt(ICMP_FILTER): Protocol not available
PING (37.252.73.34) 56(84) bytes of data.
64 bytes from 37.252.73.34: icmp_seq=1 ttl=55 time=2.60 ms
--- ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.603/2.603/2.603/0.000 ms
To make the networking configuration persistent, we can use the rc.local
file that OpenRC executes at boot.
chmod +x /etc/rc.local
echo '/native/ifconfig lo0 inet 127.0.0.1/8 up' >> /etc/rc.local
echo '/native/ifconfig epair0b inet 10.0.0.10/24 up' >> /etc/rc.local
echo '/native/route add default 10.0.0.1' >> /etc/rc.local
Do you know what this means? It means that now you can have proper ZFS, DTrace and pf firewalling with Linux. Congrats, now you have clean waters.
That’s all folks…
P.S. I would like to thank my mentor, norayr, for showing me how to start/stop OpenRC manually, and the awesome folks at #devuan for their help.