From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60527) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZoE09-0007oZ-Ph for qemu-devel@nongnu.org; Mon, 19 Oct 2015 13:13:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZoE07-0006VW-Ve for qemu-devel@nongnu.org; Mon, 19 Oct 2015 13:13:37 -0400 Date: Mon, 19 Oct 2015 18:13:24 +0100 From: "Dr. David Alan Gilbert" Message-ID: <20151019171324.GF2462@work-vm> References: <1445267389-21846-1-git-send-email-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: <1445267389-21846-1-git-send-email-berrange@redhat.com> Subject: Re: [Qemu-devel] [PATCH 00/17] Framework for securely passing secrets to QEMU List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Daniel P. Berrange" Cc: Kevin Wolf , Josh Durgin , Stefan Hajnoczi , qemu-block@nongnu.org, qemu-devel@nongnu.org, Markus Armbruster , Ronnie Sahlberg , Paolo Bonzini * Daniel P. Berrange (berrange@redhat.com) wrote: > 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. Agreed. >=20 > 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. >=20 > Example usage for creating secrets... >=20 > Direct password, insecure, for ad-hoc developer testing only >=20 > $QEMU -object secret,id=3Dsec0,data=3Dletmein >=20 > Indirect password via a file, good for production >=20 > echo -n "letmein" > mypasswd.txt > $QEMU -object secret,id=3Dsec0,file=3Dmypasswd.txt >=20 > The file based approach supports file descriptor passing, > so mgmt apps can use that to dynamically add passwords to > running QEMU. Would it make any sense to support the Linux kernel key system? That seems to have a way of passing keys between a limited set of processes and protecting them using SELinux and the like. (I can also imagine that people might want to feed it with keys =66rom a TPM or other hardware security device, but fortunately I can't remember enough about TPMs to remember how getting keys worked). Dave >=20 > 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. >=20 > $QEMU \ > -object secret,id=3Dsecmaster0,file=3D/var/run/libvirt/qemu/$GUEST.ke= y,format=3Dbase64 \ > -object secret,id=3Dsec0,data=3D[base64 ciphertext],\ > keyid=3Dsecmaster0,iv=3D[base64 initialization vector] >=20 > 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. >=20 > 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 >=20 > $QEMU \ > -object secret,id=3Dsecmaster0,file=3D/var/run/libvirt/qemu/$GUEST.ke= y,format=3Dbase64 \ > -object secret,id=3Dsec0,file=3D/some/secret/file.aes,\ > keyid=3Dsecmaster0,iv=3D[base64 initialization vector] >=20 >=20 >=20 > Example usage for referencing secrets... >=20 > CURL: >=20 > $QEMU -object secret,id=3Dsec0... \ > -drive driver=3Dhttp,url=3Dhttp://example.com/someimg.qcow2,\ > user=3Ddan,passwordid=3Dsec0 >=20 > $QEMU -object secret,id=3Dsec0... -object secret,id=3Dsec1 \ > -drive driver=3Dhttp,url=3Dhttp://example.com/someimg.qcow2,\ > user=3Ddan,passwordid=3Dsec0,proxyuser=3Ddan,passwordid=3Ds= ec1 >=20 > iSCSI: >=20 > $QEMU -object secret,id=3Dsec0... \ > -drive driver=3Discsi,url=3Discsi://example.com/target-foo/lun1,\ > user=3Ddan,passwordid=3Dsec0 >=20 > RBD: >=20 > $QEMU -object secret,id=3Dsec0... \ > -drive driver=3Drbd,file=3Drbd:pool/image:id=3Dmyname,\ > auth-supported-cephx,authsecret=3Dsec0 >=20 > QCow/Qcow2 encryption >=20 > $QEMU -object secret,id=3Dsec0... \ > -drive file=3Dsomeimage.qcow2,keyid=3Dsec0 >=20 >=20 > 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 >=20 > 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. >=20 > 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. >=20 > 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. >=20 > 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. >=20 > There are two obvious choices >=20 > 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. >=20 > 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. >=20 > 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 >=20 > 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 >=20 > --=20 > 2.4.3 >=20 >=20 -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK