forked from pigmonkey/cryptshot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cryptshot.sh
executable file
·178 lines (157 loc) · 4.93 KB
/
cryptshot.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/bin/bash
#
# Open and mount a LUKS volume before performing a backup.
#
# This script first checks to see if a volume with the given UUID exists. If
# the volume is found, it is treated as a LUKS volume and decrypted with the
# given key file, after which it is mounted. The script then runs the specified
# backup program. After the backup is complete, the volume is unmounted and the
# LUKS mapping is removed. Optionally, the mount point can be deleted to
# complete the clean-up.
#
# Since the first step taken is to check if the given volume exists, it is
# appropriate for situations where the external backup volume is not always
# available to the machine (such as a USB backup drive and a laptop).
#
# If using rsnapshot, the interval should be passed with the -i argument.
#
# Author: Pig Monkey ([email protected])
# Website: https://github.com/pigmonkey/backups
#
###############################################################################
# Define the UUID of the backup volume.
UUID=""
# Define the location of the LUKS key file.
KEYFILE=""
# Define the root of the mount point for the backup volume.
# This will be created if it does not already exist.
MOUNTROOT="/mnt/"
# Any non-zero value here will caused the mount point to be deleted after the
# volume is unmounted.
REMOVEMOUNT=1
# Define the location of the backup program.
BACKUP="/usr/bin/rsnapshot"
# End configuration here.
###############################################################################
# define exit codes (from /usr/include/sysexits.h) for code legibility
# see also: http://tldp.org/LDP/abs/html/exitcodes.html
EX_OK=0
EX_NOINPUT=66
EX_CANTCREAT=73
EX_NOPERM=77
EX_CONFIG=78
# Check for config file at standard locations (XDG first)
config=""
if [ "$XDG_CONFIG_HOME" != "" ] && [ -f "$XDG_CONFIG_HOME/cryptshot.conf" ]; then
config="$XDG_CONFIG_HOME/cryptshot.conf"
elif [ -f "$HOME/.cryptshot.conf" ]; then
config="$HOME/.cryptshot.conf"
fi
# Get any arguments.
while getopts "c:i:h" opt; do
case $opt in
c)
config="$OPTARG"
;;
i)
BACKUP_ARGS=$OPTARG
;;
h)
echo "Usage: $0 [ -i BACKUP_ARGS ] [ -c CONFIG ]"
exit $EX_OK
;;
esac
done
# Exit if not root
if [ x"$(whoami)" != x"root" ]; then
echo 'Not super-user.'
exit $EX_NOPERM
fi
# If a config file is given, use that file
if [ "$config" != "" ]; then
source "$config"
exitcode=$?
if [ $exitcode -ne 0 ]; then
echo 'Failed to source configuration file.'
exit $exitcode
fi
fi
# Exit if no volume is specified.
if [ "$UUID" = "" ]; then
echo 'No volume specified.'
exit $EX_CONFIG
fi
# Exit if no key file is specified.
FD_STDIN=1
if [ "$KEYFILE" = "" ] && [ ! -t $FD_STDIN ]; then
echo 'No key file specified and not on terminal for password input.'
exit $EX_CONFIG
fi
# Exit if no mount root is specified.
if [ "$MOUNTROOT" = "" ]; then
echo 'No mount root specified.'
exit $EX_CONFIG
fi
# Create the mount point from the mount root and UUID.
MOUNTPOINT="$MOUNTROOT$UUID"
# If the mount point does not exist, create it.
if [ ! -d "$MOUNTPOINT" ]; then
mkdir $MOUNTPOINT
# Exit if the mount point was not created.
if [ $? -ne 0 ]; then
echo "Failed to create mount point."
exit $EX_CANTCREAT
fi
fi
# Exit if backup program is not executable. Assume the executable is everything
# up to the first space.
BACKUP_EX=${BACKUP%%[[:space:]]*}
if [ ! -x "$BACKUP_EX" ]; then
echo "Backup program does not exist or is not executable: $BACKUP_EX"
exit $EX_CONFIG
fi
# Build the reference to the volume.
volume="/dev/disk/by-uuid/$UUID"
# Create a unique name for the LUKS mapping.
name="crypt-$UUID"
# Set the default exit code.
exitcode=$EX_OK
# Continue if the volume exists.
if [ -e $volume ];
then
# Attempt to open the LUKS volume, using keyfile if given.
if [ "$KEYFILE" = "" ]; then
cryptsetup luksOpen $volume $name
else
cryptsetup luksOpen --key-file $KEYFILE $volume $name
fi
# If the volume was decrypted, mount it.
if [ $? -eq 0 ];
then
mount --options noatime /dev/mapper/$name $MOUNTPOINT
# If the volume was mounted, run the backup.
if [ $? -eq 0 ];
then
$BACKUP $BACKUP_ARGS
# Unmount the volume
umount $MOUNTPOINT
# If the volume was unmounted and the user has requested that the
# mount point be removed, remove it.
if [ $? -eq 0 ] && [ $REMOVEMOUNT -ne 0 ] && [ -d $MOUNTPOINT ]; then
rmdir $MOUNTPOINT
fi
else
exitcode=$?
echo "Failed to mount $volume at $MOUNTPOINT."
fi
# Close the LUKS volume.
cryptsetup luksClose $name
else
exitcode=$?
echo "Failed to open $volume with key $KEYFILE."
fi
else
exitcode=$EX_NOINPUT
echo "Volume $UUID not found."
fi
exit $exitcode