ostree/composefs/index.html
2024-05-30 16:49:28 +00:00

421 lines
20 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="stylesheet" href="/ostree/assets/css/just-the-docs-default.css">
<script src="/ostree/assets/js/vendor/lunr.min.js"></script>
<script src="/ostree/assets/js/just-the-docs.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Using composefs with OSTree | ostreedev/ostree</title>
<meta name="generator" content="Jekyll v3.9.5" />
<meta property="og:title" content="Using composefs with OSTree" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="ostree documentation" />
<meta property="og:description" content="ostree documentation" />
<link rel="canonical" href="https://ostreedev.github.io/ostree/composefs/" />
<meta property="og:url" content="https://ostreedev.github.io/ostree/composefs/" />
<meta property="og:site_name" content="ostreedev/ostree" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Using composefs with OSTree" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebPage","description":"ostree documentation","headline":"Using composefs with OSTree","url":"https://ostreedev.github.io/ostree/composefs/"}</script>
<!-- End Jekyll SEO tag -->
</head>
<body>
<a class="skip-to-main" href="#main-content">Skip to main content</a>
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="svg-link" viewBox="0 0 24 24">
<title>Link</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<!-- Feather. MIT License: https://github.com/feathericons/feather/blob/master/LICENSE -->
<symbol id="svg-external-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link">
<title id="svg-external-link-title">(external link)</title>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line>
</symbol>
<symbol id="svg-doc" viewBox="0 0 24 24">
<title>Document</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
</svg>
</symbol>
<symbol id="svg-search" viewBox="0 0 24 24">
<title>Search</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
<circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</symbol>
<!-- Bootstrap Icons. MIT License: https://github.com/twbs/icons/blob/main/LICENSE.md -->
<symbol id="svg-copy" viewBox="0 0 16 16">
<title>Copy</title>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
<path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
</svg>
</symbol>
<symbol id="svg-copied" viewBox="0 0 16 16">
<title>Copied</title>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard-check-fill" viewBox="0 0 16 16">
<path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/>
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/>
</svg>
</symbol>
</svg>
<div class="side-bar">
<div class="site-header">
<a href="/ostree/" class="site-title lh-tight">
ostreedev/ostree
</a>
<a href="#" id="menu-button" class="site-button">
<svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg>
</a>
</div>
<nav aria-label="Main" id="site-nav" class="site-nav">
<ul class="nav-list"><li class="nav-list-item"><a href="/ostree/" class="nav-list-link">libostree</a></li><li class="nav-list-item"><a href="/ostree/introduction/" class="nav-list-link">OSTree Overview</a></li><li class="nav-list-item"><a href="/ostree/repo/" class="nav-list-link">Anatomy of an OSTree repository</a></li><li class="nav-list-item"><a href="/ostree/deployment/" class="nav-list-link">Deployments</a></li><li class="nav-list-item"><a href="/ostree/atomic-upgrades/" class="nav-list-link">Atomic Upgrades</a></li><li class="nav-list-item"><a href="/ostree/atomic-rollbacks/" class="nav-list-link">Atomic Rollbacks</a></li><li class="nav-list-item"><a href="/ostree/adapting-existing/" class="nav-list-link">Adapting existing mainstream distributions</a></li><li class="nav-list-item"><a href="/ostree/var/" class="nav-list-link">OSTree and /var handling</a></li><li class="nav-list-item"><a href="/ostree/formats/" class="nav-list-link">OSTree data formats</a></li><li class="nav-list-item"><a href="/ostree/buildsystem-and-repos/" class="nav-list-link">Writing a buildsystem and managing repositories</a></li><li class="nav-list-item"><a href="/ostree/authenticated-repos/" class="nav-list-link">Handling access to authenticated remote repositories</a></li><li class="nav-list-item"><a href="/ostree/repository-management/" class="nav-list-link">Managing content in OSTree repositories</a></li><li class="nav-list-item"><a href="/ostree/copying-deltas/" class="nav-list-link">Static deltas for offline updates</a></li><li class="nav-list-item"><a href="/ostree/ima/" class="nav-list-link">Using Linux IMA with OSTree</a></li><li class="nav-list-item"><a href="/ostree/related-projects/" class="nav-list-link">Related Projects</a></li><li class="nav-list-item active"><a href="/ostree/composefs/" class="nav-list-link active">Using composefs with OSTree</a></li><li class="nav-list-item"><a href="/ostree/bootloaders/" class="nav-list-link">Bootloaders</a></li><li class="nav-list-item"><a href="/ostree/CONTRIBUTING/" class="nav-list-link">Contributing</a></li><li class="nav-list-item"><a href="/ostree/contributing-tutorial/" class="nav-list-link">OSTree Contributing Tutorial</a></li><li class="nav-list-item"><a href="/ostree/README-historical/" class="nav-list-link">Historical OSTree README</a></li></ul>
</nav>
<footer class="site-footer">
This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
</footer>
</div>
<div class="main" id="top">
<div id="main-header" class="main-header">
<div class="search">
<div class="search-input-wrap">
<input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search ostreedev/ostree" aria-label="Search ostreedev/ostree" autocomplete="off">
<label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
</div>
<div id="search-results" class="search-results"></div>
</div>
<nav aria-label="Auxiliary" class="aux-nav">
<ul class="aux-nav-list">
<li class="aux-nav-list-item">
<a href="https://github.com/ostreedev/ostree" class="site-button"
>
OSTree on GitHub
</a>
</li>
</ul>
</nav>
</div>
<div id="main-content-wrap" class="main-content-wrap">
<div id="main-content" class="main-content" role="main">
<h1 class="no_toc" id="using-composefs-with-ostree">
<a href="#using-composefs-with-ostree" class="anchor-heading" aria-labelledby="using-composefs-with-ostree"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Using composefs with OSTree
</h1>
<ol id="markdown-toc">
<li><a href="#composefs" id="markdown-toc-composefs">composefs</a> <ol>
<li><a href="#enabling-composefs-unsigned" id="markdown-toc-enabling-composefs-unsigned">Enabling composefs (unsigned)</a></li>
<li><a href="#composefs-configuration" id="markdown-toc-composefs-configuration">composefs configuration</a></li>
<li><a href="#injecting-composefs-digests" id="markdown-toc-injecting-composefs-digests">Injecting composefs digests</a></li>
<li><a href="#signatures" id="markdown-toc-signatures">Signatures</a></li>
</ol>
</li>
<li><a href="#requirements" id="markdown-toc-requirements">Requirements</a></li>
<li><a href="#status" id="markdown-toc-status">Status</a></li>
<li><a href="#compatiblity" id="markdown-toc-compatiblity">Compatiblity</a></li>
<li><a href="#comparison-with-other-approaches" id="markdown-toc-comparison-with-other-approaches">Comparison with other approaches</a></li>
<li><a href="#further-references" id="markdown-toc-further-references">Further references</a></li>
</ol>
<!-- SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later) -->
<h2 id="composefs">
<a href="#composefs" class="anchor-heading" aria-labelledby="composefs"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> composefs
</h2>
<p>The <a href="https://github.com/containers/composefs">composefs</a> project is a new
hybrid Linux stacking filesystem that provides many benefits when
used for bootable host systems, such as a strong story for integrity.</p>
<p>At the current time, integration of composefs and ostree is experimental.
<a href="https://github.com/ostreedev/ostree/issues/2867">This issue</a> tracks the latest status.</p>
<h3 id="enabling-composefs-unsigned">
<a href="#enabling-composefs-unsigned" class="anchor-heading" aria-labelledby="enabling-composefs-unsigned"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Enabling composefs (unsigned)
</h3>
<p>When building a disk image <em>or</em> to transition an existing system, run:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ostree config --repo=/ostree/repo set ex-integrity.composefs true
</code></pre></div></div>
<p>This will ensure that any future deployments (e.g. created by <code class="language-plaintext highlighter-rouge">ostree admin upgrade</code>)
have a <code class="language-plaintext highlighter-rouge">.ostree.cfs</code> file in the deployment directory which is a mountable
composefs metadata file, with a “backing store” directory that is
shared with the current <code class="language-plaintext highlighter-rouge">/ostree/repo/objects</code>.</p>
<h3 id="composefs-configuration">
<a href="#composefs-configuration" class="anchor-heading" aria-labelledby="composefs-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> composefs configuration
</h3>
<p>The <code class="language-plaintext highlighter-rouge">ostree-prepare-root</code> binary will look for <code class="language-plaintext highlighter-rouge">ostree/prepare-root.conf</code> in <code class="language-plaintext highlighter-rouge">/etc</code> and
<code class="language-plaintext highlighter-rouge">/usr/lib</code> in the initramfs. Using that configuration file you can enable composefs,
and specify an Ed25519 public key to validate the booted commit.</p>
<p>See the manpage for <code class="language-plaintext highlighter-rouge">ostree-prepare-root</code> for details of how to configure it.</p>
<h3 id="injecting-composefs-digests">
<a href="#injecting-composefs-digests" class="anchor-heading" aria-labelledby="injecting-composefs-digests"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Injecting composefs digests
</h3>
<p>When generating an OSTree commit, there is a CLI switch <code class="language-plaintext highlighter-rouge">--generate-composefs-metadata</code>
and a corresponding C API <code class="language-plaintext highlighter-rouge">ostree_repo_commit_add_composefs_metadata</code>. This will
inject the composefs digest as metadata into the ostree commit under a metadata
key <code class="language-plaintext highlighter-rouge">ostree.composefs.v0</code>. Because an OSTree commit can be signed, this allows
covering the composefs fsverity digest with a signature.</p>
<h3 id="signatures">
<a href="#signatures" class="anchor-heading" aria-labelledby="signatures"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Signatures
</h3>
<p>If a commit is signed with an Ed25519 private key (see <code class="language-plaintext highlighter-rouge">ostree
--sign</code>), and <code class="language-plaintext highlighter-rouge">composefs.keyfile</code> is specified in <code class="language-plaintext highlighter-rouge">prepare-root.conf</code>,
then the initrd will find the commit being booted in the system repo
and validate its signature against the public key. It will then ensure
that the composefs digest being booted has an fs-verity digest
matching the one in the commit. This allows a fully trusted read-only
/usr.</p>
<p>The exact usage of the signature is up to the user, but a common way
to use it with transient keys. This is done like this:</p>
<ul>
<li>Generate a new keypair before each build</li>
<li>Embed the public key in the initrd that is part of the commit.</li>
<li>Ensure the initrd has a <code class="language-plaintext highlighter-rouge">prepare-root.conf</code> with <code class="language-plaintext highlighter-rouge">[composefs] enabled=signed</code>, and either use <code class="language-plaintext highlighter-rouge">keypath</code> or inject <code class="language-plaintext highlighter-rouge">/etc/ostree/initramfs-root-binding.key</code>; for more see <code class="language-plaintext highlighter-rouge">man ostree-prepare-root</code></li>
<li>After committing, run <code class="language-plaintext highlighter-rouge">ostree --sign</code> with the private key.</li>
<li>Throw away the private key.</li>
</ul>
<p>When a transient key is used this way, that ties the initrd with the
userspace part from the commit. This means each initrd can only boot
the very same userspace it was made for. For example, if an older
version of the OS has a security flaw, you cant boot a new fixed
(signed) initrd and have it boot the older userspace with the flaw.</p>
<h2 id="requirements">
<a href="#requirements" class="anchor-heading" aria-labelledby="requirements"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Requirements
</h2>
<p>The current default composefs integration in ostree does not have any
requirements from the underlying kernel and filesystem other than
having the following kernel options set:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">CONFIG_OVERLAY_FS</code></li>
<li><code class="language-plaintext highlighter-rouge">CONFIG_BLK_DEV_LOOP</code></li>
<li><code class="language-plaintext highlighter-rouge">CONFIG_EROFS_FS</code></li>
</ul>
<p>At the current time, there are no additional userspace runtime requirements.</p>
<h2 id="status">
<a href="#status" class="anchor-heading" aria-labelledby="status"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Status
</h2>
<p><strong>IMPORTANT</strong> The integration with composefs is experimental and subject to change. Please
try it and report issues but do not deploy to production systems yet.</p>
<h2 id="compatiblity">
<a href="#compatiblity" class="anchor-heading" aria-labelledby="compatiblity"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Compatiblity
</h2>
<p>One issue that ostree users transitioning to composefs may hit is that it is no
longer possible to add new toplevel directories via the <code class="language-plaintext highlighter-rouge">chattr -i / &amp;&amp; mkdir /somedir &amp;&amp; chattr -i</code>
trick. A bit more on this in the following issues:</p>
<ul>
<li><a href="https://github.com/coreos/rpm-ostree/issues/337">https://github.com/coreos/rpm-ostree/issues/337</a></li>
<li><a href="https://github.com/ostreedev/ostree/pull/2681">https://github.com/ostreedev/ostree/pull/2681</a></li>
</ul>
<p>However, users who were doing things like this probably want to enable the
<code class="language-plaintext highlighter-rouge">root.transient</code> option; see <code class="language-plaintext highlighter-rouge">man ostree-prepare-root</code> which will allow
this (but also change other behaviors too).</p>
<h2 id="comparison-with-other-approaches">
<a href="#comparison-with-other-approaches" class="anchor-heading" aria-labelledby="comparison-with-other-approaches"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Comparison with other approaches
</h2>
<p>There is also support for using <a href="/ostree/ima/">IMA</a> with ostree. In short, composefs
provides much stronger and more efficient integrity:</p>
<ul>
<li>composefs validates an entire filesystem tree, not just individual files</li>
<li>composefs makes files actually read-only, whereas IMA does not by default</li>
<li>composefs uses fs-verity which does on-demand verification (IMA by default does a full readahead of every file accessed, though IMA can also use fs-verity as a backend)</li>
</ul>
<h2 id="further-references">
<a href="#further-references" class="anchor-heading" aria-labelledby="further-references"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Further references
</h2>
<ul>
<li>https://github.com/containers/composefs</li>
<li>https://www.kernel.org/doc/html/next/filesystems/fsverity.html</li>
</ul>
<hr>
<footer>
<p class="text-small text-grey-dk-100 mb-0">Copyright &copy; <a href="https://www.redhat.com">Red Hat, Inc.</a> and <a href="https://github.com/ostreedev">others</a>.</p>
<div class="d-flex mt-2">
<p class="text-small text-grey-dk-000 mb-0">
<a href="https://github.com/ostreedev/ostree/tree/main/docs/composefs.md" id="edit-this-page">Edit this page on GitHub</a>
</p>
</div>
</footer>
</div>
</div>
<div class="search-overlay"></div>
</div>
</body>
</html>