#!/bin/bash set +o xtrace +o verbose +o errexit -o errtrace trap 'set +o errexit; return 1' ERR trap 'set +o xtrace +o verbose +o errexit +o errtrace; return 2' INT TERM version=0.991 ############################################################################ # # lmdescrypt 0.991 # # Download shortlinks: https://4e4.win/lm or http://j.mp/lmdescrypt # # This script installs Linux Mint Debian Edition (201403), LMDE2 (201503 or # 201701), LMDE3 (201808), LMDE4 (202004) or regular Linux Mint 17, 17.1/2/3, # 18, 18.1/2/3, 19, 20, or Ubuntu 18.04, either i686 or amd64, with MSDOS or # GPT partitions, with UEFI or not. # The result: a fully LUKS encrypted system, with LVM2 volumes of root and # swap (and optionally: data) with optional boot partition # (with optional boot-from-iso-file). # # Shortlink to download the script: http://4e4.win/lmdescrypt # Tutorial on Linux Mint community: # https://community.linuxmint.com/tutorial/view/2265 # Gitlab page: https://gitlab.com/pepa65/lmdescrypt # Questions? Email pepa65@passchier.net or post an Issue on the gitlab page. # ############################################################################ ### CONTENTS: ## - INSTRUCTIONS for preparation and use ## - SETTINGS to be adjusted ## - FUNCTIONS used internally ## - MAIN action ############################################################################ ############################################################################ #### INSTRUCTIONS ############################################################################ ## ### 1. Boot the Live environment ## ### 2. Open a Terminal (Menu/Terminal of Ctrl-Alt-T) and enter: ##> sudo -i ##> wget 4e4.win/lmdescrypt ## ### 3. If needed, adapt the SETTINGS section: ##> nano lmdescrypt ## ### 4. Make sure all the partitions mentioned in SETTINGS exist ## For example, (re)partition the drive like this for non-UEFI ## (erasing all, taking up all space): ## ##> sgdisk -Zon1::+2M -t1:ef02 -c1:BIOS -n 2::-0 -t2:8e00 -c2:X -g /dev/sda ## ## For a UEFI setup instead, this example works: ## ##> sgdisk -Zon1::+260M -t1:ef00 -c1:EFI -n2::-0 -t2:8e00 -c2:X -g /dev/sda ## ## (This is giving almost the whole drive to the encrypted lvm2) ## ### 5. Start the script: ## ##> source lmdescrypt ## ### 6. Answer the questions as they come up: ## - set password for encryption ## Then after a wait for all the preparations to have happened: ## - set password for user ## - set timezone ## - configure keyboard ## ### And that's it! ## ### Installing into a pre-existing environment ## Using a pre-existing boot-partition, LUKS partition and LVM Logical ## Volumes is entirely supported. ## Not having a separate boot partition is also supported: total encryption! ## Multiple boot setups with other OSes also works out of the box. ## MBR, GPT partition tables and UEFI work according to configuration. ## ############################################################################ ############################################################################ #### SETTINGS ############################################################################ ## Review all settings in this section ### The device to be booted (for the grub bootloader: usually a drive!): grub_device=/dev/sda ## Adjust if needed (not needed if following the suggested partitioning) ## Specify the partitions you created by any valid device path, like: ## /dev/disk/by-label/... /dev/... /dev/disk/by-id/... ## Total encryption: boot_part should be empty ## UEFI setup: Must have an efi partition (type ef00) of at least 260M with a ## VFAT filesystem, will be formatted if not yet formatted! ## GPT non-UEFI setup: Must have a bios partition (type ef02) of at least 2M! ### Partitions to use: boot_part= crypt_part=/dev/sda2 ## When boot_part is not set, this is ignored ## If the boot partition is too small, the install will fail in the end! ### Set to 1 to include this iso as a file on boot partition to boot from include_isofile=1 ## When booting with total encryption, it is necessary to enter the password ## twice, once for grub and once for the kernel to decrypt the LUKS partition ## Entering a password only once to unlock is possible by using a keyfile that ## is stored in the initrd file, but anyone with read access to the initrd ## file could read it and use it to decrypt the LUKS-encrypted partition! ### Set to 1 to use an initrd keyfile (INSECURE!) when doing total encryption: insecure_keyfile=0 ## Set to 1 only if you already have a LUKS encrypted partition that you want ## to wipe and start from scratch. If set to 0 and there are pre-existing ## volumes that you want to erase, you can do it manually: ##> cryptsetup luksOpen ##> lvremove /dev// ### Wipe out the crypt-partition before setup, even if already set up, if 1: force_reencrypt=0 ## No strict need to adjust, unless paranoid. WARNING: Putting 1 here will ## take a LONG time (depending on partition size) - let it run overnight! ### Check for bad blocks and fill with pseudorandom data if 1: force_random=0 ## No need to adjust unless re-using existing volumes! ## If a Volume Group / Logical Volume with this name EXISTS, IT WILL BE USED! ## The data_label will also be the name of the mountpoint. ## If empty, the default NAME (as in NAME_label) will be used. ### Filesystem labels (no spaces): boot_label= vg_label= crypt_label= root_label= swap_label= data_label= ## Don't allot more space than available, and at least 6GB for root. ## Specify lvm2 volume sizes in gigabytes (G) or megabytes (M), no decimal ## points or spaces, like: 10G or 200M ## - if empty (only for swap or data) it will NOT BE USED ## - if EXISTING it will NOT be created, and then the Logical Volume needs ## to exist already (and so should the Volume Group then!) ## - If REST (only for root or data, not both) then the rest of the available ## space will be used ## - DEFAULT (only for swap) means 40% of RAM size (/sys/power/image_size) ## (See: https://www.kernel.org/doc/Documentation/power/interface.txt) ### Logical volume usage & sizes: root_size=REST swap_size=DEFAULT data_size= ## Adjust if re-using preexisting boot or data volumes! ## Fill in the desired filesystem-type, empty means it will NOT BE FORMATTED! ## (Pre-existing filesystem will be kept!) ## Supported for boot and root: btrfs ext2 ext3 ext4 reiserfs xfs. ## For swap: swap. For data: btrfs ext2 ext3 ext4 hfs hfsplus jfs minix msdos ## ntfs reiserfs vfat xfs ### Filesystems: boot_fs=ext4 root_fs=ext4 swap_fs=swap data_fs= ## Adjust if you require another encryption scheme, see /proc/crypto. ## Find the speeds on your hardware (and choose accordingly) by: ##> cryptsetup benchmark ## The -i parameter is the number of milliseconds iterating on THIS system! ### Parameters for cryptsetup luksFormat: cryptopts='-s 512 -h sha512 -i 5000 --type luks1' ## Adjust according to preference ### Username and hostname (no spaces): username=me hostname=mine ## Adjust according to preference; internet connection required! ### Extra packages to install (in between single quotes, seperated by space): packages='' ############################################################################ #### FUNCTIONS ############################################################################ Echo(){ ## $1=message echo -n '________________________________________________________________' echo -e '_______________\n' echo -e " $1" echo -n '________________________________________________________________' echo -e '_______________\n' } ## To really exit it needs to be followed by 'return' in the main body! Exit(){ ## $1=message Echo "ERROR: $1\n ABORTING" } Warning(){ ## $1=message echo -e "\n WARNING: $1\n" } Mkfs(){ ## $1=fs $2=label $3=dev $4=kind case $1 in hfs|hfsplus|jfs|minix|msdos|vfat|ntfs) [[ ! $4 = data ]] && return 3 ;;& ## Continue even if the above pattern matched (unless $4 isn't data) btrfs) mkfs.$1 -f -L "$2" "$3" ;; ext2|ext3|ext4) mkfs.$1 -F -L "$2" "$3" ;; hfs) mkfs.$1 -h -v "$2" "$3" ;; hfsplus) mkfs.$1 -J -v "$2" "$3" ;; jfs) mkfs.$1 -q -L "$2" "$3" ;; minix) mkfs.$1 "$3" ;; msdos|vfat) mkfs.$1 -n "$2" "$3" ;; ntfs) mkfs.$1 -f -F -U -L "$2" "$3" ;; reiserfs) mkfs.$1 -ffl "$2" "$3" ;; xfs) mkfs.$1 -f -L "$2" "$3" ;; *) return 4 ;; esac } Checklabel(){ ## $1: labelname label="$1_label" content=$(eval "echo \$$label") [[ $content ]] || eval "$label=$1" [[ ! $content = ${content/ } ]] && Exit "Label $label contains spaces: '$content'" } ############################################################################ #### MAIN ############################################################################ self=$(basename $BASH_SOURCE) ## If not run interactively, don't run [[ $- != *i* ]] && Exit "Must be sourced! Run it like:\n source $self" && exit 1 ((EUID)) && Exit "Must be run with root privileges, do:\n sudo -i\n source $self" && return 5 ## Set parameters from commandline for p in "$@" do [[ ! $p =~ ^[a-z_][a-z0-9_]*= ]] && Exit "No variable assignment: $p" && return 6 q="${p/=/=\'}'" ! eval "$q" && Exit "Failed argument evaluation: '$p'" && return 7 echo " ${q%%=*}: ${q#*=}" done ## Check existence of mandatory devices [[ ! -w "$crypt_part" ]] && Exit "Crypt device does not exist or is not writable: '$crypt_part'" && return 8 [[ ! -w "$grub_device" ]] && Exit "Grub device does not exist or is not writable: '$grub_device'" && return 9 ## Check names, labels, root_fs [[ ! $username =~ ^[a-z_][a-z0-9_]*$ ]] && Exit "Illegal format for username: '$username'" && return 10 [[ ! $hostname =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$ ]] && Exit "Illegal format for hostname: '$hostname'" && return 11 Checklabel crypt && return 12 Checklabel vg && return 13 Checklabel boot && return 14 Checklabel root && return 15 Checklabel swap && return 16 Checklabel data && return 17 [[ ! $root_fs =~ ^(btrfs|ext2|ext3|ext4|reiserfs|xfs|)$ ]] && Exit "Wrong value for root_fs: '$root_fs'" && return 18 ## Determine root and data partition usage & size [[ $root_size ]] && [[ ! $root_size = REST ]] && [[ ! $root_size = EXISTING ]] && [[ ! $root_size =~ [1-9][0-9]*[MG] ]] && Exit "Invalid format root_size: '$root_size'" && return 19 if [[ $data_size = REST ]] then [[ $root_size = REST ]] && Exit "Settings data_size and root_size can't both be REST" && return 20 lvm_data='-l 100%FREE -Zy' else if [[ $data_size && ! $data_size = EXISTING ]] then [[ ! $data_size =~ [1-9][0-9]*[MG] ]] && Exit "Invalid format data_size: '$data_size'" && return 21 lvm_data="-L $data_size -Zy" fi fi ## Set swap size if [[ $swap_size = DEFAULT ]] then lvm_swap="-L $(cat /sys/power/image_size)B -Cy -Zy" else if [[ ! $swap_size = EXISTING ]] then [[ $swap_size ]] && [[ ! $swap_size =~ [1-9][0-9]*[MG] ]] && Exit "Invalid format swap_size: $swap_size" && return 22 lvm_swap="-L $swap_size -Cy -Zy" fi fi ## Check type of setup gdisk=$(echo 2 |gdisk -l "$grub_device") efi_part= if ! grep -q ' GPT: not present$' <<<"$gdisk" then ## GPT partition scheme if [[ -e /sys/firmware/efi ]] then ## UEFI: so it is an amd64 architecture that supports UEFI read n discard <<<"$(grep ' EF00 ' <<<"$gdisk" |head -1)" [[ -z $n ]] && Exit "UEFI without type ef00 efi partition!" && return 23 efi_part="$grub_device$n" [[ ! $(lsblk "$efi_part" -no FSTYPE) = vfat ]] && mkfs.vfat -n EFI "$efi_part" else ## non-UEFI GPT setup ! grep -q ' EF02 ' <<<"$gdisk" && Exit "Non-UEFI GPT setup without type ef02 bios partition" && return 24 fi fi Echo "$self $version\n Install Linux Mint with LUKS encryption" ## Encrypt pwf=$(mktemp) pwf2=$(mktemp) chmod 600 "$pwf" "$pwf2" while [[ ! -s "$pwf" ]] do /lib/cryptsetup/askpass "Enter encryption password:" >"$pwf" echo if [[ -s "$pwf" ]] then /lib/cryptsetup/askpass "Enter the same password again:" >"$pwf2" echo diff -q --label $'\b\b\b\b\b\b\b\bFirst' "$pwf" \ --label "second password" "$pwf2" || shred -u "$pwf" shred -u "$pwf2" else echo -e "Empty password not allowed\n" fi done if ((force_reencrypt)) then ((force_random)) && badblocks -c 10240 -s -w -t random -v "$crypt_part" cryptsetup luksFormat $cryptopts "$crypt_part" --key-file "$pwf" else cryptsetup isLuks "$crypt_part" && Warning "$crypt_part is already formatted, reencryption not forced" || cryptsetup luksFormat $cryptopts "$crypt_part" --key-file "$pwf" fi if [[ -z $boot_part ]] && ((insecure_keyfile)) then key=crypto_keyfile.bin dd bs=512 count=4 if=/dev/urandom of="/root/$key" cryptsetup luksAddKey "$crypt_part" "/root/$key" --key-file "$pwf" fi ## Decrypt if not yet mapped crypt_dev="/dev/mapper/$crypt_label" [[ ! -b "$crypt_dev" ]] && ! cryptsetup luksOpen "$crypt_part" $crypt_label --key-file "$pwf" && shred -u "$pwf" && Exit "Failed to open the encrypted partition $crypt_part" && return 25 shred -u "$pwf" crypt_uuid=$(blkid -s UUID -o value "$crypt_part") ## Make lvm2 volumes if not there yet and make filesystems if wanted vgchange -ay vg_dev="/dev/mapper/$vg_label" [[ " $vg_label" = "$(vgs --noheadings -o vg_name)" ]] || vgcreate -Zy $vg_label $crypt_dev root_dev="/dev/$vg_label/$root_label" data_dev="/dev/$vg_label/$data_label" swap_dev="/dev/$vg_label/$swap_label" ## Create & format swap if wanted if [[ $swap_size ]] then [[ ! -h $swap_dev ]] && lvcreate -Wy $lvm_swap -n $swap_label $vg_label if [[ $swap_fs ]] then [[ ! $swap_fs = swap ]] && Exit "Wrong value for swap_fs: '$swap_fs'" && return 26 || mkswap -f -L $swap_label "$swap_dev" fi fi ## Create and format root partition, and data partition if wanted [[ ! $root_size = REST ]] && [[ ! -h $root_dev ]] && lvcreate -Wy -L $root_size -Zy -n $root_label $vg_label if [[ $data_size ]] then ## Create if it doesn't exist and format if required [[ ! -h $data_dev && $data_size = EXISTING ]] && Exit "There is no existing data device $data_dev" && return 27 lvcreate -Wy $lvm_data -n $data_label $vg_label if [[ $data_fs ]] then ! Mkfs "$data_fs" "$data_label" "$data_dev" data && Exit "Unsupported filesystem $data_fs for data volume $data_dev with label $data_label" && return 28 else ## No data filesystem specified: existing or bust if [[ $data_size = EXISTING ]] then ! data_fs=$(lsblk "$data_dev" -no FSTYPE 2>/dev/null) && Exit "No filesystem specified for data volumeand none present" && return 29 else Exit "No filesystem specified for data volume" return 30 fi fi fi [[ $root_size = REST ]] && [[ ! -h $root_dev ]] && lvcreate -Wy -l 100%FREE -Zy -n $root_label $vg_label if [[ $root_fs ]] then ! Mkfs "$root_fs" "$root_label" "$root_dev" root && Exit "Unsupported filesystem $root_fs for root-device $root_dev with label $root_label" && return 31 else root_fs=$(lsblk "$root_dev" -no FSTYPE 2>/dev/null) [[ -z $root_fs ]] && Exit "Root volume is not has no filesystem, fill in 'root_fs'" && return 32 [[ ! $root_fs =~ ^(btrfs|ext2|ext3|ext4|reiserfs|xfs)$ ]] && Exit "Root partition has unsupported filesystem: $root_fs" && return 33 fi if [[ $boot_part ]] then [[ ! $boot_fs =~ ^(btrfs|ext2|ext3|ext4|reiserfs|xfs|)$ ]] && Exit "Wrong value for boot_fs: '$boot_fs'" && return 34 if [[ $boot_fs ]] then ! Mkfs "$boot_fs" "$boot_label" "$boot_part" boot && Exit "Unsupported filesystem $boot_fs for boot-device $boot_part with label $boot_label" && return 35 else boot_fs=$(lsblk "$boot_part" -no FSTYPE 2>/dev/null) [[ -z $boot_fs ]] && Exit "Boot partition $boot_part has no filesystem, fill in 'boot_fs' (or leave boot_part empty)" && return 36 fi boot_uuid=$(blkid -s UUID -o value "$boot_part") fi ## Mount [[ $swap_size ]] && swapon "$swap_dev" && swapon -s target='/target' mkdir -p "$target" mount "$root_dev" "$target" if [[ $boot_part ]] then mkdir -p "$target/boot" mount "$boot_part" "$target/boot" fi if [[ $data_size ]] then mkdir -p "$target/$data_label" mount "$data_dev" "$target/$data_label" fi ## Copy rofsde='/lib/live/mount/rootfs/filesystem.squashfs' rofslm='/rofs' lmde=0 lmde4=0 if [[ -d /lib/live ]] then ## Debian Edition [[ -h $rofsde/vmlinuz ]] && lmde4=1 lmde=1 rofs=$rofsde else ## regular Mint rofs=$rofslm fi Echo "Copying the system files..." cp -a "$rofs"/* "$target" aptsrc="/etc/apt/sources.list" rm "$target/$aptsrc" osrelease=$("$target/etc/fstab" [[ $root_fs = btrfs ]] && echo "$root_dev / $root_fs defaults,compress 0 1" >>"$target/etc/fstab" || echo "$root_dev / $root_fs defaults,relatime,errors=remount-ro 0 1" \ >>"$target/etc/fstab" [[ $swap_size ]] && echo "$swap_dev $swap_label swap sw 0 0" >>"$target/etc/fstab" [[ $data_size ]] && echo "$data_dev /$data_label $data_fs relatime 0 2" >>"$target/etc/fstab" p3=none p4=luks if [[ -z $boot_part ]] then if ((insecure_keyfile)) then keytarget="$target/etc/initramfs-tools/hooks/crypto_keyfile" mv "/root/$key" "$target/root/$key" chmod 000 "$target/root/$key" echo "cp /root/$key \"\${DESTDIR}\"" >"$keytarget" chmod +x "$keytarget" p3="/$key" p4="luks,keyscript=/bin/cat" fi sed -i '/^GRUB_TIMEOUT/a GRUB_ENABLE_CRYPTODISK=y' "$target/etc/default/grub" gcl="GRUB_CMDLINE_LINUX=\"cryptdevice=$crypt_part:$crypt_label\"" sed -i "s@^GRUB_CMDLINE_LINUX=\"\"@$gcl@" "$target/etc/default/grub" sed -i 's@ splash"$@"@' "$target/etc/default/grub" else echo "UUID=$boot_uuid /boot $boot_fs relatime 0 2" >>"$target/etc/fstab" if ((include_isofile)) then cd=$(df |grep -o '^/dev/sr..') isoname=$(grep '^GRUB_TITLE=' "$target/etc/linuxmint/info") isoname=${isoname/GRUB_TITLE=/} isofile="/$(date +%s).iso" Echo "Copying the iso..." dd if=$cd of="$target/boot$isofile" (cd "$target/boot"; ln -s "$isofile" "$isoname") ((lmde)) && dir=live || dir=casper sdxn=$(readlink -e "$boot_part") x=$(grep -o '/sd.' <<<"$sdxn") root="hd$(($(printf '%d' "'${x: -1}")-97)),msdos${sdxn//[^0-9]/}" echo "ISO $isoname is on ($root)$isofile" cat <<-X >>"$target/etc/grub.d/40_custom" menuentry "Boot from ISO $isoname ($isofile)" { set root='$root' set isofile='$isofile' loopback loop \$isofile linux (loop)/$dir/vmlinuz boot=$dir iso-scan/filename=\$isofile noeject noprompt splash -- initrd (loop)/$dir/initrd.lz } X fi fi sed -i 's/^GRUB_TIMEOUT=10/GRUB_TIMEOUT=4/' "$target/etc/default/grub" sed -i 's/^GRUB_HIDDEN_TIMEOUT=0/#GRUB_HIDDEN_TIMEOUT=0/' "$target/etc/default/grub" echo "$crypt_label UUID=$crypt_uuid $p3 $p4" >"$target/etc/crypttab" sed "s/mint/$hostname/g" /etc/hosts >"$target/etc/hosts" echo $hostname >"$target/etc/hostname" echo "$LANG UTF-8" >>"$target/etc/locale.gen" mv "$target/etc/lvm/lvm.conf" "$target/etc/lvm.conf_orig" echo -e "devices {\n multipath_component_detection = 0\n md_component_detection = 0\n}\n\nactivation {\n udev_sync = 0\n udev_rules = 0\n}\n" >"$target/etc/lvm/lvm.conf" mdm=/etc/mdm/mdm.conf ldm=/etc/lightdm/lightdm.conf [[ -f $mdm ]] && dm=$mdm || dm=$ldm sed "s/mint/$username/g" "$dm" >"$target$dm" rm -- "$target/etc/resolv.conf" ## remove symlink cp /etc/resolv.conf "$target/etc" cryptsetup luksHeaderBackup --header-backup-file "$target/root/$crypt_label.luksHeaderBackup" "$crypt_part" chmod 400 "$target/root/$crypt_label.luksHeaderBackup" cp "$(readlink -e $BASH_SOURCE)" "$target/root/$self" if ((lmde4)) then cp /run/live/medium/live/vmlinuz "$target/boot/vmlinuz-$(uname -r)" else ((lmde)) && cp /lib/live/mount/medium/live/vmlinuz "$target/boot/vmlinuz-$(uname -r)" || cp /cdrom/casper/vmlinuz "$target/boot/vmlinuz-$(uname -r)" fi mount --bind /dev "$target/dev" ## Prepare the chroot script inside="/root/$self.inside" ( ## Subshell start cat </dev/null && localectl set-locale LANG=$LANG useradd -ms /bin/bash $username pwf=\$(mktemp) pwf2=\$(mktemp) chmod 600 "\$pwf" "\$pwf2" while [[ ! -s "\$pwf" ]] do /lib/cryptsetup/askpass "Enter password for user $username: " >"\$pwf" echo if [[ -s "\$pwf" ]] then /lib/cryptsetup/askpass "Enter the same password again: " >"\$pwf2" echo diff -q --label \$'\b\b\b\b\b\b\b\bFirst' "\$pwf" \ --label "second password" "\$pwf2" || shred -u "\$pwf" shred "\$pwf2" else echo -e "Empty password not allowed\n" fi done chpasswd <<<"$username:\$(cat "\$pwf")" addgroup $username sudo X ((lmde)) && echo 'chpasswd <<<"root:$(cat "$pwf")"' || echo 'passwd -l root' cat </dev/null if [[ "$efi_part" ]] then mkdir /media/cdrom mdev=$(grep ' iso9660 ' /proc/mounts) mount "${mdev%% *}" /media/cdrom apt-cdrom -m add -d=/media/cdrom sed -i 's/^deb /deb [arch=amd64] /g' "$aptsrc" fi if [[ "$packages" ]] then [[ "$efi_part" ]] || apt-get update apt-get --yes install $packages fi X if ((lmde)) then echo "apt-get -qq purge '^live-.*'" echo 'rm -rvf /lib/live' echo 'update-initramfs -c -k $(uname -r)' fi efi_dir=/boot/efi cat </dev/null umount /dev/pts umount /proc umount /sys [[ -f /lvm.pid ]] && kill -9 \$(cat /lvm.pid) && rm /lvm.pid exit 0 X ## Subshell end ) >"$target$inside" chmod +x "$target$inside" ## Enter the fresh installation to finish up Echo "Finalizing settings on the install" chroot "$target" "$inside" [[ $(df --output=pcent $target |tail -1) = 100% ]] && Exit "The filesystem on $root_dev is 100% full" && return 37 [[ $boot_part && $(df --output=pcent $target/boot |tail -1) = 100% ]] && Exit "The filesystem on $boot_part is 100% full" && return 38 mv "$target/etc/lvm.conf_orig" "$target/etc/lvm/lvm.conf" umount "$target/dev" [[ $boot_part ]] && umount "$target/boot" [[ $data_size ]] && umount "$target/$data_label" umount "$target" [[ $swap_size ]] && swapoff "$swap_dev" sync sleep 1 ! vgchange -an && Exit "Not able to close all logical volumes" && return 39 sync sleep 1 ! cryptsetup luksClose $crypt_label && Exit "Not able to cleanly close crypt" && return 40 sync Echo "Ready for reboot!" return 0