[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 00/17] Framework for securely passing secrets to QEM
From: |
Daniel P. Berrange |
Subject: |
[Qemu-block] [PATCH 00/17] Framework for securely passing secrets to QEMU |
Date: |
Mon, 19 Oct 2015 16:09:32 +0100 |
There are a variety of places where QEMU needs to have access
to passwords, encryption keys or similar kinds of secrets.
- VNC / SPICE user passwords
- Curl block http / proxy passwords
- RBD auth password
- iSCSI CHAP password
- x509 private key password
- QCow/QCow2 encryption key
QEMU has a variety of ways of dealing with this problem, some
good, some ugly, some bad.
- The RBD block driver accepts the password in plaintext
via a private RBD config option. This is a pending CVE
https://security-tracker.debian.org/tracker/CVE-2015-5160
- The iSCSI driver accepts the password in plaintext as
a block driver option. This is the same as the RBD CVE
essentially, just a QEMU option, rather than a librbd
option
- The VNC / SPICE servers only accept the passwords via
the QEMU monitor. This is secure, but it inconvenient
for adhoc developer usage where security of CLI args
does not matter.
- QCow/QCow2 encryption keys can be provided by the monitor
but this is not available for qemu-img, qemu-io and
qemu-nbd. QEMU falls back to doing interactive
console prompting to get keys.
- x509 privte key passwords are not supported at all by
QEMU which forces users to store their key in plaintext
on their host FS.
- The CURL driver doesn't support HTTP auth at all
currently.
It is obvious there there is a wide variety of functionality
in QEMU that needs access to "secrets". This need will only
grow over time. We need to stop having everyone invent their
own dangerous wheels and provide a standard mechanism for
securely passing secrets to QEMU.
To this end, this series introduces a QCryptoSecret object
class with short name "secret". All the places which needs
passwords/keys are then converted to get their via this
API, except VNC/SPICE which are a future exercise.
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
Finally, this extends qemu-img, qemu-nbd and qemu-io. All of
them gain a new '--object' parameter which provides the same
functionality as '-object' with QEMU system emulators. This
lets us create QCryptoSecret object instances in those tools
The tools also then get support for a new '--source IMG-OPTS'
parameter to allow a full set of image options to be specified,
instead of just separate hardcoded args for format + filename
which they currently permit. This is probably the area I am
least sure of. I struggled to understand what the "best
practice" is for turning a QemuOpts into something you can
use to instantiate block backends. So I may well have not
done the right thing.
Towards the end I rip out the current encryption key handling
from the block layer so all the hairy code for dealing
with encrypted block devices disappears, and encryption
can be a 100% private matter for the block driver internal
impl. This is obviously not backwards compatible, but we
have been warning users we're dropping qcow2 encryption
support for a while.
Finally I disable support for writing to encrypted qcow2
files, but keep the ability to read them, so users can
liberate data. Originally we were intending to fully
delete encryption support, due to the burden it places
on the internal boock API. Since I removed that burden
I figured it is reasonable to keep read-only support
around.
The only real missing thing is wiring up the VNC/SPICE
servers. There is one complication here in that it is
common to change the VNC/SPICE password at runtime, and
I'm not sure what the best way to deal with this is.
There are two obvious choices
a. Create a new secret, tell the VNC server to use
the new secret, delete the old secret. This will
need a new 'graphics_secret_update' command in
the monitor, to use alongside object_add/del.
b. Allow the existing secret to be updated via some
new 'object_update' method, and internally notify
the VNC/SPICE server when the secret is updated.
This would probably need a new QOM interface
UserUpdatableObject to be defined, as an refinement
of UserCreatableObject.
Daniel P. Berrange (17):
crypto: add QCryptoSecret object class for password/key handling
crypto: add support for loading encrypted x509 keys
rbd: add support for getting password from QCryptoSecret object
curl: add support for HTTP authentication parameters
iscsi: add support for getting CHAP password via QCryptoSecret API
qcow: add a 'keyid' parameter to qcow options
qcow2: add a 'keyid' parameter to qcow2 options
qom: add user_creatable_add & user_creatable_del methods
qemu-img: add support for --object command line arg
qemu-nbd: add support for --object command line arg
qemu-io: add support for --object command line arg
qemu-io: allow specifying image as a set of options args
qemu-nbd: allow specifying image as a set of options args
qemu-img: allow specifying image as a set of options args
block: rip out all traces of password prompting
block: remove all encryption handling APIs
block: remove support for writing to qcow/qcow2 encrypted images
block.c | 88 +----
block/curl.c | 66 ++++
block/iscsi.c | 24 +-
block/qapi.c | 2 +-
block/qcow.c | 122 +++++--
block/qcow2.c | 116 +++---
block/qcow2.h | 1 +
block/rbd.c | 42 +++
blockdev.c | 69 +---
crypto/Makefile.objs | 1 +
crypto/secret.c | 513 ++++++++++++++++++++++++++
crypto/tlscredsx509.c | 47 +++
hmp.c | 42 +--
hw/usb/dev-storage.c | 32 --
include/block/block.h | 5 +-
include/crypto/secret.h | 139 +++++++
include/crypto/tlscredsx509.h | 1 +
include/monitor/monitor.h | 10 -
include/qemu/option.h | 1 +
include/qemu/osdep.h | 2 -
include/qom/object_interfaces.h | 31 ++
monitor.c | 65 ----
qapi/block-core.json | 23 +-
qapi/crypto.json | 14 +
qemu-img-cmds.hx | 44 +--
qemu-img.c | 788 +++++++++++++++++++++++++++++++++++-----
qemu-img.texi | 8 +
qemu-io.c | 145 ++++++--
qemu-nbd.c | 142 +++++++-
qemu-nbd.texi | 7 +
qemu-options.hx | 84 ++++-
qmp.c | 83 +----
qom/object_interfaces.c | 76 ++++
tests/.gitignore | 1 +
tests/Makefile | 2 +
tests/qemu-iotests/087 | 20 +
tests/qemu-iotests/087.out | 26 +-
tests/qemu-iotests/134 | 17 +-
tests/qemu-iotests/134.out | 44 +--
tests/qemu-iotests/common.rc | 4 +-
tests/test-crypto-secret.c | 440 ++++++++++++++++++++++
util/oslib-posix.c | 66 ----
util/oslib-win32.c | 24 --
util/qemu-option.c | 6 +
vl.c | 8 +-
45 files changed, 2740 insertions(+), 751 deletions(-)
create mode 100644 crypto/secret.c
create mode 100644 include/crypto/secret.h
create mode 100644 tests/test-crypto-secret.c
--
2.4.3
- [Qemu-block] [PATCH 00/17] Framework for securely passing secrets to QEMU,
Daniel P. Berrange <=
- [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-block] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
[Qemu-block] [PATCH 03/17] rbd: add support for getting password from QCryptoSecret object, Daniel P. Berrange, 2015/10/19