Skip to content

Instantly share code, notes, and snippets.

@coffebar
Last active February 12, 2020 17:20
Show Gist options
  • Save coffebar/fa06473548fdf3f88a05eee9caba4630 to your computer and use it in GitHub Desktop.
Save coffebar/fa06473548fdf3f88a05eee9caba4630 to your computer and use it in GitHub Desktop.
#!/usr/bin/env zsh
# Script to create backups from ssh server
# to LUKS encrypted disk on Linux
# Preparation:
# 1. Intsall "cryptsetup" and create LUKS encrypted partition
# save your passphrase into securely stored file - personal usb stick
# or other encrypted partition/folder
# Unmount your partition
#
# 2. Device mapper
# create file /etc/crypttab with contents or add if exists:
#
# bk2 UUID=xxxxxxx-yyyy-aaaaa-bbbbb-zzzzzz /PATH/YOUR.key luks,noauto
#
# where
# bk2 - custom label to create device "/dev/mapper/bk2"
# xxxxxxx-yyyy-aaaaa-bbbbb-zzzzzz - UUID of your LUKS partition
# /PATH/YOUR.key - path to file where securely stored your LUKS pass
# NOTE: you can start this mapping without reboot with next command:
# sudo cryptdisks_start bk2
#
# 3. Allow user to mount device without sudo
#
# Create mount point and set permissions:
# sudo mkdir /mnt/luks-blue/
#
# Add next line to /etc/fstab
#
# /dev/mapper/bk2 /mnt/luks-blue ext4 noauto,nodev,nofail,nosuid,noexec,user 0 0
#
# now you can mount drive with next command:
# mount /dev/mapper/bk2
#
# validate that partition is mounted, then change permissions
# sudo chown $USER:$USER /mnt/luks-blue
# sudo chmod 750 /mnt/luks-blue
#
# and unmount it:
# umount /dev/mapper/bk2
#
# Create file /etc/sudoers.d/cryptdisks with next 2 lines:
# YourUsername ALL=(root) NOPASSWD:/usr/sbin/cryptdisks_start bk2
# YourUsername ALL=(root) NOPASSWD:/usr/sbin/cryptdisks_stop bk2
#
# where you need to change "YourUsername" to your real username
# Also set permissions on that file:
# sudo chmod 0400 /etc/sudoers.d/cryptdisks
#######
TARGET_NAME="bk2"
TARGET_DEVICE="/dev/mapper/$TARGET_NAME"
MOUNT_POINT="" # auto
# starting mapper
sudo /usr/sbin/cryptdisks_start $TARGET_NAME
# getting target directory from mapped device name
# mount it if not mounted
grep_for_mount=$(grep "^$TARGET_DEVICE " /proc/mounts)
if [[ $grep_for_mount ]]; then
echo "Found mounted:"
echo $grep_for_mount
else
echo "Mounting $TARGET_DEVICE"
mount "$TARGET_DEVICE" && grep_for_mount=`grep "^$TARGET_DEVICE " /proc/mounts`
if [[ ! $grep_for_mount ]]; then
echo "Error: Failed to mount $TARGET_DEVICE"
exit -1
fi
fi
MOUNT_POINT=`echo "$grep_for_mount" | cut -d ' ' -f 2`
echo
echo "Target: $MOUNT_POINT"
echo
# not allow to start if already running
PID_FILE="$MOUNT_POINT/backup.pid"
if [ -e $PID_FILE ]; then
echo "Error: Backup is already running!"
exit -2
fi
touch $PID_FILE
# Upon exit, remove lockfile and encrypt disk
function before_exit() {
echo "** EXIT"
rm -f "$PID_FILE"
# unmount encrypted disk
umount "$TARGET_DEVICE"
sudo /usr/sbin/cryptdisks_stop $TARGET_NAME
}
trap before_exit EXIT
##########################################
## Replace all the code below with yours.
## This is an example only.
##########################################
#
# backup start
#
notify-send "$0" "Backup started" --expire-time=6000
# Creating directory 'site' if not exists
TARGET_DIR="$MOUNT_POINT/site"
if [ ! -d $TARGET_DIR ]; then
mkdir $TARGET_DIR
if [ ! -d $TARGET_DIR ]; then
echo "Error: Can't create directory '$TARGET_DIR'"
exit -1
fi
fi
# remove log files before start
LOG_FILE_DB="$HOME/Downloads/rsync.elastic.log"
rm -f "$LOG_FILE_DB"
# copy db dump
rsync -e "ssh -i $HOME/.ssh/projectkey -o Compression=no -T" -ah --delete \
--stats --log-file="$LOG_FILE_DB" \
--partial --min-size=50G --compress-level=1 \
'[email protected]:/backup/db' "$TARGET_DIR/"
test $? -eq 0 || notify-send "$0" "Rsync failed to handle DB" --expire-time=0
notify-send "$0" "Backup process is finished! Check logs in '$HOME/Downloads'" --expire-time=10000
#
# backup end
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment