Fully Ephemeral DispVM's

Currently Qubes DispVM’s are not fully ephemeral; by default data written to xvda and xvdb is written to the disk in plaintext. When the user sets ephemeral=True data written to xvdc is encrypted with an ephemeral encryption key placed in RAM. If in addition the user sets rw:root rw 0 then writes to xvda are routed to xvdc and thus encrypted. However xvdb is at present always written to the disk in plaintext.

I recently wrote a patch for initramfs that resolves this issue; after application of the patch all data written by a PVH DispVM (including to swap) is encrypted by an ephemeral key. The code and a guide is available at

Hopefully this will find its way to R4.2. The patch has been tested only on the most recent stable R4.1.

19 Likes

this is EPIC!!!

WOW. I saw the title and definitely not expecting this. Up until now Qubes “disposable” has been like browser “private mode”. Adding ephemeral encryption takes this to the next level. This has to be one of the most consequential improvements in the security posture of QubesOS in a long time.

I am going to do a full backup and test this out over the weekend and report back.

4 Likes

@ewokky: if you just want to convince yourself that it works you don’t need a full backup. Instead create a copy of a kernel in /var/lib/qubes/vm-kernels, e.g

cp -rf /var/lib/qubes/vm-kernels/5.10.90-1.fc32 /var/lib/qubes/vm-kernels/testkernel

Then patch testkernel with

sudo sh patch_initramfs.sh testkernel

Now you create an AppVM, say testvm,

qvm-create testvm --template sometemplate --class AppVM --label red

Make the testkernel the kernel for testvm with

qvm-prefs testvm kernel testkernel

Now make xvda, xvdb read-only on the AppVM and set ephemeral mode on for xvdc, i.e

qvm-volume config testapp:root rw 0
qvm-volume config testapp:private rw 0
qvm-volume config testapp:volatile ephemeral 1

Now AppVM is made fully ephemeral. In addition all the DispVM’s that will be subsequently created based on this AppVM will also inherit the ephemeral property. To test this issue

qvm-run --dispvm testapp xterm

and check that this DispVM is fully ephemeral (well it has to because xvda, xvdb are readonly, you can only write to xvdc and xvdc is being encrypted by ephemeral=True). If you don’t want the AppVM to be fully ephemeral simply make xvdb writeable again with qvm-volume config testapp:private rw 1.

The same mechanism works for DispVM’s: if you make a named DispVM use the kernel testkernel and you make its xvda, xvdb read-only and make xvdc ephemeral using qvm-prefs then this DispVM will be made fully ephemeral. This will not work on sys-usb and sys-net since they are HVM and not PVH. If you are concerned about sys-net and sys-usb I suggest running them fully in RAM. I have a solution in mind that I’m working on.

Note however that what I outlined above is a tricky way of using this patch, it’s easy to get things wrong. For example the changes made this way might not be persistent across reboots. Furthermore DispVM that were created before the AppVM was made ephemeral are not made ephemeral – one would have to clone them, delete them and then reclone them back. Patching dispvm.py removes all of this unnecessary confusion, every single PVH DispVM is then made fully ephemeral.

If you are really interested I have a python script that allows one to make only select AppVM’s fully ephemeral in a way that is persistent across reboots (it edits qubes.xml which is arguably even more dangerous than editing dispvm.py :)). If there is interest in that I can upload it too. I just find it a harder way of using the patch … less consistent, and more easy to get wrong, and also less in the spirit of what we actually want: all DispVM’s fully ephemeral. By the way even though all my DispVM’s are now fully encrypted I haven’t noticed an impact on performance.

3 Likes

Wow, great work. Looks very promising and hopefully will be the new default.

Have you ran into any issue after implementing the patch?

4 Likes

As a noob QubesOS user, can you explain a bit more this stuff about “getting written to xvda, xvdb, xvdc”? Also can you shortly explain what is a “PVH” ?

3 Likes

it also makes sense to put logs to some securely disposable place as well?

@BEBF738VD : The only issue that I observed so far is about HVM’s (that are also DispVM’s). After implementing the patch newly created HVM’s might start but will refuse to run any applications from qvm-run. However this is easily fixable just by issuing

qvm-volume config hvmvm:private rw 1

The point is that HVM’s cannot be at present fully ephemerized and this command disables the patch from running in initramfs. I mentioned this in the last note on the github page.

It would be good if somebody could check whether this command needs to be issued on sys-net and sys-usb after patching. They might be not affected because they might be still reading their configuration from qubes.xml. In the next iteration of the patch I’ll try to fix the issue with the HVM’s.

1 Like

My understanding is that @marmarek is intending to utilize a very similar methodology for ephemeral disposable VMs (hence the scaffolding OPs approach uses) but there are some edge cases and UI management items he still has to mull over (as well as the time factor) before moving forward.

B

Just to have links here to related issues, for completeness:

3 Likes

Does someone could explain the underlying process of “Copy to other AppVM” operation ?

in case i apply this fix for “fully ephemeral dispVM’s”, when i copy files between these VMs,
is there any trace possible on disk/dom0 ?

also: does global clipboard fully handled by RAM ?

If you want to create DVMs with no disk trace, I think unman’s approach is the best option if you have enough memory to run the VM from a ram drive Really Disposable Qubes

2 Likes
2 Likes

Very cool, it worked on my old laptop but on the new one dispVMs just fail to start and I cannot even fix it as you suggested. I have to reinstall to fix it, I do not understand why it would work on one laptop HP Spectre and not on another System 76 Lemur.

Anyone have any luck getting this working?

I have followed all of the instructions on github but when I complete the process no apps are running within dispvms.
The dispvms boot but I cannot open any app into them.

I thought it might be because the dispvm.py file that I previously replaced was old and maybe incompatible with qubes 4.2. So I edited the file on line 138 and I managed to stop EVERYTHING from running :joy:.

In qubes version 4.2, this setting will cause all VMs to fail to start, please ask the publisher to update the tutorial.