How to Encrypt KVM qcow2 Disks with LUKS and Ceph RBD – Step‑by‑Step Guide
This guide explains how to use LUKS to encrypt KVM qcow2 virtual machine disks, create and define libvirt secrets, configure encrypted volumes, and apply the same technique to Ceph RBD storage, providing full command‑line examples and XML snippets for a secure virtualization setup.
kvm qcow2 disk encryption
About LUKS encryption
LUKS implements a platform‑independent standard disk format for encrypting block devices, supporting multiple key slots (up to 8 in LUKS1 or 32 in LUKS2) and allowing easy password changes without re‑encrypting the whole disk.
LUKS encryption for KVM virtual machine disks
Before libvirt 4.5, qcow encryption was also supported, but it has been deprecated. The following steps show how to use LUKS to encrypt an existing VM disk.
qemu-img convert -O qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 -f qcow2 test.qcow2 fw-encry.qcow2Encryption format "default" and "qcow" are no longer used for creating encrypted volumes. The example below demonstrates converting a qcow2 disk to a LUKS‑encrypted disk.
Create a 20G empty LUKS disk.
qemu-img create -f luks --object secret,data=123,id=sec0 -o key-secret=sec0 fw.luks 20GConvert the existing qcow2 disk to a LUKS disk (the target must exist).
qemu-img convert --target-image-opts \
--object secret,data=123,id=sec0 -f qcow2 fw.qcow2 -n \
driver=luks,file.filename=fw.luks,key-secret=sec0Create a secret XML file (UUID will be generated automatically if omitted).
vim volume-secret.xml
<secret ephemeral='no' private='yes'>
<uuid>92f35b9e-c845-47e1-b5a6-f2036a706866</uuid>
<description>Super secret name of my first puppy</description>
<usage type='volume'>
<volume>/home/kvm/images/fw.luks</volume>
</usage>
</secret>Define the secret. virsh secret-define volume-secret.xml Set the secret password value.
# MYSECRET=`printf %s "123" | base64`
# virsh secret-set-value dc057b2b-6a7d-4dba-b76e-37a458448765 $MYSECRET
Secret value setEdit the VM's <disk> section to add the secret field.
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/home/kvm/images/fw.luks'/>
<target dev='vda' bus='virtio'/>
<encryption format='luks'>
<secret type='passphrase' uuid='dc057b2b-6a7d-4dba-b76e-37a458448765'/>
</encryption>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>When creating a LUKS volume, you can specify the cipher and IV generation algorithm. By default, QEMU uses aes-256-cbc with essiv IV generation and sha256 hashing.
<volume>
<name>twofish.luks</name>
<capacity unit='G'>5</capacity>
<target>
<path>/var/lib/libvirt/images/demo.luks</path>
<format type='raw'/>
<encryption format='luks'>
<secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/>
<cipher name='twofish' size='256' mode='cbc' hash='sha256'/>
<ivgen name='plain64' hash='sha256'/>
</encryption>
</target>
</volume>Start the virtual machine: virsh start vm To copy the encrypted disk to another host, repeat the secret creation steps on the new host.
Note: The password must match the one defined on the host.
If the <encryption> field is removed from the boot disk, the VM will fail to find the boot device.
<encryption format='luks'>
<secret type='passphrase' uuid='dc057b2b-6a7d-4dba-b76e-37a458448765'/>
</encryption>Encrypted data disks cannot be mounted directly; they must be mapped via cryptsetup:
cryptsetup luksOpen /dev/vdb fwkvm using ceph rbd disk encryption
Define secret
Generate secret (run on all Ceph nodes).
Create secret.xml:
cd /etc/libvirt/qemu
cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
<usage type='ceph'>
<name>client.libvirt secret</name>
</usage>
</secret>
EOFDefine the secret and note its UUID.
virsh secret-define --file secret.xml
# Example output: Secret 01a0ba00-f277-48bb-b937-9001ec91f53e createdObtain the client.libvirt key and save it.
ceph auth get-key client.libvirt | tee client.libvirt.keySet the secret password.
virsh secret-set-value --secret 01a0ba00-f277-48bb-b937-9001ec91f53e --base64 $(cat client.libvirt.key)Edit the VM configuration to use the secret for the RBD disk.
<devices>
<emulator>/usr/bin/kvm-spice</emulator>
<disk type='network' device='disk'>
<driver name='qemu' type='raw'/>
<auth username='libvirt'>
<secret type='ceph' uuid='01a0ba00-f277-48bb-b937-9001ec91f53e'/>
</auth>
<source protocol='rbd' name='libvirt-pool/fw-system'>
<host name='node1' port='6789'/>
<host name='node2' port='6789'/>
<host name='node3' port='6789'/>
</source>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
</devices>Start VM
Define and start the virtual machine:
virsh define vm.xml
virsh start vmSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
