14

I have a virtualized CentOS 7 server that needs to mount multiple password-protected encrypted volumes. I cannot automatically map the devices on boot, because I don't have access to the console during the boot process to enter the decryption password. After I reboot the system, I have to manually run

cryptsetup luksOpen <device> <name>

to map each underlying block device to an encrypted device. That requires keeping notes on the UUID of each underlying block device and the name it maps to. Is there an easy way to automate this process? I can add the information to /etc/crypttab with the noauto keyword to prevent the devices from mounting on boot. However, I can't get cryptsetup to use the information from this file.

It would be great if there were a command like cryptsetup luksOpen <name> that would read /etc/crypttab to find the name of the underlying block device (similar to the way that you can can mount <mountpoint> if is defined in /etc/fstab).

Is there any way to get cryptsetup to read the mappings from /etc/crypttab?

Craig Finch
  • 370
  • 1
  • 4
  • 12

4 Answers4

9

You can use

sudo systemctl start systemd-cryptsetup@<name>

instead of

cryptsetup luksOpen UUID=... <name>

when you have an entry as follows in your /etc/crypttab:

<name> UUID=... none noauto

It will prompt you for the passphrase if needed.

The corresponding unit file is generated automatically by systemd-cryptsetup-generator.

You can list all generated unit files using

systemctl list-unit-files| grep systemd-cryptsetup

phiresky
  • 189
  • 1
  • 3
5

Have a look at cryptdisks_start and cryptdisks_stop, they do exactly that.

# cryptdisks_start <name>
# mount <mountpoint>
...stuff...
# umount <mountpoint>
# cryptdisks_stop <name>
Steven
  • 67
  • 1
  • 2
0

I think you want to experiment with systemd-cryptsetup-generator.

Normally this process runs during the initramfs boot, to dynamically generate systemd units that decrypt each block device listed in /etc/crypttab. You can then start those units whenever you wish, and you'll be prompted for any necessary passphrases.

Since this is a virtual machine, you should have access to the virtual console, meaning you could simply encrypt your filesystems normally and provide the passphrase at boot. Of course, the security of the encrypted filesystems is compromised anyway, simply by being used in a virtual machine, regardless of when you enter the passphrase.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
0

I made a bash script specifically for this case,
it parses crypttab to retrieve the uuid of device to open/close,
afterwards it uses fstab to store mount options.

As a convention I mount the encrypted device in the root folder on a directory named like the device node in /dev/mapper but capitalized;
for example, a device named xsnl in crypttab will mount on /Xsnl.

NB: you will need to use noauto option in both fstab and crypttab.

#!/bin/bash

usage(){
  echo "usage:   ./crypt.sh [open|close] <encrypted_dev>"
}

OP=$1
TARGET=$2

# we bail out in case no first argument is passed
if [[ $OP != 'close' ]] && [[ $OP != 'open' ]]; then
  usage
  echo "Exiting: first argument must be either 'lock' or 'unlock'."
  exit
fi

# we bail out in case no second argument is passed
if [[ -z $TARGET ]]; then
  usage
  echo "Exiting: second argument must be the name of the entry in fstab."
  exit
fi

# our convention is to give same name to fstab mount point (upperfirst) and crypttab name (lower)
MAPPDEV=$(echo $TARGET | awk '{print tolower($0)}')

ENCRYPTED_DEV=$(sudo grep -w $MAPPDEV /etc/crypttab)

# we bail out if we don't match a device in crypttab
if [[ -z $ENCRYPTED_DEV ]]; then
  usage
  echo "Exiting: no device named $MAPPDEV found in crypttab."
  exit
fi

SEC_FIELD=$( echo $ENCRYPTED_DEV | sed -r 's/\s+/ /g' | cut -d' ' -f2)

# now we have all the info,
# depending on $OP (operation mode) we decide what to do
if [[ $OP == 'close' ]]; then
  sudo umount /$TARGET
  sudo cryptsetup luksClose $MAPPDEV
  exit
fi

# if we get here we need to open and mount
sudo cryptsetup luksOpen $SEC_FIELD $MAPPDEV
sudo mount /$TARGET

gist

maioman
  • 209
  • 2
  • 4