mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-06 09:55:46 +00:00
encryption: Add luks parsing for storageencryption
Add parse and format of the luks/passphrase secret including tests for volume XML parsing. Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
47e88b33be
commit
9bbf0d7e64
@ -248,7 +248,12 @@
|
|||||||
<p>
|
<p>
|
||||||
This secret is a general purpose secret to be used by various libvirt
|
This secret is a general purpose secret to be used by various libvirt
|
||||||
objects to provide a single passphrase as required by the object in
|
objects to provide a single passphrase as required by the object in
|
||||||
order to perform its authentication.
|
order to perform its authentication. For example, this secret will
|
||||||
|
be used either by the
|
||||||
|
<a href="formatstorage.html#StorageVol">storage volume</a> in order to
|
||||||
|
provide the passphrase to encrypt a luks volume or by the
|
||||||
|
<a href="formatdomain.html#elementsDisks">disk device</a> in order to
|
||||||
|
provide the passphrase to decrypt the luks volume for usage.
|
||||||
<span class="since">Since 2.1.0</span>. The following is an example
|
<span class="since">Since 2.1.0</span>. The following is an example
|
||||||
of a secret.xml file:
|
of a secret.xml file:
|
||||||
</p>
|
</p>
|
||||||
|
@ -56,8 +56,20 @@
|
|||||||
the <code>secret</code> element is not present during volume creation,
|
the <code>secret</code> element is not present during volume creation,
|
||||||
a secret is automatically generated and attached to the volume.
|
a secret is automatically generated and attached to the volume.
|
||||||
</p>
|
</p>
|
||||||
|
<h3><a name="StorageEncryptionLuks">"luks" format</a></h3>
|
||||||
|
<p>
|
||||||
|
The <code>luks</code> format is specific to a luks encrypted volume
|
||||||
|
and the secret used in order to either encrypt or decrypt the volume.
|
||||||
|
A single <code><secret type='passphrase'...></code> element is
|
||||||
|
expected. The secret may be referenced via either a <code>uuid</code> or
|
||||||
|
<code>usage</code> attribute. One of the two must be present. When
|
||||||
|
present for volume creation, the secret will be used in order for
|
||||||
|
volume encryption. When present for domain usage, the secret will
|
||||||
|
be used as the passphrase to decrypt the volume.
|
||||||
|
<span class="since">Since 2.1.0</span>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2><a name="example">Example</a></h2>
|
<h2><a name="example">Examples</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here is a simple example, specifying use of the <code>qcow</code> format:
|
Here is a simple example, specifying use of the <code>qcow</code> format:
|
||||||
@ -67,5 +79,17 @@
|
|||||||
<encryption format='qcow'>
|
<encryption format='qcow'>
|
||||||
<secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' />
|
<secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' />
|
||||||
</encryption></pre>
|
</encryption></pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Here is a simple example, specifying use of the <code>luks</code> format
|
||||||
|
where it's assumed that a <code>secret</code> has been defined using a
|
||||||
|
<code>usage</code> element with a <code>id</code> of "luks_example":
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<encryption format='luks'>
|
||||||
|
<secret type='passphrase' usage='luks_example'/>
|
||||||
|
</encryption>
|
||||||
|
</pre>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<choice>
|
<choice>
|
||||||
<value>default</value>
|
<value>default</value>
|
||||||
<value>qcow</value>
|
<value>qcow</value>
|
||||||
|
<value>luks</value>
|
||||||
</choice>
|
</choice>
|
||||||
</attribute>
|
</attribute>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
@ -81,6 +82,7 @@
|
|||||||
<value>fat</value>
|
<value>fat</value>
|
||||||
<value>vhd</value>
|
<value>vhd</value>
|
||||||
<value>ploop</value>
|
<value>ploop</value>
|
||||||
|
<value>luks</value>
|
||||||
<ref name='storageFormatBacking'/>
|
<ref name='storageFormatBacking'/>
|
||||||
</choice>
|
</choice>
|
||||||
</define>
|
</define>
|
||||||
|
@ -2414,6 +2414,12 @@ qemuProcessInitPasswords(virConnectPtr conn,
|
|||||||
!virDomainDiskGetSource(vm->def->disks[i]))
|
!virDomainDiskGetSource(vm->def->disks[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (vm->def->disks[i]->src->encryption->format !=
|
||||||
|
VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT &&
|
||||||
|
vm->def->disks[i]->src->encryption->format !=
|
||||||
|
VIR_STORAGE_ENCRYPTION_FORMAT_QCOW)
|
||||||
|
continue;
|
||||||
|
|
||||||
VIR_FREE(secret);
|
VIR_FREE(secret);
|
||||||
if (qemuProcessGetVolumeQcowPassphrase(conn,
|
if (qemuProcessGetVolumeQcowPassphrase(conn,
|
||||||
vm->def->disks[i],
|
vm->def->disks[i],
|
||||||
|
@ -1027,8 +1027,7 @@ virStorageBackendCreateQemuImgCheckEncryption(int format,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("qcow volume encryption unsupported with "
|
_("volume encryption unsupported with format %s"), type);
|
||||||
"volume format %s"), type);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,12 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
|
|||||||
case VIR_STORAGE_FILE_QCOW2:
|
case VIR_STORAGE_FILE_QCOW2:
|
||||||
(*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
|
(*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
|
case VIR_STORAGE_FILE_LUKS:
|
||||||
|
(*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_STORAGE_ENCRYPTION_FORMAT_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +321,8 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
|
|||||||
if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
|
if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
|
||||||
vol->target.format == VIR_STORAGE_FILE_QCOW2)
|
vol->target.format == VIR_STORAGE_FILE_QCOW2)
|
||||||
vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
|
vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
|
||||||
|
if (vol->target.format == VIR_STORAGE_FILE_LUKS)
|
||||||
|
vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
|
||||||
}
|
}
|
||||||
vol->target.features = meta->features;
|
vol->target.features = meta->features;
|
||||||
meta->features = NULL;
|
meta->features = NULL;
|
||||||
|
@ -43,7 +43,7 @@ VIR_ENUM_IMPL(virStorageEncryptionSecret,
|
|||||||
|
|
||||||
VIR_ENUM_IMPL(virStorageEncryptionFormat,
|
VIR_ENUM_IMPL(virStorageEncryptionFormat,
|
||||||
VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
|
VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
|
||||||
"default", "qcow")
|
"default", "qcow", "luks")
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
|
virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
|
||||||
|
@ -48,6 +48,7 @@ typedef enum {
|
|||||||
/* "default" is only valid for volume creation */
|
/* "default" is only valid for volume creation */
|
||||||
VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
|
VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
|
||||||
VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
|
VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
|
||||||
|
VIR_STORAGE_ENCRYPTION_FORMAT_LUKS,
|
||||||
|
|
||||||
VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
|
VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
|
||||||
} virStorageEncryptionFormatType;
|
} virStorageEncryptionFormatType;
|
||||||
|
45
tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
Normal file
45
tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>encryptdisk</name>
|
||||||
|
<uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid>
|
||||||
|
<memory unit='KiB'>1048576</memory>
|
||||||
|
<currentMemory unit='KiB'>524288</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='luks'/>
|
||||||
|
<source file='/storage/guest_disks/encryptdisk'/>
|
||||||
|
<target dev='vda' bus='virtio'/>
|
||||||
|
<encryption format='luks'>
|
||||||
|
<secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
|
||||||
|
</encryption>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
|
||||||
|
</disk>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='luks'/>
|
||||||
|
<source file='/storage/guest_disks/encryptdisk2'/>
|
||||||
|
<target dev='vdb' bus='virtio'/>
|
||||||
|
<encryption format='luks'>
|
||||||
|
<secret type='passphrase' usage='mycluster_myname'/>
|
||||||
|
</encryption>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<input type='mouse' bus='ps2'/>
|
||||||
|
<input type='keyboard' bus='ps2'/>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
1
tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml
Symbolic link
1
tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../qemuxml2argvdata/qemuxml2argv-luks-disks.xml
|
@ -502,6 +502,7 @@ mymain(void)
|
|||||||
|
|
||||||
DO_TEST("encrypted-disk");
|
DO_TEST("encrypted-disk");
|
||||||
DO_TEST("encrypted-disk-usage");
|
DO_TEST("encrypted-disk-usage");
|
||||||
|
DO_TEST("luks-disks");
|
||||||
DO_TEST("memtune");
|
DO_TEST("memtune");
|
||||||
DO_TEST("memtune-unlimited");
|
DO_TEST("memtune-unlimited");
|
||||||
DO_TEST("blkiotune");
|
DO_TEST("blkiotune");
|
||||||
|
21
tests/storagevolxml2xmlin/vol-luks.xml
Normal file
21
tests/storagevolxml2xmlin/vol-luks.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<volume>
|
||||||
|
<name>LuksDemo.img</name>
|
||||||
|
<key>/var/lib/libvirt/images/LuksDemo.img</key>
|
||||||
|
<source>
|
||||||
|
</source>
|
||||||
|
<capacity unit="G">5</capacity>
|
||||||
|
<allocation>294912</allocation>
|
||||||
|
<target>
|
||||||
|
<path>/var/lib/libvirt/images/LuksDemo.img</path>
|
||||||
|
<format type='luks'/>
|
||||||
|
<permissions>
|
||||||
|
<mode>0644</mode>
|
||||||
|
<owner>0</owner>
|
||||||
|
<group>0</group>
|
||||||
|
<label>unconfined_u:object_r:virt_image_t:s0</label>
|
||||||
|
</permissions>
|
||||||
|
<encryption format='luks'>
|
||||||
|
<secret type='passphrase' usage='mumblyfratz'/>
|
||||||
|
</encryption>
|
||||||
|
</target>
|
||||||
|
</volume>
|
21
tests/storagevolxml2xmlout/vol-luks.xml
Normal file
21
tests/storagevolxml2xmlout/vol-luks.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<volume type='file'>
|
||||||
|
<name>LuksDemo.img</name>
|
||||||
|
<key>/var/lib/libvirt/images/LuksDemo.img</key>
|
||||||
|
<source>
|
||||||
|
</source>
|
||||||
|
<capacity unit='bytes'>5368709120</capacity>
|
||||||
|
<allocation unit='bytes'>294912</allocation>
|
||||||
|
<target>
|
||||||
|
<path>/var/lib/libvirt/images/LuksDemo.img</path>
|
||||||
|
<format type='luks'/>
|
||||||
|
<permissions>
|
||||||
|
<mode>0644</mode>
|
||||||
|
<owner>0</owner>
|
||||||
|
<group>0</group>
|
||||||
|
<label>unconfined_u:object_r:virt_image_t:s0</label>
|
||||||
|
</permissions>
|
||||||
|
<encryption format='luks'>
|
||||||
|
<secret type='passphrase' usage='mumblyfratz'/>
|
||||||
|
</encryption>
|
||||||
|
</target>
|
||||||
|
</volume>
|
@ -105,6 +105,7 @@ mymain(void)
|
|||||||
DO_TEST("pool-dir", "vol-qcow2-lazy");
|
DO_TEST("pool-dir", "vol-qcow2-lazy");
|
||||||
DO_TEST("pool-dir", "vol-qcow2-0.10-lazy");
|
DO_TEST("pool-dir", "vol-qcow2-0.10-lazy");
|
||||||
DO_TEST("pool-dir", "vol-qcow2-nobacking");
|
DO_TEST("pool-dir", "vol-qcow2-nobacking");
|
||||||
|
DO_TEST("pool-dir", "vol-luks");
|
||||||
DO_TEST("pool-disk", "vol-partition");
|
DO_TEST("pool-disk", "vol-partition");
|
||||||
DO_TEST("pool-logical", "vol-logical");
|
DO_TEST("pool-logical", "vol-logical");
|
||||||
DO_TEST("pool-logical", "vol-logical-backing");
|
DO_TEST("pool-logical", "vol-logical-backing");
|
||||||
|
Loading…
Reference in New Issue
Block a user