#!/bin/bash # # open_sesame.sh -- semi-automated luksOpen of encrypted RAID clusters # # Copyright (C) 2018-2019 Andrew Marchetta # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Do not proceed unless user is root. verify_rootuser() { if [[ $EUID -ne 0 ]]; then printf "You must be root to run this script.\n" >&2 return 1 fi return 0 } # Do not proceed unless cryptsetup exists on the system locate_cryptsetup() { which cryptsetup 2>&1 >/dev/null err=$? if [[ $err -ne 0 ]]; then printf 'Could not locate cryptsetup.\n' >&2 printf '%s requires the cryptsetup binary to work.\n' "$0" >&2 return 1 fi return 0 } # Define a central configuration for the script. set_config() { # Define the UUIDs of the RAID members for later identification. Be sure to # replace the defaults with the UUIDs of your own devices! Naturally, you # should include an entry for each device in your RAID cluster, which may be # more than the two placeholder devices listed here. declare -g -a raid_members=( "12345678-9abc-def0-1234-56789abcdef0" "fedcba98-7654-3210-0f1e-2c3b4a596877" ) # Define the mountpoint for the RAID volume, assumed to be in fstab. Be sure to # change to change the default value if your system does not use it! declare -g raid_mountpoint="/mnt" declare -g mount_delay=2 } # Attempt to open the provided LUKS member. luks_openmember() { if [[ -z "$1" ]]; then printf "You must pass this function a single argument (others ignored)." >&2 return 1 fi if [[ -L "$(find "/dev/disk/by-id/dm-uuid-CRYPT-LUKS1-${raid_thismember//\-}-"* 2>/dev/null)" ]]; then printf "LUKS device %s already opened; skipping.\n" "$raid_thismember" else printf 'Attempting to open %s.\n' "$raid_thismember" printf 'Supply your passphrase when prompted.\n' cryptsetup luksOpen UUID="$raid_thismember" dev_"${raid_thismember}" err=$? if [[ $err -ne 0 ]]; then printf 'ERROR: cryptsetup reported error code %u\n' "$err" >&2 printf 'Check passphrase and make sure %s is a valid LUKS device.\n' "$raid_thismember" >&2 return 1 fi fi return 0 } # Attempt to luksOpen all listed devices. raid_tryopenall() { declare openfailure=0 for raid_thismember in "${raid_members[@]}"; do if luks_openmember "$raid_thismember"; then printf 'Successfully opened %s.\n' "$raid_thismember" else printf 'Failed to open %s.\n' "$raid_thismember" >&2 openfailure=1 fi done return $openfailure } # With both drives opened, it is now acceptable to attempt mounting the volume. raid_trymount() { echo "Waiting $mount_delay seconds before attempting mount..." sleep $mount_delay mount "$raid_mountpoint" err=$? if [[ $err -ne 0 ]]; then printf 'ERROR: mount reported error code %u\n' "$err" >&2 printf 'Ensure presence of /etc/fstab entry for %s\n' "$raid_mountpoint" >&2 return 1 fi return 0 } # Main routine. verify_rootuser || exit 1 locate_cryptsetup || exit 1 set_config || exit 1 declare ret=0 if raid_tryopenall; then if raid_trymount; then : else printf "Not proceeding due to fatal error.\n" >&2 ret=1 fi else printf "Not proceeding due to fatal error.\n" >&2 ret=1 fi exit $ret