Skip to main content
lotsaspaghetti

Chimera Linux Install

May 28, 2025

Tags: 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

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.


AltStyle によって変換されたページ (->オリジナル) /