Two important things happened this week for me.
First, Faraz asked me if I can rename my Jail manager to something other than Jailio because he got that domain for his Jailer manager already. So I named it
Second, I was able to run a complete Linux system using Jailer. While the repo for Jailer is not released yet (we are auditing for possible security issues), I would like to share how I was able to run VoidLinux in a Jail.
Since Jailer is not announced yet, I will give the examples using jail.conf
, as most people either are or should be familiar with its concepts.
I went with VoidLinux because I am able to run the init
process without its need to be running as PID1.
Let’s start, shall we?
First, ZFS dataset for our jail!
zfs create zroot/jails/voidlinux
Next we need to fetch the base system of VoidLinux. Luckily they do provide it on their website.
fetch https://alpha.de.repo.voidlinux.org/live/current/void-x86_64-ROOTFS-20210218.tar.xz
Now we can extract this into our dataset
tar xf void-x86_64-ROOTFS-20210218.tar.xz -C /usr/local/jails/voidlinux/
You might get an error that ./usr/bin/iputils-ping: Cannot restore extended attributes: security.capability
, which is fine, I think?
If you are on FreeBSD 12.2-RELEASE or later, now you need to enable the Linuxulator.
service linux enable; service linux start
Now you can at least chroot into the system.
chroot /usr/local/jails/voidlinux/ /bin/bash
If everything is fine until now, perfect.
Now we need to add a root user into the system.
root@host:~ # cd /usr/local/jails/voidlinux/etc/
root@host:/usr/local/jails/voidlinux/etc # echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > master.passwd
root@host:/usr/local/jails/voidlinux/etc # pwd_mkdb -d ./ -p master.passwd
pwd_mkdb: warning, unknown root shell
Execute the rest of the commands in Void.
root@host:~ # chroot /usr/local/jails/voidlinux/ /bin/bash
bash-5.1# cd /etc/
bash-5.1# pwconv
bash-5.1# grpconv
bash-5.1# passwd
New password:
Retype new password:
passwd: password updated successfully
bash-5.1# exit
If all went fine, then the system is ready to be run as a Jail!
First we need to make an fstab for the system.
Create a file at /usr/local/jails/voidlinux/etc/fstab.pre
and insert the following inside
devfs /usr/local/jails/voidlinux/dev devfs rw 0 0
tmpfs /usr/local/jails/voidlinux/dev/shm tmpfs rw,size=1g,mode=1777 0 0
fdescfs /usr/local/jails/voidlinux/dev/fd fdescfs rw,linrdlnk 0 0
linprocfs /usr/local/jails/voidlinux/proc linprocfs rw 0 0
linsysfs /usr/local/jails/voidlinux/sys linsysfs rw 0 0
/tmp /usr/local/jails/voidlinux/tmp nullfs rw 0 0
Next, let’s create a loopback interface for networking. Oh yes, VNET is not supported yet, but I’m working on a patch 🙂
ifconfig lo1 create
ifconfig lo1 inet 10.10.0.1/24 up # sorry, 10.0.0.0/24 was unavailable :P
Okay, time to create our Jail conf!
exec.clean;
allow.raw_sockets;
mount.devfs;
voidlinux {
$id = "1";
$ipaddr = "10.10.0.42";
$mask = "255.255.255.0";
$domain = "srv0.bsd.am";
devfs_ruleset = 4;
allow.mount;
allow.mount.devfs;
mount.fstab = "${path}/etc/fstab.pre";
exec.start = "/bin/sh /etc/runit/2 &";
exec.stop = "/bin/sh /etc/runit/3";
ip4.addr = "${ipaddr}";
interface = "lo1";
host.hostname = "${name}.${domain}";
path = "/usr/local/jails/voidlinux";
exec.consolelog = "/var/log/jail-${name}.log";
persist;
allow.socket_af;
}
Let’s check?
# jls
JID IP Address Hostname Path
1 192.168.0.42 voidlinux.srv0.bsd.am /usr/local/jails/voidlinux
And the process tree?
# ps auxd -J voidlinux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 35182 0.0 0.1 2320 1428 - SsJ 21:09 0:00.12 runsvdir -P /run/runit/runsvdir/current log: ot set SO_PASSCRED: Protocol not available\ncould not set SO_PASSCRED: Protocol
root 35190 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty6
root 35397 0.0 0.1 2412 1704 - SsJ 21:10 0:00.00 `-- agetty tty6 38400 linux
root 35191 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty1
root 35396 0.0 0.1 2412 1704 - SsJ 21:10 0:00.00 `-- agetty --noclear tty1 38400 linux
root 35192 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty5
root 35398 0.0 0.1 2412 1704 - SsJ 21:10 0:00.01 `-- agetty tty5 38400 linux
root 35193 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty2
root 35393 0.0 0.1 2412 1704 - SsJ 21:10 0:00.00 `-- agetty tty2 38400 linux
root 35194 0.0 0.1 2168 1396 - RsJ 21:09 0:00.12 - runsv udevd
root 35195 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty3
root 35394 0.0 0.1 2412 1704 - SsJ 21:10 0:00.00 `-- agetty tty3 38400 linux
root 35196 0.0 0.1 2168 1376 - SsJ 21:09 0:00.02 - runsv agetty-tty4
root 35390 0.0 0.1 2412 1704 - SsJ 21:10 0:00.00 `-- agetty tty4 38400 linux
You may jexec
now 🙂
# jexec voidlinux /bin/bash
bash-5.1# uname -a
Linux voidlinux.srv0.bsd.am 3.2.0 FreeBSD 12.2-RELEASE-p6 GENERIC x86_64 GNU/Linux
Let’s check networking?
bash-5.1# ping -c 1 10.10.0.1
ping: WARNING: setsockopt(ICMP_FILTER): Protocol not available
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
64 bytes from 10.10.0.1: icmp_seq=1 ttl=64 time=0.069 ms
--- 10.10.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.069/0.069/0.069/0.000 ms
There you go! Well, things that are related to netlink
might not work, but other than that it’s okay.
I did have some problems while installing packages, something about too many levels of symbolic links. Here’s the exact output when I was trying to install the curl
package
[*] Unpacking packages
libev-4.33_1: unpacking ...
ERROR: libev-4.33_1: [unpack] failed to extract file `./usr/lib/libev.so.4': Too many levels of symbolic links
ERROR: libev-4.33_1: [unpack] failed to extract files: Too many levels of symbolic links
ERROR: libev-4.33_1: [unpack] failed to unpack files from archive: Too many levels of symbolic links
Transaction failed! see above for errors.
Now, I did not find the time to fix this yet, but if you have any idea, please let me know or comment below 🙂
So, what do we have here? A Linux Jail, running VoidLinux, with init, so you can also run services, and basic networking for it.
That’s all folks…