Encrypt VM disk upon VM creation


I am trying to encrypt VM disk upon VM creation. Any clue how this could be done from OpenNebula as a part of VM template where disk formate is qcow2

Thanks in advance

this may help: Images — OpenNebula 6.4.0 documentation

@tinova thank you for your reply.

I exactly followed the steps on the documentation page you sent.
I encrypted the OS image used in one VM template. Then I instantiated one VM from that template.
However, the VM is running normally but OS can’t be bootable. it says :

" Booting from Hard Disk
Boot failed: not a bootable disk
No bootable device. "

Then Tried to make a specific usage for the secret, so I added the image path to the secret XML definition file as follows, but OS did not boot as well.

<secret ephemeral='no' private='yes'>
   <description>LUKS Sample Secret</description>
   <usage type='volume'>
      <volume> /var/lib/one/datastores/102/Windows_image</volume>

Any clue about the reason?
might it be related to the inability to decrypt the VM disk to read from it?

It looks like the VM indeed cannot read the encrypted disk.

Did you define the secret in the hypervisors?

Hi @tinova ,
Thank you for your reply. Yes, I defined the secret in the hypervisors.

Basically, I want to encrypt an image that is being used for instantiating new VMs. So, first I created and encrypted an empty image of raw formate then I converted the already existing unencrypted image whose formate is qcow2 to the new empty encrypted image by the following command:

qemy-img convert …

Then I compared them by qemu-img compare …, and they were identical.

Then, I defined the secret in the hypervisor on which the VM was instantiated.
basically, I executed two versions of defining the secret and setting its value.

First, I executed the following by oneadmin, but the secret was not recognized when I execute virsh secret-list by oneadmin but it was recognized by other user accounts.

virsh -c qemu:///system secret-define secret.xml
virsh -c qemu:///system secret-set-value f52a81b2-424e-490c-823d-6bd4235bc57 "$(echo secret-passphrase | base64)"

Then, I executed the following by oneadmin, and the secret got recognized by oneadmin when I executed virsh secret-list later.

virsh secret-define secret.xml
virsh secret-set-value f52a81b2-424e-490c-823d-6bd4235bc57 "$(echo secret-passphrase | base64)"

However, the error was not resolved in both cases (i.e., I got “No bootable device” in both cases)

I am wondering how the decryption will be occurred without specifying the secret UUID in the VM XML definition, for this reason, I tried to add the following in the VM definition but I couldn’t find the context variables provided by OpenNebula and it is supposed to be used for defining the secret UUID.

<encryption format='luks'>
  <secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc57'/>

What you describes is similar to one use case in our QA certification.

The only difference is probably the use of qemu-img convert. Can you try creating an empty image with qemu-img create? Basically just following the documentation as verbatim as possible.

If that doesn’t work I guess the next step is to try and replicate the error without OpenNebula, using virsh commands.

Hi @tinova

Thank you for your reply!

I followed the documentation, but it did not work.

Then, I tried to create a VM using an encrypted disk using virsh and qemu commands; I created encrypted empty image, created the secret XML, defined the secret, and set a value for the secret which was used for encrypting the image in the beginning.

However, I got the same problem: the VM is not bootable. This means the hypervisor can not read the secret to decrypt the VM disk. When I started the VM (virsh start VM_name), I got the following error message; even i am sure that password is identical to that used for creating the image

Error starting domain: internal error: process exited while connecting to monitor: 2022-08-22T08:42:52.109337Z qemu-system-x86_64: -blockdev {“node-name”:“libvirt-2-format”,“read-only”:false,“driver”:“luks”,“key-secret”:“libvirt-2-format-luks-secret0”,“file”:“libvirt-2-storage”}: Invalid password, cannot unlock any keyslot

Traceback (most recent call last):
File “/usr/share/virt-manager/virtManager/asyncjob.py”, line 75, in cb_wrapper
callback(asyncjob, *args, **kwargs)
File “/usr/share/virt-manager/virtManager/asyncjob.py”, line 111, in tmpcb
callback(*args, **kwargs)
File “/usr/share/virt-manager/virtManager/object/libvirtobject.py”, line 66, in newfn
ret = fn(self, *args, **kwargs)
File “/usr/share/virt-manager/virtManager/object/domain.py”, line 1279, in startup
File “/usr/lib/python3/dist-packages/libvirt.py”, line 1234, in create
if ret == -1: raise libvirtError (‘virDomainCreate() failed’, dom=self)
libvirt.libvirtError: internal error: process exited while connecting to monitor: 2022-08-22T08:42:52.109337Z qemu-system-x86_64: -blockdev {“node-name”:“libvirt-2-format”,“read-only”:false,“driver”:“luks”,“key-secret”:“libvirt-2-format-luks-secret0”,“file”:“libvirt-2-storage”}: Invalid password, cannot unlock any keyslot

Any information about the reason here is appreciated!

apologies for the slow turnaround.

i cannot reproduce your problem, but i’ll try to redo the setup.

“Invalid password, cannot unlock any keyslot” is the relevant error message, I see you are trying to perform this operation without OpenNebula first, which is the right approach.

you can refer to libvirt doc to clarify concepts, this may help: libvirt: Secret XML format