Wow, βQubes Statelessβ is insanely great! Thanks to @xuy for this simple but powerful solution!
I just tested Qubes Stateless out, using a fresh Qubes 4.1. Dom0 does run stateless from RAM. It works!
This provides a way to do up-to-date and useful stateless amnesic Qubes + Whonix now! Better than Tails, like @ adwβs cheeky βTaiQuWhonDoβ in qubes-issues #2024.
Until a true read-only Qubes Live is built by someone, I plan to now use this Qubes Stateless method in real world scenarios going forward. Thank you @xuy!
Hereβs some further observations, instructions, thoughts:
GRUB Instructions Fix and Boot Process Description:
Step #3 did not work for me, which was:
sudo grub2-mkconfig | sudo tee /boot/efi/EFI/grub.cfg
When I rebooted, the GRUB boot config had not changed and Qubes OS just did a typical normal boot.
Some researching led me to find that @xuyβs instruction was maybe only for UEFI booted systems, where my system boots via Legacy BIOS.
So I fixed this step by changing step #3 into these two commands:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo grub2-mkconfig -o /boot/efi/EFI/grub.cfg
I believe this changes the GRUB boot config to simultaneously work for both types of systems (both UEFI and Legacy BIOS).
This fix caused my next reboot to break out of the typical normal Qubes OS boot process, and prompts you to βPress Enter for maintenanceβ, which then drops you into a Dracut command line.
Note that this boot process break happens AFTER entering the Qubes OS disk decryption passphrase. So everything boots normally until after you enter your Qubes OS disk decryption passphrase (if you have full disk encryption enabled).
After decrypting the disk, and you βPress Enter for maintenanceβ, the system drops into a Dracut shell and you proceed by entering the exact commands @xuy provided in Step #4:
umount /sysroot
mkdir /mnt
mount /dev/mapper/qubes_dom0-root /mnt
mount -t tmpfs -o size=100% none /sysroot
cp -a /mnt/* /sysroot
Note that the last βcpβ (copy) step can take a little while (1-4 minutes) to complete, as it is copying all of Dom0 into RAM (I believe).
Pressing Ctrl + D exits you out of the Dracut command line and continues booting into Qubes Stateless Dom0 from RAM.
Once booted up and logged in, I noticed some interesting thingsβ¦
Lower RAM Optimization:
First, I noticed that the Dom0 RAM partition only takes up ~3.5GB for me initially, which grew to ~5.5GB with some use. Maybe it would grow further, but I didnβt seem to need 10GB of RAM allocated to Dom0, so I rebooted into normal Qubes OS mode, and repeated Step #2 & Step #3, and lowered the Dom0 RAM partition in the GRUB boot config to 6GB (dom0_mem=max:6000M). I rebooted into Qubes Stateless mode and it seemed to still work fine with only 6GB allocated to Dom0.
This means that one can explore and choose a higher or lower Dom0 RAM partition size for better RAM efficiency on lower RAM systems. If you only have 4GB of total system RAM, then you could still probably bootup Qubes Stateless. However, the additional RAM youβll then need depends on the number and type of additional qubes and apps you want to run once booted up. Note that not all system RAM should be allocated to Dom0. RAM used by other qubes is not to be confused with the Dom0 RAM partition size that you set in the GRUB boot config with Step #2.
VM Pool on Disk is still Accessible & Writable:
The follow-on volume instructions provided @xuy show you one way to configure file-backed storage for your VMs, in the βvarlibqubesβ pool, which is located in the Dom0 directory path /var/lib/qubes.
However, in testing, I didnβt have any secondary storage setup with such pre-existing VM storage loaded. So I instead played with some other options.
You can simply create new qubes and they will exist and work temporarily in RAM, but then you will loose them by default upon shutdown. That may be okay if you donβt want to save anything from your work session.
When creating new qubes in RAM, you can choose from a couple storage pools, which work differently.
If you create a new qube in the βvarlibqubesβ pool, and you havenβt implemented @xuyβs secondary storage symlinks, then your new qubeβs storage will be file-backed in RAM at /var/lib/qubes and will be completely lost upon shutdown by default.
If you create a new qube in the βvm-poolβ pool, then your new qubeβs storage will be written to your boot driveβs qubes storage pool, and the data will be saved to your boot drive, but the qube in Qube Manager will disappear upon shutdown, due to the metadata (in qubes.xml I believe) being located in the Dom0 RAM partition and being wiped. However, if you try to recreate a qube with the same name using the same storage pool in the future, Qube Manager throws an error but then seems to overwrite the old qube data if you try again, so be careful and donβt assume your data will survive this method unless you really know what you are doing and take advanced precautions.
Using Qubes Stateless and saving your data while using it is best done with adding a secondary storage location as @xuy describes as file-backed, or Qubes documentation describes as pool-backed, or via online cloud storage if that works with your threat model. But, for advanced users, I just wanted to point out that RAM storage and boot drive storage of your qubes data technically do work and these are available for expert data management use cases, or alternatively if one just does not care to save any local data while using Qubes Stateless.
Qubes Stateless Does NOT Seem to Work with a Read-Only Boot Drive:
I tried booting Qubes Stateless on a read-only USB connected drive and some errors did not allow it to work. The boot process of Qubes OS in general seems to demand write access in the initial stages of startup.
First, the LUKS FDE (full drive encryption) seems to demand write access to pass, which can be bypassed by simply not using drive encryption (not ideal).
Second, in @xuyβs Step #4, the following command seems to throw an error when using a read-only boot drive, but seems to work when write access is enabled to the boot drive:
mount /dev/mapper/qubes_dom0-root /mnt
THROWS ERROR:
mount: /mnt: canβt read superblock on /dev/mapper/qubes_dom0-root.
When booting the drive with write access, I was able to pull out the USB drive once Dom0 booted up to the user login screen, seemingly without encountering any unexpected errors after that.
One time, during some boot testing I was doing, I accidentially borked my Dom0 (i forget how, but it seemed unexpected), and had to reinstall from scratch. So a true read-only Qubes Live boot drive would be much more ideal for protection and security, compared to needing to give write access to the boot drive.
Dual Boot Qubes and Qubes Stateless:
It was implied by @xuyβs post, but just wanted to mention this insight for those who may have misunderstood this concept, that:
Qubes Stateless kind of creates an optional βdual bootβ mode for Qubes. One, the normal fully stateful mode. The other, the new stateless dom0 mode.
The normal stateful mode becomes the βbaseβ for configuring each live boot of Qubes Stateless. You can reboot into Qubes normal mode, change and reconfigure your Qubes environment, then reboot into Qubes Stateless and have your newly configured Qubes environment running as Qubes Stateless.
This βdual modeβ or βdual bootβ for Qubes is pretty neat, although somewhat less ideal for security, compared to a true read-only Qubes Live implementation.
Automated Qubes Stateless Booting Considered Desirable:
Automating the inconvenient manual boot Step #4 would be great!
These commands:
umount /sysroot
mkdir /mnt
mount /dev/mapper/qubes_dom0-root /mnt
mount -t tmpfs -o size=100% none /sysroot
cp -a /mnt/* /sysroot
@ xuy mentions the idea of implementing this automation as a Dracut Module.
@ alzer89 mentions the idea of implementing this automation as a SystemD Service.
However best, it would be awesome to have the code made available for automating this Qubes Stateless boot process, as it gets bothersome when repeating this manually multiple times per day.
Qubes Stateless to Qubes Live:
It would be great to see a truly read-only Qubes Live implementation come out of this innovative Qubes Stateless method somehow!
This Qubes Stateless implementation seems very very close already to a read-only Qubes Live, suitable for everyday use at least from advanced users initially, except for the read-only drive errors during boot and the needed automation of the tmpfs steps.
Iβd love to be able to boot from a read-only Qubes Live using read-only media.
@51lieal and All Other Community Members - YES! - as we now seem quite close, letβs start a technical discussion about extending this excellent initial work of Qubes Stateless into a truly working read-only Qubes Live! Would this thread, a new forum thread, or a GitHub issue be best?