<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Encryption on inetshell</title><link>https://inet.sh/en/tags/encryption/</link><description>Recent content in Encryption on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 19 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/encryption/index.xml" rel="self" type="application/rss+xml"/><item><title>Native ZFS encryption (OpenZFS): create, inherit, change-key</title><link>https://inet.sh/en/posts/zfs/encryption/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/zfs/encryption/</guid><description>Create an encrypted OpenZFS dataset with a passphrase or keyfile, inherit encryption on children, and rotate keys with zfs change-key — not Solaris zfs key -c.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p><code>zfs create -o encryption=on …</code>. Children inherit. Rotate keys on Linux with <code>zfs change-key</code> (not Solaris <code>zfs key -c</code>).</p>
<p>OpenZFS encrypts <strong>datasets</strong>, not the whole pool. Pool labels and metaslabs stay visible; <code>tank/secret</code> contents do not. This is the TrueNAS / Proxmox / Linux path.</p>
<p>Background: <a href="https://arstechnica.com/gadgets/2021/06/a-quick-start-guide-to-openzfs-native-encryption/">Ars native encryption</a>, <a href="https://mtlynch.io/zfs-encrypted-backups/">ZFS encrypted backups</a>.</p>
<h2 id="create">Create</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs create -o <span class="nv">encryption</span><span class="o">=</span>on -o <span class="nv">keyformat</span><span class="o">=</span>passphrase -o <span class="nv">keylocation</span><span class="o">=</span>prompt tank/encrypted
</span></span><span class="line"><span class="cl">zfs create tank/encrypted/child1
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>child1</code> inherits encryption. Do not set <code>encryption=off</code> on a child: OpenZFS will not let you punch a plaintext hole under an encrypted parent.</p>
<p>Keyfile instead of prompt:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs create -o <span class="nv">encryption</span><span class="o">=</span>on -o <span class="nv">keyformat</span><span class="o">=</span>passphrase <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  -o <span class="nv">keylocation</span><span class="o">=</span>file:///root/zfs.key tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>The key file does <strong>not</strong> live on the encrypted dataset. USB, TPM, or a path on another pool.</p>
<h2 id="load-the-key-at-boot">Load the key at boot</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs load-key tank/encrypted
</span></span><span class="line"><span class="cl">zfs mount tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>Without <code>load-key</code> the dataset exists and <code>zfs list</code> shows it, but it will not mount.</p>
<h2 id="receive-plaintext-as-encrypted">Receive plaintext as encrypted</h2>
<p>On the <strong>first</strong> <code>recv</code> you can set encryption properties:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs send tank/test@snap1 <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  <span class="p">|</span> zfs recv -o <span class="nv">encryption</span><span class="o">=</span>on -o <span class="nv">keyformat</span><span class="o">=</span>passphrase <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>      -o <span class="nv">keylocation</span><span class="o">=</span>file:///path/to/keyfile tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>That receive is <strong>without</strong> <code>-w</code>. Raw <code>-w</code> copies the source wrapping key: only valid if the source was already encrypted. Details: <a href="/en/posts/zfs/send-unencrypted-to-encrypted/">unencrypted send into encrypted</a>.</p>
<h2 id="rotate-the-passphrase-openzfs">Rotate the passphrase (OpenZFS)</h2>
<p>On <strong>Solaris</strong> the command was <code>zfs key -c</code>. On <strong>OpenZFS / Linux / TrueNAS</strong>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs change-key tank/encrypted
</span></span><span class="line"><span class="cl">zfs get keyformat,keylocation,keystatus tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>New keyfile:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs change-key -o <span class="nv">keylocation</span><span class="o">=</span>file:///media/stick/key tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>Wrapping-key rekey (does not rewrite every block; rotates the key that wraps master keys) is <code>zfs change-key -i</code> depending on version — read <strong>your</strong> <code>zfs change-key</code> man page before production.</p>
<p>See also: <a href="/en/posts/zfs/hold-protect-snapshot/">snapshot holds</a>, <a href="/en/posts/zfs/backups-to-s3/">off-host backups</a>.</p>
]]></content:encoded></item><item><title>zfs send/recv from an unencrypted dataset into an encrypted one</title><link>https://inet.sh/en/posts/zfs/send-unencrypted-to-encrypted/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/zfs/send-unencrypted-to-encrypted/</guid><description>Migrate a plaintext ZFS dataset onto an encrypted one with zfs send | zfs recv -o encryption=on on the initial receive.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p>First <code>recv</code> with <code>-o encryption=on</code> (no <code>-w</code>). Destination dataset name is required.</p>
<p>Same bytes, new key. Source stays plaintext; destination is born encrypted. OpenZFS allows this <strong>only on the initial receive</strong> (dataset that does not exist yet).</p>
<p>Source thread: <a href="https://www.reddit.com/r/zfs/comments/mus2gn/zfs_sendreceive_from_enencrypted_dataset_to/">r/zfs</a>.</p>
<h2 id="command">Command</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs snapshot tank/test@snap1
</span></span><span class="line"><span class="cl">zfs send tank/test@snap1 <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  <span class="p">|</span> zfs recv -o <span class="nv">encryption</span><span class="o">=</span>on <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>      -o <span class="nv">keyformat</span><span class="o">=</span>passphrase <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>      -o <span class="nv">keylocation</span><span class="o">=</span>file:///path/to/keyfile <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>      tank/encrypted
</span></span></code></pre></td></tr></table>
</div>
</div><p>Things that silently break the send:</p>
<ol>
<li><strong>Do not use <code>-w</code>.</strong> Raw send replicates the source encryption state. Plaintext in → plaintext out, and <code>-o encryption=…</code> is ignored or errors.</li>
<li><strong>Name the destination dataset</strong> (<code>tank/encrypted</code>). A <code>recv</code> with no target does not create it.</li>
<li><strong>Passphrase vs file:</strong> <code>keylocation=prompt</code> is a bad fit across a non-interactive pipe. Use a keyfile.</li>
<li>Later incrementals (<code>-i</code>) <strong>inherit</strong> encryption. Do not pass <code>-o encryption=on</code> again.</li>
</ol>
<h2 id="check">Check</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zfs get encryption,keystatus,keyformat tank/encrypted
</span></span><span class="line"><span class="cl">zfs load-key tank/encrypted   <span class="c1"># if keystatus=unavailable</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="the-other-direction">The other direction</h2>
<p>Encrypted → encrypted with the <strong>same</strong> wrapping key: <code>zfs send -w</code>. Encrypted → new wrapping key: send <strong>without</strong> <code>-w</code> (ZFS decrypts on send; recv encrypts). That needs <code>load-key</code> on the source and is slower.</p>
<p>See also: <a href="/en/posts/zfs/encryption/">native encryption</a>.</p>
]]></content:encoded></item></channel></rss>