Chimera Linux Install
May 28, 2025Tags: sysadmin
deprecation notice!
this post has been marked as deprecated! the information within may be outdated, incorrect, or there may simply be an objectively better solution. the post is preserved for archival purposes and there still may be useful information here, but please check it against official sources (such as a project's own documentation) and do your own research!
Deprecation reason: see this post for an easier solution to auto-unlocking partitions with a usb drive
NOTE: This guide is actually really janky and prone to errors, and there are even some parts that I've since found are incorrect. My experience after doing installs is fine, but the biggest issue I found since writing this has been auto-unlocking with a USB drive without the initramfs triggering emergency mode. In the future I'll make a follow-up guide that doesn't involve a ton of painful debugging when I get around to figuring it out.
I recently did a Chimera Linux install with encrypted root-on-ZFS that auto-unlocks with a USB stick and wrote down everything I did on my phone. This is mostly for my own reference but this may be a helpful example for others as well. Fair warning though, this was a lot more involved to set up than Chimera probably usually is.
hardware
- Ethernet connection with DHCP
- 2x1TB NVME drives
nvme0n1andnvme1n1 - 2TB SSD recognized as
sda - 2x4TB HDDs
sdbandsdc, the former containing backup data in LUKS partitionsdb1which needs to be preserved - Intel CPU w/ integrated graphics connected to HDMI monitor
- AMD GPU connected to DP monitor (separated for GPU passthrough)
- Hardware-encrypted pendrive with vfat label
PEEONURWIFE(she's mine now robotnik)
installation
Plug in and mount pendrive:
mkdir /keys
mount /dev/disk/by-label/PEEONURWIFE /keys
Create random hexadecimal keyfiles to be used for rpool, gpool, spool, and some specific datasets:
for i in 'rpool' 'rpool-home' 'gpool' 'spool' 'spool-archive'; do
od -A none -x -N 32 /dev/random | tr -d [:blank:] | tr -d [:cntrl:] > /keys/zfs/sonic/"$i".key
done
Update repositories:
apk add --no-interactive chimera-repo-contrib
apk update
Generate /etc/hostid:
zgenhostid
Initialize disks (confirm disk description above is correct with lsblk first!):
for i in nvme0n1 nvme1n1 sda; do
blkdiscard -f /dev/"$i"
done
wipefs -a /dev/sdc
Create the following GPT partitions on both NVMEs using cfdisk:
550M EFI System (nvme0n1) or Linux extended boot (nvme1n1)
100% Linux filesystem
Create rpool, efi, and boot filesystems on NVMEs:
mkdir /media/root && \
zpool create \
-o ashift=12 \
-o autotrim=on \
-O compression=lz4 \
-O acltype=posixacl \
-O canmount=off \
-O dnodesize=auto \
-O encryption=aes-256-gcm \
-O keylocation=file:///keys/zfs/sonic/rpool.key \
-O keyformat=hex \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/ \
-R /media/root \
rpool \
/dev/nvme0n1p2 \
/dev/nvme1n1p2
zfs create \
-o canmount=off \
-o mountpoint=none \
rpool/ROOT
zfs create \
-o canmount=noauto \
-o mountpoint=/ \
rpool/ROOT/chimera
zfs mount rpool/ROOT/chimera
chmod 755 /media/root
zfs create \
-o reservation=1T \
-o devices=off \
-o encryption=aes-256-gcm \
-o keylocation=file:///keys/zfs/sonic/rpool-home.key \
-o keyformat=hex \
rpool/home
zfs create \
-o quota=1G \
-o devices=off \
-o mountpoint=/root \
rpool/home/root
chmod 700 /media/root/root
zfs create \
-o quota=32G \
-o setuid=off \
-o devices=off \
rpool/var
for i in 'var/log' 'var/log/audit'; do
zfs create \
-o quota=1G \
-o setuid=off \
-o devices=off \
-o exec=off \
-o sync=disabled \
rpool/"$i"
done
for i in 'var/cache' 'tmp'; do
zfs create \
-o quota=4G \
-o setuid=off \
-o devices=off \
-o exec=off \
-o sync=disabled \
-o com.sun:auto-snapshot=false \
rpool/"$i"
done
chmod 1777 /media/root/tmp
mkdir /media/root/efi
mkfs.vfat /dev/nvme0n1p1
mount /dev/nvme0n1p1 /media/root/efi
mkdir /media/root/boot
mkfs.xfs /dev/nvme1n1p1
mount /dev/nvme1n1p1 /media/root/boot
Create spool from non-backup HDD:
mkdir /media/root/srv && \
zpool create \
-o ashift=12 \
-O compression=lz4 \
-O acltype=posixacl \
-O dnodesize=auto \
-O encryption=aes-256-gcm \
-O keylocation=file:///keys/zfs/sonic/spool.key \
-O keyformat=hex \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/srv \
-R /media/root \
spool \
/dev/sdc
zfs create \
-o reservation=1T \
-o encryption=aes-256-gcm \
-o keylocation=file:///keys/zfs/sonic/spool-archive.key \
-o keyformat=hex \
-o devices=off \
-o exec=off \
-o xattr=dir \
spool/archive
zfs create \
-o devices=off \
spool/incus
Create gpool from SSD:
mkdir /media/root/srv/games && \
zpool create \
-o ashift=12 \
-o autotrim=on \
-O compression=lz4 \
-O acltype=posixacl \
-O dnodesize=auto \
-O encryption=aes-256-gcm \
-O keylocation=file:///keys/zfs/sonic/gpool.key \
-O keyformat=hex \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/srv/games \
-R /media/root \
gpool \
/dev/sda
for i in 'nondrm' 'steamapps' 'heroic' 'emulation'; do
zfs create \
-o devices=off \
gpool/"$i"
done
Install chimera and add some config files:
chimera-bootstrap /media/root
echo sonic > /media/root/etc/hostname
mkdir -p /media/root/etc/zfs
mv /etc/hostid /media/root/etc
Mount sdb1, move its data to /srv/archive, then add sdb to spool:
cryptsetup luksOpen /dev/sdb1 crypt
mount /dev/mapper/crypt /mnt
mv -v /mnt/* /media/root/srv/archive/.
umount /mnt && cryptsetup luksClose crypt
wipefs -a /dev/sdb
zpool add spool /dev/sdb
Configure chimera via chroot:
chimera-chroot /media/root
apk update && apk upgrade --available
apk add linux-lts linux-lts-zfs-bin grub-x86_64-efi vim audit
genfstab / >> /etc/fstab
passwd root
mkdir /usr/share/initramfs-tools/scripts/init-premount/
vim /usr/share/initramfs-tools/scripts/init-premount/zfsloadkeyusb
# enter script near end of doc
chmod 755 /usr/share/initramfs-tools/scripts/init-premount/zfsloadkeyusb
vim /usr/share/initramfs-tools/scripts/init-bottom/zfsunmountkeyusb
# ditto
chmod 755 /usr/share/initramfs-tools/scripts/init-bottom/zfsunmountkeyusb
printf '%s/n%s/n%s/n%s/n%s/n%s/n' 'zfs' 'xfs' 'vfat' 'fat' 'nls_cp437' 'nls_iso8859_1' >> /etc/initramfs-tools/modules
update-initramfs -c -k all -v
grub-install --efi-directory /efi
vim /etc/default/grub
# uncomment the line for GRUB_DISABLE_OS_PROBER
update-grub
exit
zfs snapshot rpool/ROOT/chimera@bootstrap
poweroff
Remove chimera liveUSB, re-auth key usb and power on PC. If any of the encrypted datasets fails to mount see the troubleshooting section below.
Do configuration in rebooted system:
useradd charel
passwd charel
usermod -aG wheel,kvm charel
ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime
dinitctl enable syslog-ng
for i in 'rpool' 'spool' 'gpool'; do
zpool set \
cachefile=/etc/zfs/"$i".cache "$i"
done
Take snapshots and reboot into newly installed system:
zfs snapshot rpool/ROOT/chimera@install
zfs snapshot spool/archive@"$(date '+%s')"
reboot
initramfs script
These scripts are an edited version of ones shown on this blog.
zfsloadkeyusb:
#!/bin/sh -e
errmsg() {
echo "ERROR: 1ドル"
exit 2ドル
}
PREREQ="udev"
prereqs() {
echo "$PREREQ"
}
case "1ドル" in
prereqs)
prereqs
exit 0
;;
esac
LABEL=PEEONURWIFE
USB=/dev/disk/by-label/"$LABEL"
echo "Waiting for $USB"
for i in "$(seq 1 20)"; do
if [ -n "$USB" ]; then break; fi
echo -n .; sleep 1
done
echo; sleep 2
if [ -e "$USB" ]; then
mkdir /keys 2>/dev/null || true
mount -t vfat -o ro "$USB" /keys \
|| errmsg "$USB failed to mount!" 1
else
errmsg "$USB not found!" 2
fi
exit 0
zfsunmountkeyusb:
#!/bin/sh -e
errmsg() {
echo "ERROR: \1ドル"
exit \2ドル
}
PREREQ="udev"
prereqs() {
echo "$PREREQ"
}
case "1ドル" in
prereqs)
prereqs
exit 0
;;
esac
if [ -e /keys ]; then
# Unlock other filesystems missed by the debian scripts
for i in 'spool' 'gpool'; do
/usr/bin/zpool import "$i" || errmsg "Could not import \$i!" 1
done
for i in 'rpool/home' 'spool' 'spool/archive' 'gpool'; do
/usr/bin/zfs load-key -r "$i" || errmsg "Could not decrypt \$i!" 2
done
sleep 2; umount /keys && rmdir /keys
fi
exit 0
Troubleshooting
If stuck at busybox prompt, reboot into the liveISO and run the following commands to chroot into the install:
mkdir /keys && mount /dev/disk/by-label/PEEONURWIFE
# may have to force-import pools
for i in 'rpool' 'gpool' 'spool'
zpool import -f "$i"
done
zfs load-key -a
mkdir /media/root
zfs set mountpoint=/media/root rpool/ROOT/chimera
zfs set mountpoint=/media/root/home rpool/home
zfs set mountpoint=/media/root/root rpool/home/root
zfs set mountpoint=/media/root/tmp rpool/tmp
zfs set mountpoint=/media/root/var rpool/var
zfs set mountpoint=/media/root/var/cache rpool/var/cache
zfs set mountpoint=/media/root/var/log rpool/var/log
zfs set mountpoint=/media/root/var/log/audit rpool/var/log/audit
mount /dev/nvme0n1p1 /efi
mount /dev/nvme1n1p1 /boot
chimera-chroot /media/root
# do troubleshooting
update-initramfs -c -k all -v
update-grub
exit
# don't forget to change mountpoints back before restarting!
umount -R /media/root
zfs set mountpoint=/ rpool/ROOT/chimera
zfs set mountpoint=/home rpool/home
zfs set mountpoint=/root rpool/home/root
zfs set mountpoint=/tmp rpool/tmp
zfs set mountpoint=/var rpool/var
zfs set mountpoint=/var/cache rpool/var/cache
zfs set mountpoint=/var/log rpool/var/log
zfs set mountpoint=/var/log/audit rpool/var/log/audit
reboot # if pools were force-imported, will have to force-import again in the initramfs
If it can mount rpool/ROOT/chimera on its own but fails with other filesystems, the mountpoints won't need to be tediously changed and troubleshooting can be done just by logging in as root. Either way, double-check that the stuff added to the initramfs matches what's in this guide and it should work.