mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 11:39:53 +00:00
docs: document how to pass secret data to QEMU
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
e0bd0cd43e
commit
491024a5b4
@ -30,6 +30,7 @@ Contents:
|
||||
guest-loader
|
||||
vnc-security
|
||||
tls
|
||||
secrets
|
||||
gdb
|
||||
managed-startup
|
||||
cpu-hotplug
|
||||
|
162
docs/system/secrets.rst
Normal file
162
docs/system/secrets.rst
Normal file
@ -0,0 +1,162 @@
|
||||
.. _secret data:
|
||||
|
||||
Providing secret data to QEMU
|
||||
-----------------------------
|
||||
|
||||
There are a variety of objects in QEMU which require secret data to be provided
|
||||
by the administrator or management application. For example, network block
|
||||
devices often require a password, LUKS block devices require a passphrase to
|
||||
unlock key material, remote desktop services require an access password.
|
||||
QEMU has a general purpose mechanism for providing secret data to QEMU in a
|
||||
secure manner, using the ``secret`` object type.
|
||||
|
||||
At startup this can be done using the ``-object secret,...`` command line
|
||||
argument. At runtime this can be done using the ``object_add`` QMP / HMP
|
||||
monitor commands. The examples that follow will illustrate use of ``-object``
|
||||
command lines, but they all apply equivalentely in QMP / HMP. When creating
|
||||
a ``secret`` object it must be given a unique ID string. This ID is then
|
||||
used to identify the object when configuring the thing which need the data.
|
||||
|
||||
|
||||
INSECURE: Passing secrets as clear text inline
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**The following should never be done in a production environment or on a
|
||||
multi-user host. Command line arguments are usually visible in the process
|
||||
listings and are often collected in log files by system monitoring agents
|
||||
or bug reporting tools. QMP/HMP commands and their arguments are also often
|
||||
logged and attached to bug reports. This all risks compromising secrets that
|
||||
are passed inline.**
|
||||
|
||||
For the convenience of people debugging / developing with QEMU, it is possible
|
||||
to pass secret data inline on the command line.
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=secvnc0,data=87539319
|
||||
|
||||
|
||||
Again it is possible to provide the data in base64 encoded format, which is
|
||||
particularly useful if the data contains binary characters that would clash
|
||||
with argument parsing.
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=secvnc0,data=ODc1MzkzMTk=,format=base64
|
||||
|
||||
|
||||
**Note: base64 encoding does not provide any security benefit.**
|
||||
|
||||
Passing secrets as clear text via a file
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The simplest approach to providing data securely is to use a file to store
|
||||
the secret:
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=secvnc0,file=vnc-password.txt
|
||||
|
||||
|
||||
In this example the file ``vnc-password.txt`` contains the plain text secret
|
||||
data. It is important to note that the contents of the file are treated as an
|
||||
opaque blob. The entire raw file contents is used as the value, thus it is
|
||||
important not to mistakenly add any trailing newline character in the file if
|
||||
this newline is not intended to be part of the secret data.
|
||||
|
||||
In some cases it might be more convenient to pass the secret data in base64
|
||||
format and have QEMU decode to get the raw bytes before use:
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=sec0,file=vnc-password.txt,format=base64
|
||||
|
||||
|
||||
The file should generally be given mode ``0600`` or ``0400`` permissions, and
|
||||
have its user/group ownership set to the same account that the QEMU process
|
||||
will be launched under. If using mandatory access control such as SELinux, then
|
||||
the file should be labelled to only grant access to the specific QEMU process
|
||||
that needs access. This will prevent other processes/users from compromising the
|
||||
secret data.
|
||||
|
||||
|
||||
Passing secrets as cipher text inline
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To address the insecurity of passing secrets inline as clear text, it is
|
||||
possible to configure a second secret as an AES key to use for decrypting
|
||||
the data.
|
||||
|
||||
The secret used as the AES key must always be configured using the file based
|
||||
storage mechanism:
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=secmaster,file=masterkey.data,format=base64
|
||||
|
||||
|
||||
In this case the ``masterkey.data`` file would be initialized with 32
|
||||
cryptographically secure random bytes, which are then base64 encoded.
|
||||
The contents of this file will by used as an AES-256 key to encrypt the
|
||||
real secret that can now be safely passed to QEMU inline as cipher text
|
||||
|
||||
::
|
||||
|
||||
-object secret,id=secvnc0,keyid=secmaster,data=BASE64-CIPHERTEXT,iv=BASE64-IV,format=base64
|
||||
|
||||
|
||||
In this example ``BASE64-CIPHERTEXT`` is the result of AES-256-CBC encrypting
|
||||
the secret with ``masterkey.data`` and then base64 encoding the ciphertext.
|
||||
The ``BASE64-IV`` data is 16 random bytes which have been base64 encrypted.
|
||||
These bytes are used as the initialization vector for the AES-256-CBC value.
|
||||
|
||||
A single master key can be used to encrypt all subsequent secrets, **but it is
|
||||
critical that a different initialization vector is used for every secret**.
|
||||
|
||||
Passing secrets via the Linux keyring
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The earlier mechanisms described are platform agnostic. If using QEMU on a Linux
|
||||
host, it is further possible to pass secrets to QEMU using the Linux keyring:
|
||||
|
||||
::
|
||||
|
||||
-object secret_keyring,id=secvnc0,serial=1729
|
||||
|
||||
|
||||
This instructs QEMU to load data from the Linux keyring secret identified by
|
||||
the serial number ``1729``. It is possible to combine use of the keyring with
|
||||
other features mentioned earlier such as base64 encoding:
|
||||
|
||||
::
|
||||
|
||||
-object secret_keyring,id=secvnc0,serial=1729,format=base64
|
||||
|
||||
|
||||
and also encryption with a master key:
|
||||
|
||||
::
|
||||
|
||||
-object secret_keyring,id=secvnc0,keyid=secmaster,serial=1729,iv=BASE64-IV
|
||||
|
||||
|
||||
Best practice
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
It is recommended for production deployments to use a master key secret, and
|
||||
then pass all subsequent inline secrets encrypted with the master key.
|
||||
|
||||
Each QEMU instance must have a distinct master key, and that must be generated
|
||||
from a cryptographically secure random data source. The master key should be
|
||||
deleted immediately upon QEMU shutdown. If passing the master key as a file,
|
||||
the key file must have access control rules applied that restrict access to
|
||||
just the one QEMU process that is intended to use it. Alternatively the Linux
|
||||
keyring can be used to pass the master key to QEMU.
|
||||
|
||||
The secrets for individual QEMU device backends must all then be encrypted
|
||||
with this master key.
|
||||
|
||||
This procedure helps ensure that the individual secrets for QEMU backends will
|
||||
not be compromised, even if ``-object`` CLI args or ``object_add`` monitor
|
||||
commands are collected in log files and attached to public bug support tickets.
|
||||
The only item that needs strongly protecting is the master key file.
|
Loading…
Reference in New Issue
Block a user