Created
July 29, 2014 05:50
-
-
Save arpanpal010/ac9f610316d709da53aa to your computer and use it in GitHub Desktop.
wrapper for cryptsetup with LUKS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#script wrapper to create/(u)mount/resize encrypted non-root filesystems using cryptsetup + LUKS | |
#does NOT unmount automatically on shutdown. | |
#Truecrypt is insecure. | |
#more info: https://wiki.archlinux.org/index.php/Dm-crypt | |
#TODO | |
#move functions to own module function | |
#improve cli | |
#added create | |
#added open/close | |
#added extend | |
#doesn't need root login to mount, although needs sudo | |
#does not preserve passwords | |
#only works with fstype ext2-3-4 | |
#requires dd, sudo, cryptsetup, grep, head, (filemanager optional) | |
#filesystem type | |
fstype="ext4"; | |
#opens file manager if set | |
FILE_MANAGER="pcmanfm"; | |
#takes filepath and returns absolute filepath #$1=filename | |
function getabspath() { | |
echo `readlink -f "$1"`; | |
} | |
#get a mapper name from filename...e.g for container ~/priv.ate the mapper is priv #$1=filepath | |
function getmapper() { | |
fname=`basename "$1"`; | |
#echo $fname; | |
mapper=${fname%.*}; | |
if [ "$mapper" == "" ]; then echo "Invalid Mapper. Exiting..."; exit; | |
else echo "$mapper"; | |
fi; | |
} | |
#lists available loop devices | |
function listloop() { | |
losetup -a; | |
} | |
#list map devices in /dev/mapper | |
function listmap() { | |
ls /dev/mapper/; | |
} | |
#creating new containers - needs container path and size | |
function cryptcreate() { | |
#get abspath | |
filepath=`getabspath "$1"`; | |
#get mapper | |
mapper=`getmapper "$filepath"`; | |
#get bs and count | |
examt="$2"; | |
#get block_size from size - use first one if erranously multiple | |
exunit="`echo "$2" | grep -io '[KMGT]\?' | head -n 1`"; | |
#get count from size | |
excount="`echo "$2" | grep -o [0-9]*`"; | |
if [ $excount -lt 0 ] || [ $excount -eq 0 ]; then echo "Cannot use size \"$2\""; exit; fi; | |
#validate given filepath | |
#file exists - prompt | |
if [ -f "$filepath" ] && [ -s "$filepath" ]; | |
then | |
echo "Found file: $filepath"; | |
#directory exists - reject | |
elif [ -d "$filepath" ]; | |
then | |
echo "Cannot work with directory: $filepath";exit; | |
#file doesnt exist or zero size - try to create and fill | |
elif [ ! -e "$filepath" ] || [ ! -s "$filepath" ]; | |
then | |
echo "Creating container at $filepath"; | |
#try touch filepath exit if fails | |
touch "$filepath"; | |
if [ $? -eq 1 ]; then echo "Failed to create \"$filepath\""; exit; fi; | |
#fill with random data from /dev/urandom | |
echo "Filling $filepath with random data. Blocksize=1${exunit^^}, Count=$excount..." | |
dd if=/dev/urandom of="$filepath" bs="1${exunit^^}" count="$excount"; | |
echo "Done." | |
#everything else - exit | |
else | |
echo "Cannot find file: $filepath";exit; | |
fi; | |
#check if root, given only root can mount stuff | |
if (( $EUID != 0 )); then echo "Please provide sudo password for mount.";fi; | |
#get sudo password for mount | |
read -p "enter [sudo] password:" -s -r testpassword; | |
echo; #newline | |
#if not a LUKS container, exit..otherwise start setup LUKS | |
if [ `echo "$testpassword" | sudo -S cryptsetup isLuks "$filepath" && echo 1 || echo 0` == 1 ] | |
then | |
echo "Container is already setup LUKS Format. Try opening it..."; | |
exit; | |
fi; | |
echo "Setting up LUKS container..."; | |
#else mount container as loop device | |
echo "Mounting container as loop device..." | |
ld=`echo "$testpassword" | sudo -S losetup -f "$filepath" --show`; | |
echo "Loop device: $ld"; | |
#create luks headers | |
echo "Creating LUKS header..." | |
#get sudo password for mount | |
read -p "enter [dm-crypt] password:" -s -r cryptpassword; | |
echo; #newline | |
#sudo has not timed out yet so no need for password #find alternative | |
echo -n "$cryptpassword" | sudo cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha1 --iter-time 5000 --use-urandom --key-file - luksFormat "$ld"; | |
#setting up filesystem | |
echo "Setting up filesystem..." | |
#get mapper and unlock | |
echo "Unlocking device \"$ld\" as \"$mapper\""; | |
sudo cryptsetup luksOpen "$ld" "$mapper"; | |
#make filesystem with mkfs | |
echo -n "$testpassword" | sudo -S mkfs -t "$fstype" "/dev/mapper/$mapper"; | |
#lock again | |
echo "Removing and locking map \"$mapper\"..." | |
echo -n $testpassword | sudo -S cryptsetup luksClose "$mapper"; | |
#detach loop device before exit | |
echo "Detaching loop device $ld..."; | |
echo -n "$testpassword" | sudo -S losetup -d $ld; | |
echo "Finished setting up LUKS in $filepath"; | |
} | |
#open container - needs container path and mountpoint | |
function cryptopen() { | |
#show input | |
cfilepath=`getabspath "$1"`; | |
mfilepath=`getabspath "$2"`; | |
mapper=`getmapper "$cfilepath"`; | |
echo "Container: $cfilepath"; | |
echo "Mountpoint: $mfilepath"; | |
#if not root, given only root can mount stuff | |
if (( $EUID != 0 )); then echo "Please provide sudo password for mount.";fi; | |
#get sudo password for mount | |
read -p "enter [sudo] password:" -s -r testpassword; | |
echo; #newline | |
#mount container as loop device | |
echo "Mounting container as loop device..." | |
ld=`echo -n "$testpassword" | sudo -S losetup -f "$cfilepath" --show`; | |
if [ "$ld" == "" ]; then echo "Cannot loop container. Exiting";exit; | |
else | |
echo "Loop device: $ld"; | |
fi; | |
#unlock loop device | |
echo "Unlocking container \"$ld\" as \"$mapper\""; | |
sudo cryptsetup luksOpen "$ld" "$mapper"; | |
#mount map to filesystem - filepath=$2 | |
echo "Mounting mapper in \"$mfilepath\""; | |
echo -n "$testpassword" | sudo -S mount "/dev/mapper/$mapper" "$mfilepath"; | |
#try to open mountpoint in file manager | |
if [ "$FILE_MANAGER" != "" ]; then $FILE_MANAGER "$2";fi; | |
} | |
#close container - needs container path | |
function cryptclose() { | |
#get filepath | |
filepath=`getabspath "$1"`; | |
#get mapper from filename | |
mapper=`getmapper $filepath`; | |
#check if valid mapper | |
if [ "`listmap | grep -w "$mapper"`" != "" ]; | |
then echo "Found mapper \"$mapper\"."; | |
else echo "Mapper $mapper not found!"; exit; | |
fi; | |
#if not root, given only root can umount stuff | |
if (( $EUID != 0 )); then echo "Please provide sudo password for umount.";fi; | |
#get sudo password for mount | |
read -p "enter [sudo] password:" -s -r testpassword; | |
echo; #newline | |
#locate mapper in mtab | |
mt=`cat /etc/mtab | grep "/dev/mapper/$mapper"`; | |
#if mapper mounted | |
if [ "$mt" != "" ]; | |
then #unmount mapper | |
echo "Unmounting: /dev/mapper/$mapper"; | |
echo -n "$testpassword" | sudo -S umount "/dev/mapper/$mapper"; | |
fi; | |
#lock container | |
echo "Removing and locking map \"$mapper\"..." | |
echo -n "$testpassword" | sudo -S cryptsetup luksClose "$mapper"; | |
#find loop device and detach | |
ld=`echo "$testpassword" | sudo -S losetup -j $filepath | grep -o "/dev/loop[0-9]*"`; | |
echo "Detaching device $ld"; | |
echo "$testpassword" | sudo -S losetup -d $ld; | |
echo "Done."; | |
} | |
#extend container - needs container path and size | |
function cryptextend() { | |
#get filepath | |
filepath=`getabspath $1`; | |
#get mapper from filename | |
mapper=`getmapper $filepath`; | |
#check if valid mapper, prompt unmount and exit if already mounted | |
if [ "`listmap | grep -w "$mapper"`" != "" ]; | |
then echo "Before resize, please close Mapper \"$mapper\"."; exit; | |
fi; | |
#get bs and count | |
examt="$2"; | |
#get block_size from size | |
exunit="`echo "$2" | grep -io '[KMGT]\?' | head -n 1`"; | |
#get count from size | |
excount="`echo "$2" | grep -o [0-9]*`"; | |
if [ $excount -lt 0 ] || [ $excount -eq 0 ]; then echo "Cannot use size \"$2\""; exit; fi; | |
#extend container size #>> do not overwrite | |
echo "Extending container with random data in $filepath with Block_size=1${exunit^^} and Count=$excount "; | |
dd if=/dev/urandom bs="1${exunit^^}" count="$excount" | cat - >> "$filepath"; | |
echo "Done."; | |
#check if root, given only root can mount stuff | |
if (( $EUID != 0 )); then echo "Please provide sudo password for mount.";fi; | |
#get sudo password for mount | |
read -p "enter [sudo] password:" -s -r testpassword; | |
echo; #newline | |
#mount container as loop device | |
echo "Mounting container as loop device..." | |
ld=`echo "$testpassword" | sudo -S losetup -f "$filepath" --show`; | |
echo "Loop device: $ld"; | |
#unlock loop device | |
mapper=`getmapper "$filepath"`; | |
echo "Unlocking container \"$ld\" as \"$mapper\""; | |
sudo cryptsetup luksOpen "$ld" "$mapper"; | |
#resize mapper to maximum size available -> size of container | |
echo "$testpassword" | sudo -S cryptsetup resize "$mapper"; | |
#check and resize filesystem | |
echo "$testpassword" | sudo -S e2fsck -f "/dev/mapper/$mapper" -y; | |
echo "$testpassword" | sudo -S resize2fs -p "/dev/mapper/$mapper"; | |
#lock container | |
echo "Removing and locking map \"$mapper\"..." | |
echo -n "$testpassword" | sudo -S cryptsetup luksClose "$mapper"; | |
#detach loop device before exit | |
echo "Detaching loop device $ld..."; | |
echo -n "$testpassword" | sudo -S losetup -d "$ld"; | |
echo "Finished resizing container $filepath"; | |
} | |
#cli - sanitize arguments before forwarding | |
function cli() { | |
case "$1" in | |
"create") #create container | |
shift; | |
#if not enough arguments | |
if [ ! "$1" ] || [ ! "$2" ]; | |
then | |
echo "Error: check arguments!"; | |
echo "Usage: create /path/to/container size[KMGT]"; | |
exit; | |
#elif invalid size | |
elif [ "`echo "$2" | grep -o [0-9]*`" == "" ] || [ "`echo "$2" | grep -io '[KMGT]'`" == "" ]; | |
then | |
echo "Invalid size \"$2\""; | |
#else run function create | |
else cryptcreate "$1" "$2"; | |
fi; | |
;; | |
"open") #open container | |
shift; | |
#if not enough arguments | |
if [ ! "$1" ] || [ ! "$2" ]; | |
then | |
echo "Error: check arguments!"; | |
echo "Usage: open /path/to/container /path/to/mountpoint"; | |
#elif invalid or size-zero container filepath | |
elif [ ! -f "$1" ] || [ ! -s "$1" ]; then echo "Container not found at \"$1\""; | |
#elif invalid mountpoint dir | |
elif [ ! -d "$2" ]; then echo "Mountpoint not found at \"$2\""; | |
#else run function open | |
else cryptopen "$1" "$2"; | |
fi; | |
;; | |
"close") #close container | |
shift; | |
#if not enough arguments or size-zero container filepath | |
if [ ! -f "$1" ] || [ ! -s "$1" ]; | |
then | |
echo "Error: check arguments!"; | |
echo "Usage: close /path/to/container"; | |
exit; | |
#else run function close | |
else cryptclose "$1"; | |
fi; | |
;; | |
"extend") #extend container | |
shift; | |
#if not enough arguments | |
if [ ! "$1" ] || [ ! "$2" ]; | |
then | |
echo "Error: check arguments!"; | |
echo "Usage: extend /path/to/container size[KMGT]"; | |
#elif invalid container path | |
elif [ ! -f "$1" ] || [ ! -s "$1" ]; then echo "Container not found at \"$1\""; | |
#elif invalid size | |
elif [ "`echo "$2" | grep -o [0-9]*`" == "" ] || [ "`echo "$2" | grep -io '[KMGT]'`" == "" ]; | |
then | |
echo "Invalid size \"$2\""; | |
echo "Usage: extend /path/to/container size[KMGT]"; | |
#else run function extend | |
else cryptextend "$1" "$2"; | |
fi; | |
;; | |
#extra functions (not to be used without knowing what they do, or don't do) | |
"unmount") #unmounts device if mounted | |
cryptumount "$1"; | |
;; | |
"listmap") #lists mapped devices | |
listmap; | |
;; | |
"listloop") #lists used loop devices | |
listloop; | |
;; | |
*) #echo usage | |
echo "Error: check arguments!"; | |
echo "Usage:"; | |
echo "sh ./$0 create /path/to/container size[KMGT]"; | |
echo "sh ./$0 open /path/to/container /path/to/mountpoint"; | |
echo "sh ./$0 close /path/to/container"; | |
echo "sh ./$0 extend /path/to/container size[KMGT]"; | |
;; | |
esac | |
} | |
#run cli | |
cli "$@"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment