[libvirt] [PATCH 0/9] Add support for (qcow*) volume encryption

Daniel P. Berrange berrange at redhat.com
Thu Jul 23 20:20:49 UTC 2009

On Tue, Jul 21, 2009 at 01:11:56PM +0200, Miloslav Trma?? wrote:
> Hello,
> the following patches add full support for qcow/qcow2 volume encryption,
> assuming a client that supports it.
> New XML tags are defined to represent encryption parameters (currently
> format and passphrase, more can be added in the future), e.g.
>     <encryption format='qcow'>
>         <passphrase>c2lsbHk=</passphrase>
>     </encryption>
> (passphrase content uses base64)

I don't think we need 'format=qcow' in there - the guest XML already
has ability to have a <driver name='qemu' type='qcow2'/> element,
and the storage vol XML also has a <format type='qcow2'/> element.

I think it would be good to change the naming of the inner element 
a little too. I think having it called 'secret' and then a 'type' 
attribute would be a little nicer. eg

      <secret type='passphrase'/>c2lsbHk=</secret>

It might be desirable to add encryption algorithm, but that can probably
wait since qcow doesn't support multiple algorithms at this time.

> The <encryption> tag can be added to a <volume> node passed to
> virStorageVolCreateXML() to create an encrypted volume, or to a
> <disk> node inside a <domain> to specify what encryption parameters to
> use for a domain.  If the domain is persistent, the parameters
> (including the passphrase) will be saved unencrypted in /etc/libvirtd;
> the primary use case is to store the parameters outside of libvirtd,
> (perhaps by virt-manager in a GNOME keyring).
> Possible enhancements:
> - Documentation and test cases.  I'll write both if the code is acceptable,
>   I wanted to make the code available for review first.
> - Support for "dumb" clients that don't know anything about encryption
>   formats and the required parameters: adding an encryption format to libvirt
>   would automatically make it supported in all clients.
>   Such a client would only request that a volume should be created when
>   creating it, and libvirt would choose an appropriate format, parameters
>   and passphrase/key and return it to the client, who could later pass it
>   unmodified inside a <domain>.
>   This requires public API additions to let libvirt return the encryption
>   information as one of the results of a volume creation operation.
> - Support for storing the passphrases/keys used by persistent domains
>   outside of the main XML files, e.g. in a separate passphrase-encrypted
>   file that must be entered on libvirtd startup.

I think these two points overlap quite alot. I'll use 'secret' to refer
to a passphrase or key here

As you say there are two initial approaches to persistence of secrets

 - Keep the keys in the domain XML files
 - Use a separate keystore

For the separate keystore, there are probably 3 interesting targets
to consider

 1. A simple text (or pkcs11) file managed by libvirtd on the host

    This would be useful for the privileged libvirtd to use in 
    ad-hoc, small scale deployments. Perhaps allowing it to be
    shared between a small number of hosts on NFS, or GFS etc

 2. A desktop key agent (eg gnome-keyring)

    This would be useful for the unprivileged libvirtd instances
    that run in the context of the desktop login session. Users
    already have SSH, GPG, website keys stored here, so having
    keys for their VM disks is obviously desirable

 3. A off-node key management server

    This would be useful for a large scale data center / cluster
    cloud deployment. This is good to allow management scalability
    and better separation of responsiblities of adminstration.

If no keystore is in use, then I clearly all keys must go in & out
of libvirt using the XML, which is pretty much what you're doing
in this series. I would say though, there is no point in clearing
the secret from the virStorageVolDefPtr instance/XML after volume
creation, since the secret is going to be kept in memory forever
for any guest using the volume.  By not clearing the secret, an
app could create a volume, requesting automatic key generation,
then just do virStorageVolDumpXML(vol, VIR_STORAGE_VOL_XML_SECURE)
to extract it and pass to onto the XML for the guest that's created

If a keystore is in use, then I'd suggest we should have explicit
APIs for secret management, and forbid the use of the actual secrets
in the XML everywhere.

Instead, either pass in a pre-created key UUID when creating a volume
or defining a guest eg, the XML fragment would look like this

     <secret type='keyuuid'>123456-1234-1245-1234-124512345</secret>

Internally libvirt would then get the real passphrase from the keystore
by looking up the associated UUID. 

Or request auto-creation of a key by leaving out the data

     <secret type='keyuuid'/>

Internally libvirt would add a key to its database, and fillin the UUID
which you could then see via DumpXML.

With a keystore we'd likely need a handful of APIs

 - create a secret providing a passphrase
 - list all known secret UUIDs
 - get the passphrase assoicated with a secret 
 - delete a secret based on UUID
 - lookup a secret UUID based on the a disk path

The nice thing about separating the passphrases out of the XML completely
is that we would then have the ability to do fine grained access control.
eg, you could give people ability to create new guests / volumes, using
encryption without them ever specifying, or having access to the secrets.
A seperate role could be given ability to create/list/delete secrets.
This would also let us associate one secret with many disks, which 
might be a useful scenario for some people.

|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

More information about the libvir-list mailing list