From 08e790a13b1e7acecb83e1a60ac43e31a051402e Mon Sep 17 00:00:00 2001 From: Marco Cetica Date: Thu, 4 Apr 2024 11:55:56 +0200 Subject: [PATCH] Fixed various bugs --- README.md | 15 +++++++-------- backup.sh | 56 ++++++++++++++++++++++++++++++++++++++----------------- man.md | 15 +++++++-------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b8a6112..c8cca39 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This will copy `backup.sh` into `/usr/local/bin/backup.sh`, `sources.bk` into `/ you can issue `sudo make uninstall`. At this point you still need to install the following dependencies: +- `Bash` - `rsync` - `tar` - `gpg` @@ -112,7 +113,7 @@ After that, you will find the backup archive and the checksum file in You can also use `backup.sh` from a crontab rule: ```sh $> sudo crontab -e -30 03 * * 6 EKEY=$(cat /home/john/.ekey) sh -c '/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY' > /dev/null 2>&1 +30 03 * * 6 EKEY=$(cat /home/john/.ekey) bash -c '/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY' > /dev/null 2>&1 ``` @@ -121,8 +122,8 @@ key is stored in a local file(with fixed permissions) to avoid password leaking adopt this practice while using the `--extract` option to avoid password leaking in shell history. ### Backup extraction -`backup.sh` can also be used to extract the encrypted backup as well to verify the integrity -of the backup data. To do so, use the following commands: +`backup.sh` can also be used to extract and to verify the encrypted backup. +To do so, use the following commands: ```sh $> ./backup.sh --extract @@ -142,10 +143,10 @@ backup-nginx- backup-ssh- ``` -**note:**: be sure to rename any directory with that name to avoid collisions. +**note**: be sure to rename any directory with that name to avoid collisions. -Instead, if you also want to verify the integrity of the backup data, use the following commands: +If you also want to verify the integrity of the backup data, use the following commands: ```sh $> ./backup.sh --checksum --extract ``` @@ -153,11 +154,9 @@ $> ./backup.sh --checksum --extract ./backup.sh --checksum --extract backup--.tar.gz.enc badpw1234 $PWD/backup--.sha256 +$> ./backup.sh --checksum --extract backup--.tar.gz.enc badpw1234 backup--.sha256 ``` -**note:** be sure to provide the ABSOLUTE PATH of the checksum file. - ## How does backup.sh work? **backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup, _gpg_ to encrypt it and _sha256sum_ to verify it. diff --git a/backup.sh b/backup.sh index ddd8137..1a021ea 100755 --- a/backup.sh +++ b/backup.sh @@ -1,4 +1,4 @@ -#!/bin/sh -e +#!/usr/bin/env bash # backup.sh is a POSIX compliant, modular and lightweight # backup utility to save and encrypt your files. # @@ -34,6 +34,8 @@ # Copyright (c) 2018,2023,2024 Marco Cetica # +set -e + checkdeps() { # Check if dependencies are installed missing_dep=0 @@ -51,6 +53,20 @@ checkdeps() { fi } +# $1: filename +gethash() { + FILE_NAME="$1" + OS="$(uname)" + + if [ "$OS" = "Linux" ]; then + HASH="$(sha256sum "$FILE_NAME" | awk '{print $1}')" + else + HASH="$(sha256 -q "$FILE_NAME")" + fi + + echo "$HASH" +} + # $1: sources.bk file # $2: output path # $3: password @@ -75,12 +91,6 @@ make_backup() { exit 1 fi - # Check whether the sources file exists or not - if [ ! -f "$BACKUP_SH_SOURCES_PATH" ]; then - echo "$BACKUP_SH_SOURCES_PATH does not exist." - exit 1 - fi - # Create temporary directory mkdir -p "$BACKUP_SH_OUTPUT" @@ -97,7 +107,13 @@ make_backup() { # Compute SHA256 of all files of the current directory if [ "$BACKUP_SH_SHA256" -eq 1 ]; then - find "$path" -type f -exec sha256sum {} + | sort -k 2 | awk '{print $1}' >> "$BACKUP_SH_CHECKSUM_FILE" + shopt -s globstar dotglob + for file in "$path"/**/*; do + # Skip directories + [ -d "$file" ] && continue + gethash "$file" >> "$BACKUP_SH_CHECKSUM_FILE" + done + shopt -u globstar dotglob fi # Copy files @@ -150,7 +166,7 @@ extract_backup() { --decrypt \ --no-symkey-cache \ --pinentry-mode=loopback \ - --batch --passphrase "$BACKUP_SH_ARCHIVE_PW" \ + --batch --passphrase-fd 3 3<<< "$BACKUP_SH_ARCHIVE_PW" \ --output backup.sh.tar.gz \ "$BACKUP_SH_ARCHIVE_PATH" @@ -159,16 +175,20 @@ extract_backup() { # If specified, use SHA256 file to compute checksum of files if [ -n "$BACKUP_SH_SHA256_FILE" ]; then - for file in $(find "backup.sh.tmp" -type f | sort -k 2); do + shopt -s globstar dotglob + for file in "backup.sh.tmp"/**/*; do + # Skip directories + [ -d "$file" ] && continue; # Compute sha256 for current file - sha256="$(sha256sum "$file" | awk '{print $1}')" + SHA256="$(gethash "$file")" # Check if checksum file contains hash - if ! grep -wq "$sha256" "$BACKUP_SH_SHA256_FILE"; then + if ! grep -wq "$SHA256" "$BACKUP_SH_SHA256_FILE"; then printf "[FATAL] - integrity error for '%s'.\n" "$file" rm -rf backup.sh.tar.gz backup.sh.tmp exit 1 fi done + shopt -u globstar dotglob fi rm -rf backup.sh.tar.gz @@ -218,6 +238,7 @@ main() { fi if [ "$CHECKSUM_FLAG" -eq 1 ]; then + [ -e "$BACKUP_SH_SOURCES_PATH" ] || { echo "Sources file does not exist"; exit 1; } make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD" 1 else make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD" 0 @@ -231,18 +252,18 @@ main() { shift 1 ;; -e|--extract) - BACKUP_SH_ARCHIVE_PATH="$2" + BACKUP_SH_ARCHIVE_FILE="$2" BACKUP_SH_ARCHIVE_PW="$3" BACKUP_SH_SHA256_FILE="$4" if [ "$CHECKSUM_FLAG" -eq 1 ]; then - if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ] || [ -z "$BACKUP_SH_SHA256_FILE" ]; then + if [ -z "$BACKUP_SH_ARCHIVE_FILE" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ] || [ -z "$BACKUP_SH_SHA256_FILE" ]; then echo "Please, specify an encrypted archive, a password and a SHA256 file." echo "For more informatio, try --help" exit 1 fi else - if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ]; then + if [ -z "$BACKUP_SH_ARCHIVE_FILE" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ]; then echo "Please, specify an encrypted archive and a password." echo "For more informatio, try --help" exit 1 @@ -251,9 +272,10 @@ main() { if [ "$CHECKSUM_FLAG" -eq 1 ]; then [ -e "$BACKUP_SH_SHA256_FILE" ] || { echo "Checksum file does not exist"; exit 1; } - extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW" "$BACKUP_SH_SHA256_FILE" + [ -e "$BACKUP_SH_ARCHIVE_FILE" ] || { echo "Backup file does not exist"; exit 1; } + extract_backup "$BACKUP_SH_ARCHIVE_FILE" "$BACKUP_SH_ARCHIVE_PW" "$BACKUP_SH_SHA256_FILE" else - extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW" + extract_backup "$BACKUP_SH_ARCHIVE_FILE" "$BACKUP_SH_ARCHIVE_PW" fi exit 0 diff --git a/man.md b/man.md index 00acde9..f4e5cf9 100644 --- a/man.md +++ b/man.md @@ -3,7 +3,7 @@ title: backup.sh section: 1 header: General Commands Manual footer: Marco Cetica -date: April 3, 2024 +date: April 4, 2024 --- # NAME @@ -101,7 +101,7 @@ After that, you will find the backup archive and the checksum file in You can also use `backup.sh` from a crontab rule: ``` $> sudo crontab -e -30 03 * * 6 EKEY=$(cat /home/john/.ekey) sh -c '/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY' > /dev/null 2>&1 +30 03 * * 6 EKEY=$(cat /home/john/.ekey) bash -c '/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY' > /dev/null 2>&1 ``` @@ -110,8 +110,8 @@ key is stored in a local file(with fixed permissions) to avoid password leaking adopt this practice while using the `--extract` option to avoid password leaking in shell history. ## Backup extraction -**backup.sh** can also be used to extract the encrypted backup as well to verify the integrity -of the backup data. To do so, use the following commands: +**backup.sh** can also be used to extract and to verify the encrypted backup. +To do so, use the following commands: ``` $> ./backup.sh --extract @@ -131,10 +131,10 @@ backup-nginx- backup-ssh- ``` -**note:**: be sure to rename any directory with that name to avoid collisions. +**note**: be sure to rename any directory with that name to avoid collisions. -Instead, if you also want to verify the integrity of the backup data, use the following commands: +If you also want to verify the integrity of the backup data, use the following commands: ``` $> ./backup.sh --checksum --extract ``` @@ -142,10 +142,9 @@ $> ./backup.sh --checksum --extract ./backup.sh --checksum --extract backup--.tar.gz.enc badpw1234 $PWD/backup--.sha256 +$> ./backup.sh --checksum --extract backup--.tar.gz.enc badpw1234 backup--.sha256 ``` -**note:** be sure to provide the ABSOLUTE PATH of the checksum file. ## How does backup.sh work? **backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup, _gpg_ to encrypt it and