Skip to content

Instantly share code, notes, and snippets.

@purpleidea
Created April 25, 2016 17:43
Show Gist options
  • Save purpleidea/7a145a4f58114efcc0d642fea3757e8a to your computer and use it in GitHub Desktop.
Save purpleidea/7a145a4f58114efcc0d642fea3757e8a to your computer and use it in GitHub Desktop.
Mount your encrypted LUKS drives by uuid over SSH
#!/bin/bash
# rluks.sh: Mount your encrypted LUKS drives by uuid over SSH
# Copyright (C) 2016+ James Shubin, AGPLv3+
# Written by James Shubin <james@shubin.ca>
# You probably want to modify the following globals to match your needs...
SERVER='server.example.com' # expected server for running script
HOSTNAME='myserver' # expected hostname for running locally
MEDIA='/media/' # mount/media directory, eg: /media/
declare -A MAP # create an associative array
MAP[music]='01234567-89ab-cdef-0123-456789abcdef'
MAP[files]='12345678-9abc-def0-1234-56789abcdef0'
MAP[movies]='23456789-abcd-ef01-2345-6789abcdef01'
if [ `hostname` != "$HOSTNAME" ]; then
#echo "connecting to: $SERVER via ssh"
ssh -t "$SERVER" "$(< $0)" # magic!
exit $?
fi
echo "Running on: `hostname`..."
sudo -v || exit 1 # warm sudo
read -t 42 -p "Mount/Unmount [m/u] ? " action
if [ "$action" != "m" ] && [ "$action" != "u" ]; then
echo 'Invalid action!'
exit 1
fi
if [ "$action" = "u" ]; then
echo "Unmounting..."
else
echo "Mounting..."
fi
for K in "${!MAP[@]}"; do
V=${MAP[$K]}
#echo $K --- $V
if [ "$action" = "u" ]; then # unmount
if findmnt --output 'SOURCE,TARGET' --target "${MEDIA}$K" &>/dev/null; then
sudo umount "${MEDIA}$K" || exit 1
echo "$K: umount ✓"
fi
if [ -L "/dev/mapper/$K" ]; then
sudo cryptsetup luksClose "$K" || exit 1
echo "$K: luksClose ✓"
fi
if [ -d "${MEDIA}$K" ]; then
sudo rmdir "${MEDIA}$K" || exit 1
echo "$K: rmdir ✓"
fi
else # mount
# is dir missing
if [ ! -d "${MEDIA}$K" ]; then
sudo mkdir "${MEDIA}$K" || exit 1
echo "$K: mkdir ✓"
fi
# is luks already open?
if [ ! -L "/dev/mapper/$K" ]; then
fail=0
# get password
if [ -z "$lukspassword" ]; then
read -s -p "LUKS Password: " lukspassword
echo
fi
# open luks
(echo "$lukspassword" | sudo cryptsetup luksOpen "/dev/disk/by-uuid/$V" "$K") || fail=1
if [ "$fail" = "1" ]; then
read -s -p "LUKS Password: " lukspassword
echo
(echo "$lukspassword" | sudo cryptsetup luksOpen "/dev/disk/by-uuid/$V" "$K") || exit 1
fi
fail=0
echo "$K: luksOpen ✓"
fi
# are we already mounted ?
if ( ! findmnt --output 'SOURCE,TARGET' --source "/dev/mapper/$K" &>/dev/null ) && ( ! findmnt --output 'SOURCE,TARGET' --target "${MEDIA}$K" &>/dev/null ); then
# mount
sudo mount "/dev/mapper/$K" "${MEDIA}$K" || exit 1
echo "$K: mount ✓"
fi
fi
done
echo 'Done!'
@flavio-fernandes
Copy link

Hey Purple!

Nice script!
Below are some minor tweaks to provide better feedback should things not work as expected.

Best,

-- flaviof

--- rluks.sh.orig   2016-05-03 17:08:56.593558012 -0400
+++ rluks.sh    2016-05-03 17:14:16.423143961 -0400
@@ -19,7 +19,7 @@
 fi
 
 echo "Running on: `hostname`..."
-sudo -v    || exit 1   # warm sudo
+sudo -v    || { echo "cannot sudo"; exit 1; }  # warm sudo
 
 read -t 42 -p "Mount/Unmount [m/u] ? " action
 if [ "$action" != "m" ] && [ "$action" != "u" ]; then
@@ -39,17 +39,17 @@
    if [ "$action" = "u" ]; then    # unmount
 
        if findmnt --output 'SOURCE,TARGET' --target "${MEDIA}$K" &>/dev/null; then
-           sudo umount "${MEDIA}$K" || exit 1
+           sudo umount "${MEDIA}$K" || { echo "umount failed: $?"; exit 1; }
            echo "$K: umount ✓"
        fi
 
        if [ -L "/dev/mapper/$K" ]; then
-           sudo cryptsetup luksClose "$K" || exit 1
+           sudo cryptsetup luksClose "$K" || { echo "cryptsetup failed: $?"; exit 1; }
            echo "$K: luksClose ✓"
        fi
 
        if [ -d "${MEDIA}$K" ]; then
-           sudo rmdir "${MEDIA}$K" || exit 1
+           sudo rmdir "${MEDIA}$K" || { echo "rmdir failed: $?"; exit 1; }
            echo "$K: rmdir ✓"
        fi
 
@@ -57,7 +57,7 @@
 
        # is dir missing
        if [ ! -d "${MEDIA}$K" ]; then
-           sudo mkdir "${MEDIA}$K" || exit 1
+           sudo mkdir "${MEDIA}$K" || { echo "mkdir failed: $?"; exit 1; }
            echo "$K: mkdir ✓"
        fi
 
@@ -74,7 +74,7 @@
            if [ "$fail" = "1" ]; then
                read -s -p "LUKS Password: " lukspassword
                echo
-               (echo "$lukspassword" | sudo cryptsetup luksOpen "/dev/disk/by-uuid/$V" "$K") || exit 1
+               (echo "$lukspassword" | sudo cryptsetup luksOpen "/dev/disk/by-uuid/$V" "$K") || { echo "cryptsetup failed: $?"; exit 1; }
            fi
            fail=0
            echo "$K: luksOpen ✓"
@@ -83,7 +83,7 @@
        # are we already mounted ?
        if ( ! findmnt --output 'SOURCE,TARGET' --source "/dev/mapper/$K" &>/dev/null ) && ( ! findmnt --output 'SOURCE,TARGET' --target "${MEDIA}$K" &>/dev/null ); then
            # mount
-           sudo mount "/dev/mapper/$K" "${MEDIA}$K" || exit 1
+           sudo mount "/dev/mapper/$K" "${MEDIA}$K" || { echo "mount failed: $?"; exit 1; }
            echo "$K: mount ✓"
        fi
    fi

@malteneuss
Copy link

Could you please explain what happens on these lines?
ssh -t "$SERVER" "$(< $0)" # magic!
exit $?

When i use them in my own script i am asked for my password, although i use rsa keys, and after typing it in i am stuck at the terminal prompt
user@host:~/
but the rest of my script isn't executed.

Best regards,
Malte

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment