www

My personal website(s)
Log | Files | Refs

luks-key-sdcard.html (9474B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4 <!-- Sep 03, 2024 -->
      5 <meta charset="utf-8" />
      6 <meta name="viewport" content="width=device-width, initial-scale=1" />
      7 <title>Automatically unlock a luks encrypted partiiton with an SDCard</title>
      8 <meta name="author" content="Vincent Demeester" />
      9 <meta name="keywords" content="post" />
     10 <meta name="generator" content="Org Mode" />
     11 <link rel="stylesheet" type="text/css" href="/css/2022.css" />
     12 <link rel="stylesheet" type="text/css" href="/css/syntax.css" />
     13 <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/>
     14 <meta name='viewport' content='width=device-width, initial-scale=1'>
     15 </head>
     16 <body>
     17 <main id="content" class="content">
     18 <header>
     19 <h1 class="title">Automatically unlock a luks encrypted partiiton with an SDCard</h1>
     20 <p class="subtitle" role="doc-subtitle">… or a USB card.</p>
     21 </header><p>
     22 I am booting my work laptop (NixOS on a Thinkpad) from a LUKS-encrypted volume. I also do
     23 have another &ldquo;laptop&rdquo; (used as a build/server) that is LUKS-encrypted. So far, I&rsquo;ve been
     24 using a passphrase I type on boot. It&rsquo;s more than fine for my laptop, but it means it&rsquo;s a
     25 bit trickier for my other machine. I need to remove from its slot below my desk, type it
     26 and re-put it in the slot. This mean it&rsquo;s a bit harder to do upgrade and reboot without
     27 any input from me.
     28 </p>
     29 
     30 <p>
     31 For convenience, I want an SD card&rsquo;s LUKS volume to unlock and mount when the machine
     32 boots, rather than me needing to unlock and mount it each time.
     33 </p>
     34 
     35 <p>
     36 There is a bunch of articles about this, like <a href="https://possiblelossofprecision.net/?p=300">this one</a>. Or slightly related <a href="https://kyau.net/wiki/ArchLinux:LUKS">these</a> <a href="https://neilzone.co.uk/2021/07/auto-unlocking-a-luks-volume-on-an-sd-card-on-boot-with-debian-11-bullseye">ones</a>. I
     37 am using NixOS however, and it is actually making things relatively straightforward. The
     38 closer article to what I was looking for is <a href="https://medium.com/@geis/using-a-raw-usb-device-to-unlock-a-luks-volume-on-nixos-193406ee7474">this one</a> as well as the <a href="https://nixos.wiki/wiki/Full_Disk_Encryption">NixOS wiki entry</a> on
     39 full disk encryption.
     40 </p>
     41 
     42 <p>
     43 The idea is relatively simple : we are going to use a key file (hidden or not in a
     44 partition) to unlock a luks encrypted — with a fallback on passphrase (in case the medium
     45 is not there). There is 3 main steps :
     46 </p>
     47 <ul class="org-ul">
     48 <li>creating the key file and storing it somewhere</li>
     49 <li>add the key to a slot in the luks encrypted partition</li>
     50 <li>configuring NixOS to use it</li>
     51 </ul>
     52 <section id="outline-container-Creating%20a%20keyfile%20and%20storing%20it" class="outline-2">
     53 <h2 id="Creating%20a%20keyfile%20and%20storing%20it">Creating a keyfile and storing it</h2>
     54 <div class="outline-text-2" id="text-Creating%20a%20keyfile%20and%20storing%20it">
     55 <p>
     56 Creating a key file is very simple. If we are to use a file, we can just do the following:
     57 </p>
     58 
     59 <div class="org-src-container">
     60 <pre class="src src-bash">$ dd <span class="org-variable-name">if</span>=/dev/urandom <span class="org-variable-name">of</span>=hdd.key <span class="org-variable-name">bs</span>=4096 <span class="org-variable-name">count</span>=1
     61 </pre>
     62 </div>
     63 
     64 <p>
     65 I have two key to generate, one for <code>aomi</code> and one for <code>naruhodo</code>
     66 </p>
     67 
     68 <div class="org-src-container">
     69 <pre class="src src-bash">$ dd <span class="org-variable-name">if</span>=/dev/random <span class="org-variable-name">of</span>=naruhodo.key.bin <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
     70 4096+0 records<span class="org-keyword"> in</span>
     71 4096+0 records out
     72 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00947718 s, 432 kB/s
     73 
     74 $ dd <span class="org-variable-name">if</span>=/dev/random <span class="org-variable-name">of</span>=aomi.key.bin <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
     75 4096+0 records<span class="org-keyword"> in</span>
     76 4096+0 records out
     77 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00985101 s, 416 kB/s
     78 </pre>
     79 </div>
     80 
     81 <p>
     82 What we are going to do here is, to hide the key inside a sdcard or a usb stick. The idea
     83 is to use the first or the last few blocks to hide the key.
     84 </p>
     85 
     86 <div class="org-src-container">
     87 <pre class="src src-bash"><span class="org-comment-delimiter"># </span><span class="org-comment">This writes the aomi key to the "head" of sda (a sdcard)</span>
     88 $ sudo dd <span class="org-variable-name">if</span>=sync/aomi.key.bin <span class="org-variable-name">of</span>=/dev/sda <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
     89 <span class="org-comment-delimiter"># </span><span class="org-comment">This writes the naruhodo key to the "tail" of sdb (a usb card)</span>
     90 <span class="org-comment-delimiter"># </span><span class="org-comment">The offset has to be computed from the usb key size</span>
     91 $ sudo dd <span class="org-variable-name">if</span>=sync/naruhodo.key.bin <span class="org-variable-name">of</span>=/dev/sdb <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096 <span class="org-variable-name">seek</span>=30992883712
     92 </pre>
     93 </div>
     94 </div>
     95 </section>
     96 <section id="outline-container-Add%20the%20key%20to%20a%20slot" class="outline-2">
     97 <h2 id="Add%20the%20key%20to%20a%20slot">Add the key to a slot</h2>
     98 <div class="outline-text-2" id="text-Add%20the%20key%20to%20a%20slot">
     99 <p>
    100 This is probably the easiest step of all, this is just about running the following.
    101 </p>
    102 
    103 <div class="org-src-container">
    104 <pre class="src src-bash">$ cryptsetup luksAddKey $<span class="org-variable-name">LUKS_DEVICE</span> $<span class="org-variable-name">KEY</span>
    105 </pre>
    106 </div>
    107 
    108 <p>
    109 The only <i>trick</i> to it is : you have to do this &ldquo;offline&rdquo;, a.k.a. when the partition in
    110 locked (and thus not mounted, …). Either you do this when you are installing the operating
    111 system (and it&rsquo;s straightforward), or you need to boot your laptop/desktop with a livecd
    112 (that also then has access to the key).
    113 </p>
    114 </div>
    115 </section>
    116 <section id="outline-container-NixOS%20configuration" class="outline-2">
    117 <h2 id="NixOS%20configuration">NixOS configuration</h2>
    118 <div class="outline-text-2" id="text-NixOS%20configuration">
    119 <p>
    120 This is where NixOS helps greatly, we have just a few things to write, and NixOS will make
    121 sure all is correctly setup (the initramfs, …).
    122 </p>
    123 
    124 <div class="org-src-container">
    125 <pre class="src src-nix"><span class="org-comment-delimiter"># </span><span class="org-comment">For aomi, without offset</span>
    126 <span class="org-nix-attribute">boot.initrd.luks.devices</span> = {
    127   <span class="org-nix-attribute">root</span> = {
    128     <span class="org-nix-attribute">device</span> = <span class="org-string">"/dev/disk/by-uuid/{UUID}"</span>;
    129     <span class="org-nix-attribute">preLVM</span> = <span class="org-nix-builtin">true</span>;
    130     <span class="org-nix-attribute">allowDiscards</span> = <span class="org-nix-builtin">true</span>;
    131     <span class="org-nix-attribute">keyFile</span> = <span class="org-string">"/dev/disk/by-id/{DISKID}"</span>;
    132     <span class="org-nix-attribute">keyFileSize</span> = 4096;
    133     <span class="org-nix-attribute">fallbackToPassword</span> = <span class="org-nix-builtin">true</span>;
    134   };
    135 };
    136 <span class="org-comment-delimiter"># </span><span class="org-comment">For narudoho, with offset</span>
    137 <span class="org-nix-attribute">boot.initrd.luks.devices</span> = {
    138   <span class="org-nix-attribute">root</span> = {
    139     <span class="org-nix-attribute">device</span> = <span class="org-string">"/dev/disk/by-uuid/{UUID}"</span>;
    140     <span class="org-nix-attribute">preLVM</span> = <span class="org-nix-builtin">true</span>;
    141     <span class="org-nix-attribute">allowDiscards</span> = <span class="org-nix-builtin">true</span>;
    142     <span class="org-nix-attribute">keyFile</span> = <span class="org-string">"/dev/disk/by-id/{DISKID}"</span>;
    143     <span class="org-nix-attribute">keyFileOffset</span> = 30992883712;
    144     <span class="org-nix-attribute">keyFileSize</span> = 4096;
    145     <span class="org-nix-attribute">fallbackToPassword</span> = <span class="org-nix-builtin">true</span>;
    146   };
    147 };
    148 </pre>
    149 </div>
    150 
    151 <p>
    152 Now, we are a <code>nixos-rebuild</code> away from being able to boot a NixOS on a encrypted file
    153 system, without having to type the password <b>if we have the correct medium</b> inserted in
    154 the machine.
    155 </p>
    156 
    157 <p>
    158 <i>Of course, this means that the &ldquo;unlock&rdquo; medium becomes precious and important <b>not to</b>
    159 loose. If you go on vacation for example, you should definitely remove any of those medium
    160 and hide them (or bring them with you).</i>
    161 </p>
    162 </div>
    163 </section>
    164 </main>
    165 <footer id="postamble" class="status">
    166 <footer>
    167      <small><a href="/" rel="history">Index</a> • <a href="/sitemap.html">Sitemap</a> • <a href="https://dl.sbr.pm/">Files</a></small><br/>
    168      <small class='questions'>Questions, comments ? Please use my <a href="https://lists.sr.ht/~vdemeester/public-inbox">public inbox</a> by sending a plain-text email to <a href="mailto:~vdemeester/public-inbox@lists.sr.ht">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/>
    169      <small class='copyright'>
    170       Content and design by Vincent Demeester
    171       (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>)
    172     </small><br />
    173 </footer>
    174 </footer>
    175 </body>
    176 </html>