Dropbox 9 – Dropbox Server (USB Key)

The purpose of the USB drive is multifaceted. We need a partition to store our encrypted logs that the client can send to us to assist in troubleshooting if (when) things go wrong. We also need to be able to send them new encrypted config files to place on the drive that the Dropbox Server will then pull from. There will also be a small partition of random data at the end of the drive from which we will create a key to decrypt the Dropbox Server’s non-boot partitions. One of our requirements is to have minimal client interaction so we can’t have them entering the encryption password every time the device needs rebooted.

Having the key “hidden” on the USB solves several problems. It prevents auto-decryption by an attacker during shipment to the client if we send the Dropbox Server and the USB key separately. We can also remotely wipe the key material before we shutdown the device so that the drive cannot be auto-decrypted during return shipment. Finally, after we receive the Dropbox Server we can still access the data with the passphrase and restore the key if desired.

A SanDisk Ultra Fit 16GB USB 3.0 works great for this purpose. It fits discreetly into the Dropbox Server and has ample room for the logs and configs.

Prepare the Dropbox Server for the next few steps.

mkdir /root/.ssh/

mkdir /root/scripts/

mkdir /root/configs/

mkdir /root/logs/

Now prepare the USB drive. I prefer putting it into the front USB 3.0 slot near the power switch since it is the one thing the client may need to access.

With gparted or your favorite partition manager configure the drive (probably /dev/sdb) as follows.

(/sdb1) 14660MiB fat32 with 3MiB Free space following, labeled USB.

USB Storage
USB Storage

(/sdb2) 3MiB ext4 no label.

USB Key
USB Key

Write the changes.

Now fill the secondary partition with random data.

dd if=/dev/urandom of=/dev/sdb2 bs=1

You should see something like the following.

dd: error writing '/dev/sdb2': No space left on device
2097153+0 records in
2097152+0 records out
2097152 bytes (2.1 MB, 2.0 MiB) copied, 23.9881 s, 87.4 kB/s

Now create the key from sections of that random data.

dd if=/dev/sdb2 of=/root/configs/dbox-01.key bs=512 skip=4 count=8

You should see something similar to the following.

8+0 records in
8+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.0135305 s, 303 kB/s

We need to tell LUKS to use our key for decryption.

cryptsetup luksAddKey /dev/sda5 /root/configs/dbox-01.key

Enter the encryption passphrase you initially created during the Kali install.

Now the tricky bit. This is a munging of so many different resources that did/didn’t work that I really don’t remember who to credit and who to curse 😉

Print your crypttab.

cat /etc/crypttab

It should look something like the following.

sda5_crypt UUID=cb3c58a3-cdfc-40ff-bd18-85b01a8a99c0 none luks

If sda5_crypt is not referred to by UUID then you can get the UUID with the following command.

ls -l /dev/disk/by-uuid | grep -w sda5

Now we need to get the ID of the USB partition that holds our key material.

ls -l /dev/disk/by-id | grep -w sdb2

You should see something similar to the following.

lrwxrwxrwx 1 root root 10 Sep 12 23:09 usb-SanDisk_Ultra_Fit_4C530146140423118490-0:0-part2 -> ../../sdb2

We’re now going to modify our crypttab to follow the format.

sda5_crypt UUID=<UUID of /dev/sda5> /dev/disk/by-id/<ID of USB partition> luks,keyscript=/bin/passphrase-from-usb

So given the values used in the above examples (use your own!) we would enter the following.

sda5_crypt UUID=cb3c58a3-cdfc-40ff-bd18-85b01a8a99c0 /dev/disk/by-id/usb-SanDisk_Ultra_Fit_4C530146140423118490-0:0-part2 luks,keyscript=/bin/passphrase-from-usb

We now need to create the script that will use the key material from the USB (or fallback to ask for a passphrase should that fail).

vi/vim/nano /bin/passphrase-from-usb

#!/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..." >&2
 sleep 3
 fi
 if [ -e "$CRYPTTAB_KEY" ]; then
 echo "Unlocking the disk $CRYPTTAB_SOURCE ($CRYPTTAB_NAME) from USB key" >&2
 dd if="$CRYPTTAB_KEY" bs=512 skip=4 count=8 2>/dev/null
 exit
 else
 echo "Can't find $CRYPTTAB_KEY; USB stick not present?" >&2
 fi
fi

/lib/cryptsetup/askpass "Unlocking the disk $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)\nEnter passphrase: "

The script needs to be executable.

chmod 755 /bin/passphrase-from-usb

So this script will unlock the disk with the “random” data on the USB and fallback to a passphrase if the data isn’t present, but there’s one problem…the script lives on the hard drive that’s encrypted. We need to create a hook into the initial RAM file system.

vi/vim/nano /etc/initramfs-tools/hooks/passphrase-from-usb

#!/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

Update our initial RAM file system.

update-initramfs -u

The output should look something like the following.

update-initramfs: Generating /boot/initrd.img-4.6.0-kali1-amd64

If anything can go wrong it will be here…rub your lucky microchip and reboot.

If it worked you’ll see the Kali login (no LUKS passphrase prompt).

Leave a Reply

Your email address will not be published. Required fields are marked *