User Tools

Site Tools


docs:guide-user:storage:disk.encryption

Disk Encryption

You may want to encrypt your external disk to improve privacy (in case other people have physical access to your router) or so that you can securely reuse the disk later for another purpose if it's flash (see SSDs prove difficult to securely erase).

Install encryption packages:

# opkg install kmod-crypto-ecb kmod-crypto-xts kmod-crypto-iv kmod-crypto-misc kmod-crypto-user cryptsetup

Install ext4 packages:

# opkg install kmod-fs-ext4 e2fsprogs

There are different ways of handling the encryption key. In this example we generate a new random key on every mount.

Don't follow these instructions blindly! Read the CryptSetup FAQ to learn more about the cryptsetup command.

The following command will create a standard encrypted container on the device or partition [encrypted-device] (eg. /dev/sda), and requires you to enter a passphrase that will be used to access the encrypted data later. WARNING: This will destroy anything on [encrypted-device]!

# cryptsetup luksFormat [encrypted-device]

This step may take a long time while /dev/random gathers enough entropy to generate the key. The security of the passphrase is based on it's strength and the number of iterations it is hashed… as the CPU on embedded systems is usually slow, it's advisable to force the use of a higher iteration count for simple passphrases: use the option –iter-time=[milliseconds] to increase the iteration count (default is usually 2000 milliseconds. Note: higher values will increase the time it takes to map the device, not access it once it's mounted).

To use the encrypted container, you must map a decrypted device… this must be done before the device can be formatted or mounted (eg. after each reboot). The following command creates a mapping called [map-name] (you can choose the name yourself, eg. crypt) – you must supply the same passphrase you used when performing luksFormat above.

# cryptsetup open [encrypted-device] [map-name]

Format and mount the (now available) decrypted device. [mount-point] is where you want the filesystem mounted (eg. /mnt):

# mkfs.ext4 /dev/mapper/[map-name]
# mount /dev/mapper/[map-name] [mount-point]

On a fresh reboot, you just need for perform the mapping and mount (Note: the mapping will require a passphrase)

# cryptsetup open [encrypted-device] [map-name]
# mount /dev/mapper/[map-name] [mount-point]

Unmount:

# umount [mount-point]
# cryptsetup close [map-name]

Automated:

The following script can be used to automate decrypting and mounting removable storage that is encrypted by using entries in /etc/crypttab (like many linux distros) and /etc/config/fstab:

#!/bin/bash
# Perform tasks when called by BLOCK hotplug (/etc/hotplug.d/block/99-lukscrypt)
# CC0: 21JUL18 by WaLLy3K, updated 09AUG18
# Further adapted for OpenWRT 18.06 by jmm on 2018-09-04

# Hotplug Vars: $ACTION (add/remove), $DEVICE (?), $DEVNAME (sdx)

# logger -s "start decrypt luks" $DEVNAME $ACTION;

[[ -z "${DEVNAME}" ]] && DEVNAME="${1##*/}"
msg() { logger -st "$(basename "${0%.*}")($DEVNAME)[$$]" -- "$@"; }

if [[ ! "$ACTION" == "add" ]];
then
  #only do something if a device is being added
  exit 0;
fi

if [[ "$DEVNAME" == dm-[0-9] ]];
then
  #/dev/mapper block device has been created so now try to mount FS if set up
  # in /etc/config/fstab (or LuCI > System > Mount Points)
  block mount;
  exit 0;
fi

BID_RAW="$(block info "/dev/$DEVNAME" | awk -v RS=' ' '{gsub("[:\"]",""); print $0}')"
BID_UUID="$(awk -F= '/UUID/ {print $2}' <<< "$BID_RAW")"
BID_TYPE="$(awk -F= '/TYPE/ {print $2}' <<< "$BID_RAW")"

# Determine whether drive needs to be decrypted
[[ ! -r "/etc/crypttab" ]] && { msg "Unable to read file: /etc/crypttab"; exit 1; }
CT_RAW="$(grep "$BID_UUID" /etc/crypttab)"

if [[ -n "${CT_RAW:-}" ]]; then
  CT_LABEL="$(awk '{print $1}' <<< "$CT_RAW")"
  CT_KEYFILE="$(awk '{print $3}' <<< "$CT_RAW")"
  CT_TYPE="$(awk -F '[ ,]+' '{print $4}' <<< "$CT_RAW")"
  #CT_SCRIPT="$(awk -F "keyscript=" '{print $2}' <<< "$CT_RAW")"

  if [[ -e "/dev/mapper/${CT_LABEL,,}" ]]; then
    msg "Drive already decrypted: $CT_LABEL"
    exit 0
  fi

  # Error Handling
  if [[ ! -e "$CT_KEYFILE" ]]; then
    msg "Unable to view keyfile: '$CT_KEYFILE'"
    exit 1
  fi
  if [[ ! "${BID_TYPE,,}" == *"${CT_TYPE,,}"* ]]; then
    msg "Unable to decrypt format: $CT_TYPE"
    exit 1
  fi

  msg "Decrypting drive: $CT_LABEL (/dev/$DEVNAME)"
  cryptsetup luksOpen "/dev/$DEVNAME" "${CT_LABEL,,}" -d "$CT_KEYFILE"
  CS_EXIT="$?"
  case "$CS_EXIT" in
    0)  if test -e "/dev/mapper/${CT_LABEL,,}"; then
          msg "Drive decrypted: $CT_LABEL"
        else
          msg "Drive not found after decrypting: $CT_LABEL"
          exit 1
        fi;;
    5) msg "Device already exists: $CT_LABEL (Dmsetup stuck?)"; exit 1;;
    *) msg "Unable to decrypt drive: $CT_LABEL ($CS_EXIT)"; exit 1;;
  esac

fi

note: this needs bash and awk installed and the #!/bin/bash does not seem to work for me on 18.06 so I created a script in the /etc/hotplug.d/block/ directory that looks like this:

bash path-to-decrypt-script.sh

The above script does not unmount or remove /dev/mapper devices when a USB device is removed so this must be done manually as outlined above.

Example

A video demonstration on OpenWrt 14.07 Barrier Breaker using LUKS: https://www.youtube.com/watch?v=NSVWb6dscVI (broken link, 07.Mar.2016)

docs/guide-user/storage/disk.encryption.txt · Last modified: 2018/09/05 02:43 by jmawhorter