aboutsummaryrefslogtreecommitdiff
path: root/luksbackup.sh
diff options
context:
space:
mode:
Diffstat (limited to 'luksbackup.sh')
-rwxr-xr-xluksbackup.sh133
1 files changed, 133 insertions, 0 deletions
diff --git a/luksbackup.sh b/luksbackup.sh
new file mode 100755
index 0000000..74414cc
--- /dev/null
+++ b/luksbackup.sh
@@ -0,0 +1,133 @@
1#!/bin/bash
2
3# two operating modes
4MODE_KEY=1
5MODE_DIR=2
6
7# holds the current operating mode (see above)
8CURRENT_MODE=0
9
10# root path wherein device-specific mountpoints will be created
11MOUNTROOT=$HOME/luksbackup_$(date +%s)
12
13# source directory when operating in dir mode
14SOURCE_DIR=""
15
16print_usage() {
17 echo ""
18 echo "luksbackup: a tool for backing up GnuPG keys and entire directories to luks-encrypted devices"
19 echo ""
20 echo "* You will probably need to run this as root."
21 echo ""
22 echo "* Note that device names should not include the /dev/ prefix."
23 echo " They are assumed to only consist of the last part, i.e. 'sdb1'."
24 echo ""
25 echo "* Backing up private keys"
26 echo "** Use the -k flag to back up your private GnuPG keys to a 'gnupg' directory on the target devices"
27 echo " usage: ./luksbackup.sh -k device1 device2 ..."
28 echo ""
29 echo "* Backing up a directory"
30 echo "** Use the -d flag to back up a directory"
31 echo " usage: ./luksbackup.sh -d srcdir device1 device2 ..."
32 echo ""
33}
34
35set_key_mode() {
36 CURRENT_MODE=$MODE_KEY
37}
38
39set_dir_mode() {
40 CURRENT_MODE=$MODE_DIR
41 SOURCE_DIR=$1
42
43 # verify that source directory exists
44 if [ ! -d $SOURCE_DIR ];
45 then
46 echo "Directory $SOURCE_DIR doesn't exist! Exiting..." >&2
47 exit 1
48 fi
49}
50
51backup_dir() {
52 outfile=$1
53 echo "Archiving $SOURCE_DIR to $outfile"
54 tar -C $SOURCE_DIR -cf - . | xz -9e -T 0 -c - > $outfile
55}
56
57backup_keys() {
58 outfile=$1
59 tmpdir="/tmp/luksbackup_keys_$(date +%s)"
60
61 # create temporary output directory
62 mkdir -p $tmpdir
63
64 # export all the available secret keys
65 for key in $(gpg --list-secret-keys | grep -oE '[A-Z0-9]{40,}');
66 do
67 echo "Backing up key $key"
68 gpg -a -o $tmpdir/$key.asc --export-secret-key $key
69 done
70
71 tar -C $tmpdir -cf - . | xz -9e -T 0 -c - > $outfile
72
73 rm -rf $tmpdir
74}
75
76# parse command-line arguments
77while getopts ':d:hk' opt;
78do
79 case $opt in
80 (k) set_key_mode && shift 1 && break;;
81 (d) set_dir_mode $OPTARG && shift 2 && break;;
82 (*|h|help) print_usage && exit 0;;
83 esac
84done
85
86# verify that a valid operation mode was selected
87if [ $CURRENT_MODE -eq 0 ] || [ $CURRENT_MODE -gt 2 ];
88then
89 echo "Invalid argument(s). Exiting..." >&2
90 exit 1
91fi
92
93# iterate over the rest of the arguments, assumed to be device names
94for arg;
95do
96 device=$arg
97
98 cryptpart=cryptusb_$device
99 mountpoint=$MOUNTROOT/$device
100
101 # open the device
102 sudo cryptsetup open /dev/$device $cryptpart
103
104 if [ $? -ne 0 ];
105 then
106 echo "Could not open device $device. Skipping..."
107 continue;
108 fi
109
110 # mount the luks partition
111 mkdir -p $mountpoint
112 sudo mount /dev/mapper/$cryptpart $mountpoint
113
114 if [ $? -eq 0 ]; # only try creating backup if mounting succeeded
115 then
116 # print mountpoints
117 echo "Mounted /dev/$device ($cryptpart) -> $mountpoint"
118
119 # perform operation based on selected mode
120 case $CURRENT_MODE in
121 ($MODE_DIR) backup_dir "$mountpoint/backup_$(date +%s).tar.xz";;
122 ($MODE_KEY) backup_keys "$mountpoint/keys_$(date +%s).tar.xz";;
123 esac
124
125 # unmount the luks partition
126 sudo umount $mountpoint
127 fi
128
129 sudo cryptsetup close $cryptpart
130done
131
132# clean up root path where devices were mounted
133rm -rf $MOUNTROOT