Last active
December 25, 2019 04:51
-
-
Save astoeckel/623c589f2ffa0f48609aca7759867e94 to your computer and use it in GitHub Desktop.
Mounts a LUKS encrypted QCOW2 image
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 | |
QCOW2_ACTION="$1" | |
QCOW2_FILENAME="$2" | |
QCOW2_MOUNTPOINT="$3" | |
if test -z "$QCOW2_ACTION" || test -z "$QCOW2_FILENAME" || test -z "$QCOW2_MOUNTPOINT"; then | |
echo "Usage: mount.qcow2 <mount|unmount> <FILENAME> <MOUNTPOINT>"; | |
exit 1 | |
fi | |
# Load the nbd device driver | |
modprobe nbd max_part=63 || exit 1 | |
# Find the name of the nbdev associated with the QCOW2 image | |
QEMU_NBD_PIDS=$( pgrep qemu-nbd ) | |
if test -n "$QEMU_NBD_PIDS"; then | |
NBD_DEV=$( \ | |
ps --no-headers -o args -p $QEMU_NBD_PIDS | \ | |
grep "$QCOW2_FILENAME" | tail -n 1 | sed -e 's/.*\s\(.*\)$/\1/' ) | |
fi | |
# Find the name of the LUKS mapper associated with the NBD device | |
if test -n "$NBD_DEV"; then | |
for DEV in /dev/mapper/qcow2_*; do | |
DEV=$( basename "$DEV" ) | |
if cryptsetup status "$DEV" | grep device | grep "$NBD_DEV" > /dev/null; then | |
CRYPT_DEVNAME="$DEV" | |
break; | |
fi | |
done | |
fi | |
if [ "$QCOW2_ACTION" = "mount" ]; then | |
# Find the next free nbd device number | |
if test -z "$NBD_DEV"; then | |
NBD_DEV_NO=$( lsblk -l | grep nbd | sort | sed -e 's/^nbd\([0-9]\+\).*$/\1/' | tail -n 1 ) | |
if test -z "$NBD_DEV_NO"; then | |
NBD_DEV_NO=0 | |
else | |
NBD_DEV_NO=$( expr "$NBD_DEV_NO" + 1 ) | |
fi | |
NBD_DEV="/dev/nbd$NBD_DEV_NO" | |
# Export the device using qemu-nbd | |
qemu-nbd "$QCOW2_FILENAME" --cache=unsafe -c "$NBD_DEV" || exit 1 | |
echo "Exported image to $NBD_DEV" | |
else | |
echo "Image already exported to $NBD_DEV" | |
fi | |
if test -z "$CRYPT_DEVNAME"; then | |
# Generate a random name for the device | |
CRYPT_DEVNAME=qcow2_$( head /dev/urandom | tr -dc A-Za-z | head -c 10 ) | |
# Re-read the partition tables | |
partprobe | |
# Open the encrypted partition using LUKS | |
cat /etc/luks_passwd | cryptsetup open "${NBD_DEV}p1" "$CRYPT_DEVNAME" || exit 1 | |
echo "Opened LUKS device $CRYPT_DEVNAME" | |
else | |
echo "Image already opened as LUKS device $CRYPT_DEVNAME" | |
fi | |
# Mount the file system at the specified mountpoint | |
if mount | grep "$QCOW2_MOUNTPOINT" > /dev/null; then | |
if mount | grep "$QCOW2_MOUNTPOINT" | grep "$CRYPT_DEVNAME" > /dev/null; then | |
echo "\"/dev/mapper/$CRYPT_DEVNAME\" is already mounted on \"$QCOW2_MOUNTPOINT\"" | |
else | |
echo "Error: Mount point is already in use!" | |
fi | |
else | |
mount "/dev/mapper/$CRYPT_DEVNAME" "$QCOW2_MOUNTPOINT" || exit 1 | |
echo "Mounted \"/dev/mapper/$CRYPT_DEVNAME\" on \"$QCOW2_MOUNTPOINT\"" | |
fi | |
exit 0 | |
elif [ "$QCOW2_ACTION" = "unmount" ]; then | |
# Unmount the file system from the specified mountpoint | |
if mount | grep "$QCOW2_MOUNTPOINT" > /dev/null; then | |
echo "Unmounting $QCOW2_MOUNTPOINT" | |
umount "$QCOW2_MOUNTPOINT" || exit 1 | |
fi | |
# Close the LUKS device | |
if test -n "$CRYPT_DEVNAME"; then | |
echo "Closing LUKS device $CRYPT_DEVNAME" | |
cryptsetup close "$CRYPT_DEVNAME" || exit 1 | |
fi | |
# Disconnect the NBD dev for the image | |
if test -n "$NBD_DEV"; then | |
echo "Disconnecting image from $NBD_DEV" | |
qemu-nbd -d "$NBD_DEV" || exit 1 | |
fi | |
exit 0 | |
else | |
echo "Invalid action \"$QCOW2_ACTION\"; must be \"mount\" or \"unmount\"" | |
exit 1 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment