Hybrid Encryption With CachyOS
How I adapted the hybrid encryption described here to work with CachyOS installed in ZFS.
Introduction
I've decided to try CachyOS. It's nice that it was willing to install in an encrypted zfs. This will make some things easier in setting up the hybrid encryption unlocking, but since CachyOS uses a different system to make the initrd, there will need to be some changes too.
Install the OS
Just do the normal install, but with manual partitioning. Create these partitions:
1
EFI
2G
CachyOS defaults to using 2GB for the EFI partition. I think this is because they use the EFI partition as /boot
2
root-key
17MB
Leave unformatted for now, will be LUKS for unlocking zfs
3
crypt-swap
32GB
Leave unformatted for now. At least size of RAM (if you want hibernate). This will be encrypted swap.
4
zfsroot1
remainder of disk
The rest of the disk. Select zfs, use as "/" and turn on encryption with a temporary password.
When the install is done, but before rebooting, make a zfs snapshot
sudo zfs snapshot -r zpcachyos@hybrid1If you have data you want to load (like your /home from an old installation), now is a good time to zfs receive it.
Then reboot into the system and make sure everything is working ok. You can use the machine now like normal, and continue these steps whenever you are ready. For now you need to put in the temporary password for the zfs on boot.
Label the partitions
The unformatted partitions didn't get names, but the names do make some things a little easier. So lets use parted to set the names. I leave it to you to know your disk names and partition numbers. For this example, we will name the root-key partition on /dev/nvme3n1p2
parted /dev/nvme3n1
name 2 root-key
quitCreate the key
Now we need to create the key that we will be using to unlock the zfs.
Make the root-key LUKS space
Now we will create the LUKS volume in the root-key partition. We will also add a backup password now so we have 2 working passwords and are less likely to lose access by making some mistake. Then we will copy our root-key into this LUKS volume.
Make the encrypted swap space
Now we will create the encrypted swap space. We will use the key that we generated above to unlock the swap so we don't need to type in another password.
This should show the info for that partition, like:
Make the script to go in the initrd
CachyOS uses mkinitcpio to create the inird. This works a bit differently from other initrd systems and needs its own special setup. This needs the script to run during initrd, a script to "install" that one when the initrd is being installed. Lets start with that install script
Paste in:
And now make the hook script (the one that will end up in the initrd). This script will run after the root-key LUKS has been opened, and will copy the root-key file out so it is ready for zfs to use. It will also open the LUKS for the swap with that key to make sure it is ready before the initrd gets to trying to resume from hibernate.
There is also a cleanup function that will be called at the end of initrd before switching root to the real filesystem. We will delete the key in this step just to make sure it isn't hanging around in RAM when we don't need it anymore.
Paste in
And finally we need to add our new script to the config so it gets used.
Find the HOOKS= line, and add encrypt and rootkey, so it looks like this:
Configure the kernel command line
Get the UUID for the root-key partition
And set the cmdline in the bootloader config /boot/loader/entries/linux-cachyos.conf
and paste in:
And this one is used for UKI kernel images
Paste in
Test reboot
Then we will make a snapshot and then recreate the initrd, and reboot to test.
And reboot to test. If it all worked, it should ask for the password for root-key, then the password for the zpool, and then should boot ok. If it booted ok, you should have /dev/mapper/swap-crypt open already.
If that's good, then we add the swap into fstab.
And add this line:
Save that and reboot. This time, when done you should have swap working. This should let you hibernate and resume from hibernation.
Once that is working, we will want to change zfs so we don't need to type in the password for root-key and a password for zfs too.
Change zfs key
This is the dangerous part. If this goes wrong (which is unlikely but not impossible), recovery could be quite a pain. Do whatever are your normal backup procedures before continuing.
We will replace the password with the key from our LUKS root-key volume.
Reboot again for final testing. If it boots fine, and only needed a single password to unlock the encrypted filesystems, then we are good. The last step is to remove the /root-key file so the only copy is the one in the root-key partition.
Setup backups
And as a final touch, I decided that it would be a good idea to backup the EFI fileystem and the root-key when backing up the system. The easy way to do this was to create a space in ZFS for both of those, and just copy them on boot so those copies get backed up with the rest of the zpool. We don't want the backup of the root-key encrypted with zfs, because it contains the key we might need to unlock the zfs encryption.
So we will create these zfs spaces:
Then we will create the backup script:
And paste in:
And we want that to run a little while after a reboot. Lets say 2 minutes, which should keep us from backing it up if it is broken, and should keep the backup from slowing boot. I previously did this with cron, but arch isn't all that interested in keep us old gray-beards comfortable, so it takes extra steps to make cron work. So instead, we will use a systemd timer. This will also let us run the backup script daily. That's probably not needed, but I wanted to see if it really does work, and surprise! it does.
A systemd timer set needs two more files, a service unit file, and a timmer file to trigger the service. So first lets make the service. Paste this into /etc/systemd/system/backup-efi-and-key.service
And paste this into /etc/systemd/system/backup-efi-and-key.timer
And that should be it, we should be able to boot and unlock all the encrypted filesystems with a single password on boot. It should be easy to have tang unlock everything automatically over the network without a password, or use a yubikey to unlock. It should even be possible to set up all of these in parallel so you can unlock with whatever process you find most conveneient.
Last updated