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 “laptop” (used as a build/server) that is LUKS-encrypted. So far, I’ve been 24 using a passphrase I type on boot. It’s more than fine for my laptop, but it means it’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’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’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 “offline”, 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’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 “unlock” 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>