Qubes OS Installation - Detached encrypted boot and header

@51lieal Thanks a lot for this writeup. I’ve added some markdown formatting to make commands more readable. Hope that’s ok.

1 Like

How to update to the latest kernel? I have installed the latest kernel but still it’s using old kernel. I have changed in qube manager global settings to use by default 5.16 but still it’s using 5.10.

I read this doc

When you set kernel in global settings, it only apply for domU, for dom0 you need to manually enter the kernel version you want in grub menu, or use ‘0’ value in GRUB_DEFAULT for the first entry in grub which defaulty the newest kernel installed.

1 Like

Do you mean, instead of


in /etc/default/grub, to put


Impressive! I think I did it wrong. After rebooting, it prompts for passphrase like it should. But when I enter the passphrase, it does nothing. I let it sit for longer than two minutes. The iter-time is 10000 which should be 10 seconds.

One point of confusion was whether to leave $uuidB or $uuidR verbatim as they are, or substitute them for the alphanumeric ID. In other words, I didn’t always know whether to leave the variable as a variable, or substitute the variable for the exact ID it references. I substituted them for exact IDs in /mnt/sysroot/etc/fstab and in the generated initramfs. Everywhere else, I left them verbatim as variables.

Another point of confusion was which column to change in crypttab. Is “root device value” the first column, or the second column? I read the man7.org page about crypttab(5) and a few other articles explaining it, but none of them make clear enough which column is the “device value.” This may seem obvious and a stupid question but I’m stumped.

Finally, I had an error at vgchange -a n qubes_dom0 . The error said:

/usr/sbin/dmeventd: stat failed: No such file or directory
WARNING: Failed to unmonitor qubes_dom0/root-pool.
0 logical volume(s) in volume group "qubes_dom0" now active

When I run lsblk, it shows partitions on the flash drive but nothing on the internal drive. The internal drive had partitions at some point during the process, but they apparently all got obliterated somehow. I wonder whether it happened at cryptsetup luksErase /dev/nvme0n1 since it warned me the drive would become unusable :woman_shrugging:

Where can I go from here?

actually there’s some command that you should’nt do, but even if you do it have no harm, so I think you must fail somewhere.

I’ve decided to rewrite a complete full guide about this step in Playing with qubes part 2

actually wipefs -a is enough, it would erase crypt metadata too.
you may want to try using iter 1 first for practicing while wait for me to rewrite better guide.

$500 crypto to anyone who can clear this guide and publish a idiot proof spoon fed, step by step guide on how to do detached boot and header thing


I am 100% down to match that offer so bounty is $1000


correct me if i am wrong but there is still the problem with our current new disks ssd / nvme and iirc even newer hdds having the key remaining in their little extra cache after use.
Forgive me that i do not have the correct technical terms for all this but i think as long as we do not know how this caches work and how to proper clear them with each shutdown, no one should feel 100% secure, of course it all is depending on the individual thread vector.

Instead of creating luks header on disk with:
[anaconda /] cryptsetup luksOpen /dev/nvme0n1 luks
And later removing it from disk as described in this guide you can just create luks with specified key file:

cryptsetup --key-file=/dev/mapper/lukskey --keyfile-offset=offset --keyfile-size=size luksFormat /dev/sda --offset 32768 --header /mnt/header.img
cryptsetup open --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=offset --keyfile-size=size /dev/sda enc

Then there won’t be any traces left on the disk.

Also it’s better to specify drives by their ID instead of arbitrary name like /dev/nvme0n1 or /dev/sda3:

cryptsetup open /dev/disk/by-id/usbdrive-part2 cryptboot
cryptsetup --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=’‘offset’’ --keyfile-size=’‘size’’ open /dev/disk/by-id/harddrive enc
usbdrive is your USB drive by-id, and harddrive is your main hard drive by-id.

Also correction to the guide:
You need to leave 5-10% free space in VG in case it’ll be needed to extend pools:
lvcreate -T -l +90%FREE qubes_dom0/vm-pool
Why doesn't Qubes 4.1 use full disk space (LVM)? - #3 by marmarek
Best Way To Resize Dom0 Pool? - #9 by brendanhoar
LVM metadata problem - Free space in thin pool reached threshold - #3 by user-a9dc9a0d

you are correct, that’s why i decided to write full guide and using tmpfs for dom0 and dispvm. that would be part 4 of Running dom0 and DispVM in tmpfs.

the problem is if we did detach header before installation, anaconda would’nt understand that. try it, it would fail.

that’s correct, in my new quick install here, I already leave 10% free space

Just donate to qubes and post it here, I’m sure I will prioritize this, and complete the Playing with Qubes.

1 Like

i don’t see how that would protect from the unknowns of the manufacturer on disk device caching

Deleted, got it wrong.

Actually I only answer to this statement.

Running dom0 and dispvm from ram is decreasing thread vector.

For how this cache works I also don’t know, someday I’ll learn about this.

I just practiced again and found an error I forgot to post last time. It’s the very first error I encounter in the process. Here’s the error along with the few commands just before it:

[anaconda root@localhost /]# pvcreate /dev/mapper/luks
Physical volume "/dev/mapper/luks" successfully created.

[anaconda root@localhost /]# vgcreate qubes_dom0 /dev/mapper/luks
Volume group "qubes_dom0" successfully created

[anaconda root@localhost /]# lvcreate -n swap -L 4G qubes_dom0
Logical volume "swap" created.

[anaconda root@localhost /]# lvcreate -T -L 20G qubes_dom0/root-pool
Thin pool volume with chunk size 64.00 KiB can address at most 15.81 TiB of data.
/usr/bin/dmeventd: stat failed: No such file or directory
WARNING: Failed to monitor qubes_dom0/root-pool.
Logical volume "root-pool" created.

The other error I posted before also pertains to dmeventd. Even if nobody here has a solution, it helps to document and share errors.

1 Like

I’ve tried it out by configuring LUKS like this:

dd if=/dev/urandom of=key.img bs=32M count=1
cryptsetup luksFormat key.img
cryptsetup open key.img lukskey
dd if=/dev/zero of=header.img bs=16M count=1
cryptsetup --key-file=/dev/mapper/lukskey --keyfile-offset=0 --keyfile-size=8388608 luksFormat /dev/sda --offset 32768 --header header.img
cryptsetup open --header header.img --key-file=/dev/mapper/lukskey --keyfile-offset=0 --keyfile-size=8388608 /dev/sda qubes_dom0

pvcreate /dev/mapper/luks
vgcreate qubes_dom0 /dev/mapper/luks
lvcreate -n swap -L 512M qubes_dom0 
lvcreate -T -L 5G qubes_dom0/root-pool 
lvcreate -T -l +100%FREE qubes_dom0/vm-pool
lvcreate -V5G -T qubes_dom0/root-pool -n root
lvcreate -V4G -T qubes_dom0/vm-pool -n vm
mkfs.xfs /dev/qubes_dom0/vm

And installer can see the disk configuration created this way just fine when I press on “Reload storage configuration from disk”:

Or will it fail at a later stage?

For a key, I recommend /dev/random instead of /dev/urandom. The former ensures high entropy. (though I don’t know the answer to the rest of your question)

If you’re talking about this:
dd if=/dev/urandom of=key.img bs=32M count=1
Then I think it shouldn’t really matter because cryptsetup will use /dev/random when it’ll initialize a LUKS partition here:
cryptsetup luksFormat key.img
And the key used to encrypt /dev/sda later won’t be raw key.img file created from /dev/urandom but the decrypted key.img file that was encrypted with key from /dev/random.