Skip to content

Instantly share code, notes, and snippets.

@josefandersson
Last active June 7, 2022 19:12
Show Gist options
  • Save josefandersson/a988ef51fcb0fc2ec93a82033fabf1d9 to your computer and use it in GitHub Desktop.
Save josefandersson/a988ef51fcb0fc2ec93a82033fabf1d9 to your computer and use it in GitHub Desktop.
Script to backup (compress and pgp encrypt) a file or directory and send it anywhere via ssh.
#!/bin/bash
# Usage: script <source file/directory> <gpg recipient> <ssh login@server>:<target directory> [chmod]
# Example: /usr/local/bin/backup-tool.sh /home/alice/bwdata [email protected] [email protected]:backups/ 0600
# Example crontab: 0 5 * * * <see example above>
# Notes: Remember that elevated permissions is required to read some dirs/files
# Remember to add and trust the GPG recipient, otherwise the encryption will fail
[ -z "$1" ] && echo "No source file/directory" && exit 1
[ -z "$2" ] && echo "No recipient" && exit 1
[ -z "$3" ] && echo "No backup server" && exit 1
gpg --list-keys "$2" || (echo "Recipient not in keyring" && exit 1)
root="/tmp"
mkdir -p "$root"
fn="$root/$(basename "$1")-$(date +"%Y%m%d-%H%M%S").tar.zip"
echo "Creating tarball"
cd "$(dirname "$1")" && tar czfP "$fn" "$(basename "$1")"
echo "Encrypting tarball to recipient $2"
gpg --encrypt --recipient "$2" --trust-model always --output "$fn.pgp" "$fn"
echo "Deleting tarball"
rm -f "$fn"
if [ -n "$4" ]; then
echo "Updating encrypted backup permissions"
chmod "$4" "$fn.pgp"
fi
echo "Sending encrypted backup to $3"
scp "$fn.pgp" "$3"
echo "Cleanup"
rm -f "$fn.pgp"
echo "Done"
#!/bin/bash
# Outputs or writes to file a JSON snippet of the last time files were backed
# up (created by backup-tool.sh; .pgp) in the specified users' home directories.
# Usage: last-backups [output file]
USERS=(backups-vaultwarden backups-gitea backups-mystats backups-media)
lastForDir() {
# Alternative datetime format: '%TY-%Tm-%Td %TT', tho sort has to be used differently in that case
datetime="$(find "/home/$1" -name '*.pgp' -type f -printf '%T@\n' | sort -nr | grep -m 1 '')"
echo $'\t'"\"$1\": $datetime,"
}
for user in ${USERS[@]}; do
output+="$(lastForDir $user)\n"
done
# Remove last comma
output="${output::-3}\n"
# Print to stdout if no output file was provided
if [ -z "$1" ]; then
echo -e "{\n$output}"
exit 0
fi
# Write to file if not exists
if [ ! -f "$1" ]; then
echo -e "{\n$output}" > "$1"
exit 0
fi
# Calc md5 for old file and new output
old=$(md5sum "$1" | cut -d' ' -f1)
new=$(echo -e "{\n$output}" | md5sum | cut -d' ' -f1)
# Compare md5 to only write to output if updated
if [[ "$old" != "$new" ]]; then
echo -e "{\n$output}" > "$1"
fi
@josefandersson
Copy link
Author

Added last-backups.sh—a script to help verifying that backups works as intended. I use it to keep a .json file in my home dir on my backup server with the last update times and poll that file on my main computer system start/daily (ssh <server> "cat last-backups.json") to alert me if backups have not been made on time.

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