Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A lot of my solution is derived from the post, <a href="http://binblog.info/2008/12/04/using-a-usb-key-for-the-luks-passphrase/">Using A USB Key For The LUKS Passphrase</a>.</p> <ol> <li><p>Create a random passphrase:</p> <pre><code>dd if=/dev/urandom bs=1 count=256 &gt; passphrase </code></pre></li> <li><p>Insert a USB drive. <code>dmesg</code> output will show the device name; assume <code>/dev/sdd</code>. Figure out its size:</p> <pre><code>blockdev --getsize64 /dev/sdd </code></pre></li> <li><p>I decided to install the passphrase at the end of the raw device, figuring it might survive any accidental use of the USB drive.</p> <pre><code>dd if=passphrase of=/dev/sdd bs=1 seek=&lt;size-256&gt; </code></pre></li> <li><p>Add the passphrase to the LUKS volume:</p> <pre><code>cryptsetup luksAddKey /dev/sda5 passphrase </code></pre> <p>This does not affect the existing hand-entered passphrase from the installer. The passphrase file can be deleted:</p> <pre><code>rm passphrase </code></pre></li> <li><p>Find a unique name for the USB stick, so we can identify it when present:</p> <pre><code>ls -l /dev/disk/by-id | grep -w sdd </code></pre> <p>You should see one symlink. I will call it <code>/dev/disk/by-id/&lt;ID&gt;</code>.</p></li> <li><p>Edit <code>/etc/crypttab</code>. You should see a line like:</p> <pre><code>sdc5_crypt UUID=b9570e0f-3bd3-40b0-801f-ee20ac460207 none luks </code></pre> <p>Modify it to:</p> <pre><code>sdc5_crypt UUID=b9570e0f-3bd3-40b0-801f-ee20ac460207 /dev/disk/by-id/&lt;ID&gt; luks,keyscript=/bin/passphrase-from-usb </code></pre></li> <li><p>The <code>keyscript</code> referred to above will need to read the passphrase from the USB device. However, it needs to do more than that. To understand how it is used, check <code>/usr/share/initramfs-tools/scripts/local-top/cryptroot</code>, the script that runs at boot time to unlock the root device. Note when a <code>keyscript</code> is set, it is simply run and the output piped to <code>luksOpen</code> with no other checking. There is no way to signal an error (USB drive not present) or fall back to keyboard input. If the passphrase fails, the keyscript is run again in a loop, up to some number of times; however we are not told which iteration we are on. Also, we have no control over when the keyscript is run, so we can't be sure Linux has recognized the USB drive.</p> <p>I addressed this with some hacks:</p> <ol> <li><p>Poll on the USB drive and wait 3 seconds for it to appear. This works for me, but I would love to know a better way. </p></li> <li><p>Create a dummy file <code>/passphrase-from-usb-tried</code> on first run to indicate that we have been run at least once.</p></li> <li><p>If we have been run at least once, or the USB drive cannot be found, run the <code>askpass</code> program used by <code>cryptroot</code> for keyboard input.</p></li> </ol> <p>The final script:</p> <pre><code>#!/bin/sh set -e if ! [ -e /passphrase-from-usb-tried ]; then touch /passphrase-from-usb-tried if ! [ -e "$CRYPTTAB_KEY" ]; then echo "Waiting for USB stick to be recognized..." &gt;&amp;2 sleep 3 fi if [ -e "$CRYPTTAB_KEY" ]; then echo "Unlocking the disk $CRYPTTAB_SOURCE ($CRYPTTAB_NAME) from USB key" &gt;&amp;2 dd if="$CRYPTTAB_KEY" bs=1 skip=129498880 count=256 2&gt;/dev/null exit else echo "Can't find $CRYPTTAB_KEY; USB stick not present?" &gt;&amp;2 fi fi /lib/cryptsetup/askpass "Unlocking the disk $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)\nEnter passphrase: " </code></pre> <p>Finally, we need to ensure that this script is available in the initramfs. Create <code>/etc/initramfs-tools/hooks/passphrase-from-usb</code> containing:</p> <pre><code>#!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" } case "$1" in prereqs) prereqs exit 0 ;; esac . "${CONFDIR}/initramfs.conf" . /usr/share/initramfs-tools/hook-functions copy_exec /bin/passphrase-from-usb /bin </code></pre></li> <li><p>The USB drivers were not present in my initramfs. (It appears they are by default in later versions of Debian.) I had to add them by adding to <code>/etc/initramfs-tools/modules</code>:</p> <pre><code>uhci_hcd ehci_hcd usb_storage </code></pre></li> <li><p>When all is done, update the initramfs:</p> <pre><code>update-initramfs -u </code></pre></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload