Files
server/usr/share/doc/qemu-system-common/system/secrets.html
2026-01-07 20:52:11 +01:00

286 lines
22 KiB
HTML

<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Providing secret data to QEMU &mdash; QEMU Debian 1:8.2.2+ds-0ubuntu1.11 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=86f27845" />
<link rel="stylesheet" type="text/css" href="../_static/theme_overrides.css?v=08e6c168" />
<link rel="shortcut icon" href="../_static/qemu_32x32.png"/>
<script src="../_static/jquery.js?v=8dae8fb0"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../_static/documentation_options.js?v=802af9f6"></script>
<script src="../_static/doctools.js?v=888ff710"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/custom.js?v=2ab9f71d"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Client authorization" href="authz.html" />
<link rel="prev" title="TLS setup for network services" href="tls.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #802400" >
<a href="../index.html" class="icon icon-home">
QEMU
<img src="../_static/qemu_128x128.png" class="logo" alt="Logo"/>
</a>
<div class="version">
8.2.2
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../about/index.html">About QEMU</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">System Emulation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="introduction.html">Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="invocation.html">Invocation</a></li>
<li class="toctree-l2"><a class="reference internal" href="device-emulation.html">Device Emulation</a></li>
<li class="toctree-l2"><a class="reference internal" href="keys.html">Keys in the graphical frontends</a></li>
<li class="toctree-l2"><a class="reference internal" href="mux-chardev.html">Keys in the character backend multiplexer</a></li>
<li class="toctree-l2"><a class="reference internal" href="monitor.html">QEMU Monitor</a></li>
<li class="toctree-l2"><a class="reference internal" href="images.html">Disk Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="virtio-net-failover.html">QEMU virtio-net standby (net_failover)</a></li>
<li class="toctree-l2"><a class="reference internal" href="linuxboot.html">Direct Linux Boot</a></li>
<li class="toctree-l2"><a class="reference internal" href="generic-loader.html">Generic Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="guest-loader.html">Guest Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="barrier.html">QEMU Barrier Client</a></li>
<li class="toctree-l2"><a class="reference internal" href="vnc-security.html">VNC security</a></li>
<li class="toctree-l2"><a class="reference internal" href="tls.html">TLS setup for network services</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Providing secret data to QEMU</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#insecure-passing-secrets-as-clear-text-inline">INSECURE: Passing secrets as clear text inline</a></li>
<li class="toctree-l3"><a class="reference internal" href="#passing-secrets-as-clear-text-via-a-file">Passing secrets as clear text via a file</a></li>
<li class="toctree-l3"><a class="reference internal" href="#passing-secrets-as-cipher-text-inline">Passing secrets as cipher text inline</a></li>
<li class="toctree-l3"><a class="reference internal" href="#passing-secrets-via-the-linux-keyring">Passing secrets via the Linux keyring</a></li>
<li class="toctree-l3"><a class="reference internal" href="#best-practice">Best practice</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="authz.html">Client authorization</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdb.html">GDB usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="replay.html">Record/replay</a></li>
<li class="toctree-l2"><a class="reference internal" href="managed-startup.html">Managed start up options</a></li>
<li class="toctree-l2"><a class="reference internal" href="bootindex.html">Managing device boot order with bootindex properties</a></li>
<li class="toctree-l2"><a class="reference internal" href="cpu-hotplug.html">Virtual CPU hotplug</a></li>
<li class="toctree-l2"><a class="reference internal" href="pr-manager.html">Persistent reservation managers</a></li>
<li class="toctree-l2"><a class="reference internal" href="targets.html">QEMU System Emulator Targets</a></li>
<li class="toctree-l2"><a class="reference internal" href="security.html">Security</a></li>
<li class="toctree-l2"><a class="reference internal" href="multi-process.html">Multi-process QEMU</a></li>
<li class="toctree-l2"><a class="reference internal" href="confidential-guest-support.html">Confidential Guest Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="vm-templating.html">QEMU VM templating</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../user/index.html">User Mode Emulation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../interop/index.html">System Emulation Management and Interoperability</a></li>
<li class="toctree-l1"><a class="reference internal" href="../specs/index.html">System Emulation Guest Hardware Specifications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devel/index.html">Developer Information</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #802400" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">QEMU</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">System Emulation</a></li>
<li class="breadcrumb-item active">Providing secret data to QEMU</li>
<li class="wy-breadcrumbs-aside">
<a href="https://gitlab.com/qemu-project/qemu/blob/master/docs/system/secrets.rst" class="fa fa-gitlab"> Edit on GitLab</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="providing-secret-data-to-qemu">
<span id="secret-data"></span><h1>Providing secret data to QEMU<a class="headerlink" href="#providing-secret-data-to-qemu" title="Link to this heading"></a></h1>
<p>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 <code class="docutils literal notranslate"><span class="pre">secret</span></code> object type.</p>
<p>At startup this can be done using the <code class="docutils literal notranslate"><span class="pre">-object</span> <span class="pre">secret,...</span></code> command line
argument. At runtime this can be done using the <code class="docutils literal notranslate"><span class="pre">object_add</span></code> QMP / HMP
monitor commands. The examples that follow will illustrate use of <code class="docutils literal notranslate"><span class="pre">-object</span></code>
command lines, but they all apply equivalentely in QMP / HMP. When creating
a <code class="docutils literal notranslate"><span class="pre">secret</span></code> 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.</p>
<section id="insecure-passing-secrets-as-clear-text-inline">
<h2>INSECURE: Passing secrets as clear text inline<a class="headerlink" href="#insecure-passing-secrets-as-clear-text-inline" title="Link to this heading"></a></h2>
<p><strong>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.</strong></p>
<p>For the convenience of people debugging / developing with QEMU, it is possible
to pass secret data inline on the command line.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">data</span><span class="o">=</span><span class="mi">87539319</span>
</pre></div>
</div>
<p>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.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">data</span><span class="o">=</span><span class="n">ODc1MzkzMTk</span><span class="o">=</span><span class="p">,</span><span class="nb">format</span><span class="o">=</span><span class="n">base64</span>
</pre></div>
</div>
<p><strong>Note: base64 encoding does not provide any security benefit.</strong></p>
</section>
<section id="passing-secrets-as-clear-text-via-a-file">
<h2>Passing secrets as clear text via a file<a class="headerlink" href="#passing-secrets-as-clear-text-via-a-file" title="Link to this heading"></a></h2>
<p>The simplest approach to providing data securely is to use a file to store
the secret:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">file</span><span class="o">=</span><span class="n">vnc</span><span class="o">-</span><span class="n">password</span><span class="o">.</span><span class="n">txt</span>
</pre></div>
</div>
<p>In this example the file <code class="docutils literal notranslate"><span class="pre">vnc-password.txt</span></code> 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.</p>
<p>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:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">sec0</span><span class="p">,</span><span class="n">file</span><span class="o">=</span><span class="n">vnc</span><span class="o">-</span><span class="n">password</span><span class="o">.</span><span class="n">txt</span><span class="p">,</span><span class="nb">format</span><span class="o">=</span><span class="n">base64</span>
</pre></div>
</div>
<p>The file should generally be given mode <code class="docutils literal notranslate"><span class="pre">0600</span></code> or <code class="docutils literal notranslate"><span class="pre">0400</span></code> 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.</p>
</section>
<section id="passing-secrets-as-cipher-text-inline">
<h2>Passing secrets as cipher text inline<a class="headerlink" href="#passing-secrets-as-cipher-text-inline" title="Link to this heading"></a></h2>
<p>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.</p>
<p>The secret used as the AES key must always be configured using the file based
storage mechanism:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secmaster</span><span class="p">,</span><span class="n">file</span><span class="o">=</span><span class="n">masterkey</span><span class="o">.</span><span class="n">data</span><span class="p">,</span><span class="nb">format</span><span class="o">=</span><span class="n">base64</span>
</pre></div>
</div>
<p>In this case the <code class="docutils literal notranslate"><span class="pre">masterkey.data</span></code> 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</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">keyid</span><span class="o">=</span><span class="n">secmaster</span><span class="p">,</span><span class="n">data</span><span class="o">=</span><span class="n">BASE64</span><span class="o">-</span><span class="n">CIPHERTEXT</span><span class="p">,</span><span class="n">iv</span><span class="o">=</span><span class="n">BASE64</span><span class="o">-</span><span class="n">IV</span><span class="p">,</span><span class="nb">format</span><span class="o">=</span><span class="n">base64</span>
</pre></div>
</div>
<p>In this example <code class="docutils literal notranslate"><span class="pre">BASE64-CIPHERTEXT</span></code> is the result of AES-256-CBC encrypting
the secret with <code class="docutils literal notranslate"><span class="pre">masterkey.data</span></code> and then base64 encoding the ciphertext.
The <code class="docutils literal notranslate"><span class="pre">BASE64-IV</span></code> data is 16 random bytes which have been base64 encrypted.
These bytes are used as the initialization vector for the AES-256-CBC value.</p>
<p>A single master key can be used to encrypt all subsequent secrets, <strong>but it is
critical that a different initialization vector is used for every secret</strong>.</p>
</section>
<section id="passing-secrets-via-the-linux-keyring">
<h2>Passing secrets via the Linux keyring<a class="headerlink" href="#passing-secrets-via-the-linux-keyring" title="Link to this heading"></a></h2>
<p>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:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret_keyring</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">serial</span><span class="o">=</span><span class="mi">1729</span>
</pre></div>
</div>
<p>This instructs QEMU to load data from the Linux keyring secret identified by
the serial number <code class="docutils literal notranslate"><span class="pre">1729</span></code>. It is possible to combine use of the keyring with
other features mentioned earlier such as base64 encoding:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret_keyring</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">serial</span><span class="o">=</span><span class="mi">1729</span><span class="p">,</span><span class="nb">format</span><span class="o">=</span><span class="n">base64</span>
</pre></div>
</div>
<p>and also encryption with a master key:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">secret_keyring</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">secvnc0</span><span class="p">,</span><span class="n">keyid</span><span class="o">=</span><span class="n">secmaster</span><span class="p">,</span><span class="n">serial</span><span class="o">=</span><span class="mi">1729</span><span class="p">,</span><span class="n">iv</span><span class="o">=</span><span class="n">BASE64</span><span class="o">-</span><span class="n">IV</span>
</pre></div>
</div>
</section>
<section id="best-practice">
<h2>Best practice<a class="headerlink" href="#best-practice" title="Link to this heading"></a></h2>
<p>It is recommended for production deployments to use a master key secret, and
then pass all subsequent inline secrets encrypted with the master key.</p>
<p>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.</p>
<p>The secrets for individual QEMU device backends must all then be encrypted
with this master key.</p>
<p>This procedure helps ensure that the individual secrets for QEMU backends will
not be compromised, even if <code class="docutils literal notranslate"><span class="pre">-object</span></code> CLI args or <code class="docutils literal notranslate"><span class="pre">object_add</span></code> 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.</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="tls.html" class="btn btn-neutral float-left" title="TLS setup for network services" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="authz.html" class="btn btn-neutral float-right" title="Client authorization" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2025, The QEMU Project Developers.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
<!-- Empty para to force a blank line after "Built with Sphinx ..." -->
<p></p>
<p>This documentation is for QEMU version 8.2.2.</p>
<p><a href="../about/license.html">QEMU and this manual are released under the
GNU General Public License, version 2.</a></p>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>