Re: [Qemu-block] [Qemu-devel] [PATCH 00/17] Framework for securely passing secrets to QEMU

2015-10-19 Thread Alex Bennée

Daniel P. Berrange  writes:

> There are a variety of places where QEMU needs to have access
> to passwords, encryption keys or similar kinds of secrets.
>

>
> Example usage for creating secrets...
>
> Direct password, insecure, for ad-hoc developer testing only
>
>   $QEMU -object secret,id=sec0,data=letmein
>
> Indirect password via a file, good for production
>
>   echo -n "letmein" > mypasswd.txt
>   $QEMU -object secret,id=sec0,file=mypasswd.txt
>
> The file based approach supports file descriptor passing,
> so mgmt apps can use that to dynamically add passwords to
> running QEMU.
>
> There is a better way though, which is to use an encrypted
> secret. The intent here is that a mgmt app (like libvirt)
> will generate a random AES-256 key for each virtual machine
> it starts (saved in eg /var/run/libvirt/qemu/$GUEST.key)
> It can then use the direct password passing, but encrypt
> the data.
>
>   $QEMU \
> -object 
> secret,id=secmaster0,file=/var/run/libvirt/qemu/$GUEST.key,format=base64 \
> -object secret,id=sec0,data=[base64 ciphertext],\
>keyid=secmaster0,iv=[base64 initialization vector]
>
> This means that the mgmt app does not need to worry about
> file descriptor passing at all. It can just use regular
> object properties, safe in the knowledge that the data is
> protected by a secret AES key shared only between QEMU
> and the mgmt app.
>
> Use of encrypted secrets is not restricted to directly
> provided inline data. If the secret is stored in an
> external file, that can be encrypted too
>
>   $QEMU \
> -object 
> secret,id=secmaster0,file=/var/run/libvirt/qemu/$GUEST.key,format=base64 \
> -object secret,id=sec0,file=/some/secret/file.aes,\
>keyid=secmaster0,iv=[base64 initialization vector]
>
>
>
> Example usage for referencing secrets...
>
> CURL:
>
>   $QEMU -object secret,id=sec0... \
>  -drive driver=http,url=http://example.com/someimg.qcow2,\
>   user=dan,passwordid=sec0
>
>   $QEMU -object secret,id=sec0... -object secret,id=sec1 \
>  -drive driver=http,url=http://example.com/someimg.qcow2,\
>   user=dan,passwordid=sec0,proxyuser=dan,passwordid=sec1
>
> iSCSI:
>
>   $QEMU -object secret,id=sec0... \
>  -drive driver=iscsi,url=iscsi://example.com/target-foo/lun1,\
>  user=dan,passwordid=sec0
>
> RBD:
>
>   $QEMU -object secret,id=sec0... \
>  -drive driver=rbd,file=rbd:pool/image:id=myname,\
>  auth-supported-cephx,authsecret=sec0
>
> QCow/Qcow2 encryption
>
>   $QEMU -object secret,id=sec0... \
>  -drive file=someimage.qcow2,keyid=sec0

So one use case which I don't see here but do on other programs that
need to access secrets is calling an external program and reading its
stdout. This is simpler than having to mess around with passing FDs
although there may be security concerns having QEMU create new tasks on
the system.


-- 
Alex Bennée



Re: [Qemu-block] [Qemu-devel] [PATCH 00/17] Framework for securely passing secrets to QEMU

2015-10-19 Thread Daniel P. Berrange
On Mon, Oct 19, 2015 at 05:05:58PM +0100, Alex Bennée wrote:
> Daniel P. Berrange  writes:
> 
> > There are a variety of places where QEMU needs to have access
> > to passwords, encryption keys or similar kinds of secrets.
> >
> 
> >
> > Example usage for creating secrets...
> >
> > Direct password, insecure, for ad-hoc developer testing only
> >
> >   $QEMU -object secret,id=sec0,data=letmein
> >
> > Indirect password via a file, good for production
> >
> >   echo -n "letmein" > mypasswd.txt
> >   $QEMU -object secret,id=sec0,file=mypasswd.txt
> >
> > The file based approach supports file descriptor passing,
> > so mgmt apps can use that to dynamically add passwords to
> > running QEMU.
> >
> > There is a better way though, which is to use an encrypted
> > secret. The intent here is that a mgmt app (like libvirt)
> > will generate a random AES-256 key for each virtual machine
> > it starts (saved in eg /var/run/libvirt/qemu/$GUEST.key)
> > It can then use the direct password passing, but encrypt
> > the data.
> >
> >   $QEMU \
> > -object 
> > secret,id=secmaster0,file=/var/run/libvirt/qemu/$GUEST.key,format=base64 \
> > -object secret,id=sec0,data=[base64 ciphertext],\
> >keyid=secmaster0,iv=[base64 initialization vector]
> >
> > This means that the mgmt app does not need to worry about
> > file descriptor passing at all. It can just use regular
> > object properties, safe in the knowledge that the data is
> > protected by a secret AES key shared only between QEMU
> > and the mgmt app.
> >
> > Use of encrypted secrets is not restricted to directly
> > provided inline data. If the secret is stored in an
> > external file, that can be encrypted too
> >
> >   $QEMU \
> > -object 
> > secret,id=secmaster0,file=/var/run/libvirt/qemu/$GUEST.key,format=base64 \
> > -object secret,id=sec0,file=/some/secret/file.aes,\
> >keyid=secmaster0,iv=[base64 initialization vector]
> >
> >
> >
> > Example usage for referencing secrets...
> >
> > CURL:
> >
> >   $QEMU -object secret,id=sec0... \
> >  -drive driver=http,url=http://example.com/someimg.qcow2,\
> >   user=dan,passwordid=sec0
> >
> >   $QEMU -object secret,id=sec0... -object secret,id=sec1 \
> >  -drive driver=http,url=http://example.com/someimg.qcow2,\
> >   user=dan,passwordid=sec0,proxyuser=dan,passwordid=sec1
> >
> > iSCSI:
> >
> >   $QEMU -object secret,id=sec0... \
> >  -drive driver=iscsi,url=iscsi://example.com/target-foo/lun1,\
> >  user=dan,passwordid=sec0
> >
> > RBD:
> >
> >   $QEMU -object secret,id=sec0... \
> >  -drive driver=rbd,file=rbd:pool/image:id=myname,\
> >  auth-supported-cephx,authsecret=sec0
> >
> > QCow/Qcow2 encryption
> >
> >   $QEMU -object secret,id=sec0... \
> >  -drive file=someimage.qcow2,keyid=sec0
> 
> So one use case which I don't see here but do on other programs that
> need to access secrets is calling an external program and reading its
> stdout. This is simpler than having to mess around with passing FDs
> although there may be security concerns having QEMU create new tasks on
> the system.

Spawning external programs is a rather heavyweight approach. I can see
it being useful if you were locked into an existing API/syntax which
you couldn't modify, but we don't have that restriction here. I'm also
not a huge fan of having QEMU spawn a program that potentially has
access to a large number of passwords that QEMU should not be able
to access. I think passing in the required passwords explicitly as
done here is a better approach.

As noted earlier, FD passing is supported, but I don't think it is
going to be commonly needed or used. At least libvirt would not use
it, as providing the passwords directly, with encryption, is a more
straightforward approach to implement.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|