Migrated to '/bin/sh'
All checks were successful
backup.sh / bash (push) Successful in 12s

This commit is contained in:
Marco Cetica 2024-02-27 10:03:12 +01:00
parent 0918139225
commit 39a15d2f2a
Signed by: marco
GPG Key ID: 45060A949E90D0FD
5 changed files with 150 additions and 220 deletions

View File

@ -105,7 +105,7 @@ After that, you will find the final backup archive in `/home/john/backup-<HOSTNA
You can also use `backup.sh` from a crontab rule: You can also use `backup.sh` from a crontab rule:
```sh ```sh
$> sudo crontab -e $> sudo crontab -e
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 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
``` ```
@ -163,7 +163,7 @@ $> gpg -a \
--cipher-algo=AES256 \ --cipher-algo=AES256 \
--no-symkey-cache \ --no-symkey-cache \
--pinentry-mode=loopback \ --pinentry-mode=loopback \
--batch --passphrase-fd 3 3<<< "$PASSWORD" \ --batch --passphrase "$PASSWORD" \
--output "$OUTPUT" \ --output "$OUTPUT" \
"$INPUT" "$INPUT"
``` ```

152
backup.sh
View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash #!/bin/sh -e
# backup.sh is a POSIX compliant, modular and lightweight # backup.sh is a POSIX compliant, modular and lightweight
# backup utility to save and encrypt your files. # backup utility to save and encrypt your files.
# #
@ -27,32 +27,31 @@
# #
# You can read the full guide on https://github.com/ice-bit/backup.sh # You can read the full guide on https://github.com/ice-bit/backup.sh
# or on the manual page. # or on the manual page.
# Copyright (c) 2018,2023 Marco Cetica <email@marcocetica.com> # Copyright (c) 2018,2023,2024 Marco Cetica <email@marcocetica.com>
# #
set -e checkdeps() {
# Check if dependencies are installed
missing_dep=0
deps="rsync tar gpg"
# Check if dependencies are installed for dep in $deps; do
missing_dep=0 if ! command -v "$dep" > /dev/null 2>&1; then
deps=("rsync" "tar" "gpg") printf "Cannot find '%s', please install it.\n" "$dep"
missing_dep=1
fi
done
for dep in "${deps[@]}"; do if [ $missing_dep -ne 0 ]; then
if ! command -v "$dep" > /dev/null 2>&1; then exit 1
echo "Cannot find '$dep', please install it."
missing_dep=1
fi fi
done }
if [ $missing_dep -ne 0 ]; then
exit 1
fi
checksum() { checksum() {
BACKUP_SH_FILENAME="$1" BACKUP_SH_FILENAME="$1"
BACKUP_SH_OS="$(uname)" BACKUP_SH_OS="$(uname | tr '[:lower:]' '[:upper:]')"
BACKUP_SH_OS="${BACKUP_SH_OS^^}"
if [[ $BACKUP_SH_OS == "LINUX" ]]; then if [ "$BACKUP_SH_OS" = "LINUX" ]; then
RES="$(md5sum "$BACKUP_SH_FILENAME" | awk '{print $1}')" RES="$(md5sum "$BACKUP_SH_FILENAME" | awk '{print $1}')"
else else
RES="$(md5 -q "$BACKUP_SH_FILENAME")" RES="$(md5 -q "$BACKUP_SH_FILENAME")"
@ -72,8 +71,6 @@ make_backup() {
BACKUP_SH_START_TIME="$(date +%s)" BACKUP_SH_START_TIME="$(date +%s)"
BACKUP_SH_FILENAME="$BACKUP_SH_OUTPATH/backup-$(uname -n)-$BACKUP_SH_DATE.tar.gz.enc" BACKUP_SH_FILENAME="$BACKUP_SH_OUTPATH/backup-$(uname -n)-$BACKUP_SH_DATE.tar.gz.enc"
declare -A BACKUP_SH_SOURCES
# Check for root permissions # Check for root permissions
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then
echo "Run this tool as root!" echo "Run this tool as root!"
@ -86,28 +83,22 @@ make_backup() {
exit 1 exit 1
fi fi
# Read associative array from file
readarray -t lines < "$BACKUP_SH_SOURCES_PATH"
for line in "${lines[@]}"; do
label=${line%%=*}
path=${line#*=}
BACKUP_SH_SOURCES[$label]=$path
done
# Create temporary directory # Create temporary directory
mkdir -p "$BACKUP_SH_OUTPUT" mkdir -p "$BACKUP_SH_OUTPUT"
# For each item in the array, make a backup # For each item in the array, make a backup
BACKUP_SH_TOTAL=$(wc -l < "$BACKUP_SH_SOURCES_PATH")
BACKUP_SH_PROGRESS=1 BACKUP_SH_PROGRESS=1
for item in "${!BACKUP_SH_SOURCES[@]}"; do
while IFS='=' read -r label path; do
# Define a subdir for each backup entry # Define a subdir for each backup entry
BACKUP_SH_SUBDIR="$BACKUP_SH_OUTPUT/backup-$item-$BACKUP_SH_DATE" BACKUP_SH_SUBDIR="$BACKUP_SH_OUTPUT/backup-$label-$BACKUP_SH_DATE"
mkdir -p "$BACKUP_SH_SUBDIR" mkdir -p "$BACKUP_SH_SUBDIR"
echo "Copying $item($BACKUP_SH_PROGRESS/${#BACKUP_SH_SOURCES[*]})" printf "Copying %s(%s/%s)\n" "$label" "$BACKUP_SH_PROGRESS" "$BACKUP_SH_TOTAL"
$BACKUP_SH_COMMAND "${BACKUP_SH_SOURCES[$item]}" "$BACKUP_SH_SUBDIR" $BACKUP_SH_COMMAND "$path" "$BACKUP_SH_SUBDIR"
BACKUP_SH_PROGRESS=$((BACKUP_SH_PROGRESS+1)) BACKUP_SH_PROGRESS=$((BACKUP_SH_PROGRESS+1))
done done < "$BACKUP_SH_SOURCES_PATH"
# Compress backup directory # Compress backup directory
echo "Compressing backup..." echo "Compressing backup..."
@ -121,7 +112,7 @@ make_backup() {
--cipher-algo=AES256 \ --cipher-algo=AES256 \
--no-symkey-cache \ --no-symkey-cache \
--pinentry-mode=loopback \ --pinentry-mode=loopback \
--batch --passphrase-fd 3 3<<< "$BACKUP_SH_PASS" \ --batch --passphrase "$BACKUP_SH_PASS" \
--output "$BACKUP_SH_FILENAME" \ --output "$BACKUP_SH_FILENAME" \
"$BACKUP_SH_OUTPATH/backup.sh.tar.gz" > /dev/null 2>&1 "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" > /dev/null 2>&1
@ -138,7 +129,7 @@ make_backup() {
echo "File name: $BACKUP_SH_FILENAME" echo "File name: $BACKUP_SH_FILENAME"
echo "File size: $BACKUP_SH_FILE_SIZE($BACKUP_SH_FILE_SIZE_H)" echo "File size: $BACKUP_SH_FILE_SIZE($BACKUP_SH_FILE_SIZE_H)"
echo "File hash: $BACKUP_SH_HASH" echo "File hash: $BACKUP_SH_HASH"
echo "Elapsed time: $(("$BACKUP_SH_END_TIME" - "$BACKUP_SH_START_TIME")) seconds." printf "Elapsed time: %s seconds.\n" "$((BACKUP_SH_END_TIME - BACKUP_SH_START_TIME))"
} }
extract_backup() { extract_backup() {
@ -150,7 +141,7 @@ extract_backup() {
--decrypt \ --decrypt \
--no-symkey-cache \ --no-symkey-cache \
--pinentry-mode=loopback \ --pinentry-mode=loopback \
--batch --passphrase-fd 3 3<<<"$BACKUP_SH_ARCHIVE_PW" \ --batch --passphrase "$BACKUP_SH_ARCHIVE_PW" \
--output backup.sh.tar.gz \ --output backup.sh.tar.gz \
"$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PATH"
@ -178,49 +169,56 @@ Report bugs to: Marco Cetica(<email@marcocetica.com>)
EOF EOF
} }
main() {
# Check whether dependecies are installed
checkdeps
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
echo "Please, specify an argument." echo "Please, specify an argument."
echo "For more information, try --help." echo "For more information, try --help."
exit 1 exit 1
fi fi
# Parse CLI arguments # Parse CLI arguments
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
-b|--backup) -b|--backup)
BACKUP_SH_SOURCES_PATH="$2" BACKUP_SH_SOURCES_PATH="$2"
BACKUP_SH_OUTPATH="$3" BACKUP_SH_OUTPATH="$3"
BACKUP_SH_PASSWORD="$4" BACKUP_SH_PASSWORD="$4"
if [ -z "$BACKUP_SH_SOURCES_PATH" ] || [ -z "$BACKUP_SH_OUTPATH" ] || [ -z "$BACKUP_SH_PASSWORD" ]; then if [ -z "$BACKUP_SH_SOURCES_PATH" ] || [ -z "$BACKUP_SH_OUTPATH" ] || [ -z "$BACKUP_SH_PASSWORD" ]; then
echo "Please, specify a source file, an output path and a password." echo "Please, specify a source file, an output path and a password."
echo "For more informatio, try --help" echo "For more informatio, try --help"
exit 1
fi
make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD"
exit 0
;;
-e|--extract)
BACKUP_SH_ARCHIVE_PATH="$2"
BACKUP_SH_ARCHIVE_PW="$3"
if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ]; then
echo "Please, specify an encrypted archive and a password."
echo "For more informatio, try --help"
exit 1
fi
extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW"
exit 0
;;
-h|--help)
helper "$0"
exit 0
;;
*)
echo "Unknown option $1."
echo "For more information, try --help"
exit 1 exit 1
fi ;;
make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD" esac
exit 0 done
;; }
-e|--extract)
BACKUP_SH_ARCHIVE_PATH="$2"
BACKUP_SH_ARCHIVE_PW="$3"
if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ]; then main "$@"
echo "Please, specify an encrypted archive and a password." # vim: ts=4 sw=4 softtabstop=4 expandtab:
echo "For more informatio, try --help"
exit 1
fi
extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW"
exit 0
;;
-h|--help)
helper "$0"
exit 0
;;
*)
echo "Unknown option $1."
echo "For more information, try --help"
exit 1
;;
esac
done

View File

@ -1,38 +1,19 @@
.\" Automatically generated by Pandoc 2.17.1.1 .\" Automatically generated by Pandoc 3.1.8
.\" .\"
.\" Define V font for inline verbatim, using C font in formats .TH "backup.sh" "1" "February 27, 2024" "Marco Cetica" "General Commands Manual"
.\" that render this, and otherwise B font.
.ie "\f[CB]x\f[]"x" \{\
. ftr V B
. ftr VI BI
. ftr VB B
. ftr VBI BI
.\}
.el \{\
. ftr V CR
. ftr VI CI
. ftr VB CB
. ftr VBI CBI
.\}
.TH "backup.sh" "1" "October 10, 2023" "Marco Cetica" "General Commands Manual"
.hy
.SH NAME .SH NAME
.PP
\f[B]backup.sh\f[R] - POSIX compliant, modular and lightweight backup \f[B]backup.sh\f[R] - POSIX compliant, modular and lightweight backup
utility to save and encrypt your files. utility to save and encrypt your files.
.SH SYNOPSIS .SH SYNOPSIS
.IP .IP
.nf .EX
\f[C]
Syntax: backup.sh [-b|-e|-h] Syntax: backup.sh [-b|-e|-h]
options: options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file. -b|--backup SOURCES DEST PASS Backup folders from SOURCES file.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS. -e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
-h|--help Show this helper. -h|--help Show this helper.
\f[R] .EE
.fi
.SH DESCRIPTION .SH DESCRIPTION
.PP
\f[B]backup.sh\f[R] is a POSIX compliant, modular and lightweight backup \f[B]backup.sh\f[R] is a POSIX compliant, modular and lightweight backup
utility to save and encrypt your files. utility to save and encrypt your files.
This tool is intended to be used on small scale UNIX environment such as This tool is intended to be used on small scale UNIX environment such as
@ -40,95 +21,78 @@ VPS, small servers and workstations.
\f[B]backup.sh\f[R] uses \f[I]rsync\f[R], \f[I]tar\f[R] and \f[B]backup.sh\f[R] uses \f[I]rsync\f[R], \f[I]tar\f[R] and
\f[I]gpg\f[R] to copy, compress and encrypt the backup. \f[I]gpg\f[R] to copy, compress and encrypt the backup.
.SH OPTIONS .SH OPTIONS
.PP
\f[B]backup.sh\f[R] supports two options: \f[I]backup creation\f[R] and \f[B]backup.sh\f[R] supports two options: \f[I]backup creation\f[R] and
\f[I]backup extraction\f[R]. \f[I]backup extraction\f[R].
The former requires root permissions, while the latter does not. The former requires root permissions, while the latter does not.
Let us see them in details: Let us see them in details:
.SS Backup creation .SS Backup creation
.PP
To specify the directories to backup, \f[B]backup.sh\f[R] uses an To specify the directories to backup, \f[B]backup.sh\f[R] uses an
associative array defined in a text file(called sources file) with the associative array defined in a text file(called sources file) with the
following syntax: following syntax:
.IP .IP
.nf .EX
\f[C]
<LABEL>=<PATH> <LABEL>=<PATH>
\f[R] .EE
.fi
.PP .PP
Where \f[V]<LABEL>\f[R] is the name of the backup and \f[V]<PATH>\f[R] Where \f[CR]<LABEL>\f[R] is the name of the backup and \f[CR]<PATH>\f[R]
is its path. is its path.
For example, if you want to back up \f[I]/etc/nginx\f[R] and For example, if you want to back up \f[I]/etc/nginx\f[R] and
\f[I]/etc/ssh\f[R], add the following entries to the sources file: \f[I]/etc/ssh\f[R], add the following entries to the sources file:
.IP .IP
.nf .EX
\f[C]
nginx=/etc/nginx/ nginx=/etc/nginx/
ssh=/etc/ssh/ ssh=/etc/ssh/
\f[R] .EE
.fi
.PP .PP
\f[B]backup.sh\f[R] will create two folders inside the backup archive \f[B]backup.sh\f[R] will create two folders inside the backup archive
with the following syntax: with the following syntax:
.IP .IP
.nf .EX
\f[C]
backup-<LABEL>-<YYYYMMDD> backup-<LABEL>-<YYYYMMDD>
\f[R] .EE
.fi
.PP .PP
In the previous example, this would be: In the previous example, this would be:
.IP .IP
.nf .EX
\f[C]
backup-nginx-<YYYYMMDD> backup-nginx-<YYYYMMDD>
backup-ssh-<YYYYMMDD> backup-ssh-<YYYYMMDD>
\f[R] .EE
.fi
.PP .PP
You can add as many entries as you want, just be sure to use the proper You can add as many entries as you want, just be sure to use the proper
syntax. syntax.
In particular, the sources file, \f[I]should not\f[R] includes: In particular, the sources file, \f[I]should not\f[R] includes:
.IP .IP
.nf .EX
\f[C]
- Spaces between the label and the equal sign; - Spaces between the label and the equal sign;
- Empty lines; - Empty lines;
- Comments. - Comments.
\f[R] .EE
.fi
.PP .PP
You can find a sample sources file at \f[V]sources.bk\f[R](or at You can find a sample sources file at \f[CR]sources.bk\f[R](or at
\f[V]/usr/local/etc/sources.bk\f[R]). \f[CR]/usr/local/etc/sources.bk\f[R]).
.PP .PP
After having defined the sources file, you can invoke After having defined the sources file, you can invoke
\f[B]backup.sh\f[R] using the following syntax: \f[B]backup.sh\f[R] using the following syntax:
.IP .IP
.nf .EX
\f[C]
$> sudo ./backup.sh --backup <SOURCES_FILE> <DEST> <ENCRYPTION_PASSWORD> $> sudo ./backup.sh --backup <SOURCES_FILE> <DEST> <ENCRYPTION_PASSWORD>
\f[R] .EE
.fi
.PP .PP
Where \f[V]<SOURCES_FILE>\f[R] is the \f[I]sources file\f[R], Where \f[CR]<SOURCES_FILE>\f[R] is the \f[I]sources file\f[R],
\f[V]<DEST>\f[R] is the absolute path of the output of the backup \f[CR]<DEST>\f[R] is the absolute path of the output of the backup
\f[I]without trailing slashes\f[R] and \f[V]<ENCRYPTION_PASSWORD>\f[R] \f[I]without trailing slashes\f[R] and \f[CR]<ENCRYPTION_PASSWORD>\f[R]
is the password to encrypt the compressed archive. is the password to encrypt the compressed archive.
.PP .PP
In the previous example, this would be: In the previous example, this would be:
.IP .IP
.nf .EX
\f[C]
$> sudo ./backup.sh --backup sources.bk /home/john badpw1234 $> sudo ./backup.sh --backup sources.bk /home/john badpw1234
\f[R] .EE
.fi
.PP .PP
The backup utility will begin to copy the files defined in the sources The backup utility will begin to copy the files defined in the sources
file: file:
.IP .IP
.nf .EX
\f[C]
Copying nginx(1/2) Copying nginx(1/2)
Copying ssh(2/2) Copying ssh(2/2)
Compressing backup... Compressing backup...
@ -137,195 +101,165 @@ File name: /home/marco/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
File size: 7336400696(6.9G) File size: 7336400696(6.9G)
File hash: 0e75ca393117f389d9e8edfea7106d98 File hash: 0e75ca393117f389d9e8edfea7106d98
Elapsed time: 259 seconds. Elapsed time: 259 seconds.
\f[R] .EE
.fi
.PP .PP
After that, you will find the final backup archive in After that, you will find the final backup archive in
\f[V]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc\f[R]. \f[CR]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc\f[R].
.PP .PP
You can also use \f[B]backup.sh\f[R] from a crontab rule: You can also use \f[B]backup.sh\f[R] from a crontab rule:
.IP .IP
.nf .EX
\f[C]
$> sudo crontab -e $> sudo crontab -e
30 03 * * 6 EKEY=$(cat /home/john/.ekey) bash -c \[aq]/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY\[aq] > /dev/null 2>&1 30 03 * * 6 EKEY=$(cat /home/john/.ekey) sh -c \[aq]/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY\[aq] > /dev/null 2>&1
\f[R] .EE
.fi
.PP .PP
This will automatically run \f[B]backup.sh\f[R] every Saturday morning This will automatically run \f[B]backup.sh\f[R] every Saturday morning
at 03:30 AM. at 03:30 AM.
In the example above, the encryption key is stored in a local file(with In the example above, the encryption key is stored in a local file(with
fixed permissions) to avoid password leaking in crontab logs. fixed permissions) to avoid password leaking in crontab logs.
You can also adopt this practice while using the \f[V]--extract\f[R] You can also adopt this practice while using the \f[CR]--extract\f[R]
option to avoid password leaking in shell history. option to avoid password leaking in shell history.
.SS Backup extraction .SS Backup extraction
.PP
\f[B]backup.sh\f[R] can also extract the encrypted backup archive using \f[B]backup.sh\f[R] can also extract the encrypted backup archive using
the following syntax: the following syntax:
.IP .IP
.nf .EX
\f[C]
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> $> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
\f[R] .EE
.fi
.PP .PP
Where \f[V]<ENCRYPTED_ARCHIVE>\f[R] is the encrypted backup and Where \f[CR]<ENCRYPTED_ARCHIVE>\f[R] is the encrypted backup and
\f[V]<ARCHIVE_PASSWORD>\f[R] is the backup password. \f[CR]<ARCHIVE_PASSWORD>\f[R] is the backup password.
.PP .PP
For instance: For instance:
.IP .IP
.nf .EX
\f[C]
$> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 $> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234
\f[R] .EE
.fi
.PP .PP
This will create a new folder called \f[V]backup.sh.tmp\f[R] in your This will create a new folder called \f[CR]backup.sh.tmp\f[R] in your
local directory. local directory.
Be sure to rename any directory with that name to avoid collisions. Be sure to rename any directory with that name to avoid collisions.
From the previous example, you should have the following directories: From the previous example, you should have the following directories:
.IP .IP
.nf .EX
\f[C]
backup-nginx-<YYYYMMDD> backup-nginx-<YYYYMMDD>
backup-ssh-<YYYYMMDD> backup-ssh-<YYYYMMDD>
\f[R] .EE
.fi
.SS How does backup.sh work? .SS How does backup.sh work?
.PP
\f[B]backup.sh\f[R] uses \f[I]rsync\f[R] to copy the files, \f[B]backup.sh\f[R] uses \f[I]rsync\f[R] to copy the files,
\f[I]tar\f[R] to compress the backup and \f[I]gpg\f[R] to encrypt it. \f[I]tar\f[R] to compress the backup and \f[I]gpg\f[R] to encrypt it.
By default, rsync is being used with the following parameters: By default, rsync is being used with the following parameters:
.IP .IP
.nf .EX
\f[C]
$> rsync -aPhrq --delete $> rsync -aPhrq --delete
\f[R] .EE
.fi
.PP .PP
That is: That is:
.IP .IP
.nf .EX
\f[C]
- a: archive mode: rsync copies files recursively while preserving as much metadata as possible; - a: archive mode: rsync copies files recursively while preserving as much metadata as possible;
- P: progress/partial: allows rsync to resume interrupted transfers and to shows progress information; - P: progress/partial: allows rsync to resume interrupted transfers and to shows progress information;
- h: human readable output, rsync shows output numbers in a more readable way; - h: human readable output, rsync shows output numbers in a more readable way;
- r: recursive mode: forces rsync to copy directories and their content; - r: recursive mode: forces rsync to copy directories and their content;
- q: quiet mode: reduces the amount of information rsync produces; - q: quiet mode: reduces the amount of information rsync produces;
- delete: delete mode: forces rsync to delete any extraneous files at the destination dir. - delete: delete mode: forces rsync to delete any extraneous files at the destination dir.
\f[R] .EE
.fi
.PP .PP
After that the backup folder is being encrypted using gpg. After that the backup folder is being encrypted using gpg.
By default, it is used with the following parameters: By default, it is used with the following parameters:
.IP .IP
.nf .EX
\f[C]
$> gpg -a \[rs] $> gpg -a \[rs]
--symmetric \[rs] --symmetric \[rs]
--cipher-algo=AES256 \[rs] --cipher-algo=AES256 \[rs]
--no-symkey-cache \[rs] --no-symkey-cache \[rs]
--pinentry-mode=loopback \[rs] --pinentry-mode=loopback \[rs]
--batch --passphrase-fd 3 3<<< \[dq]$PASSWORD\[dq] \[rs] --batch --passphrase-fd \[dq]$PASSWORD\[dq] \[rs]
--output \[dq]$OUTPUT\[dq] \[rs] --output \[dq]$OUTPUT\[dq] \[rs]
\[dq]$INPUT\[dq] \[dq]$INPUT\[dq]
\f[R] .EE
.fi
.PP .PP
This command encrypts the backup using the AES-256 symmetric encryption This command encrypts the backup using the AES-256 symmetric encryption
algorithm with a 256bit key. algorithm with a 256bit key.
Here is what each flag do: - \f[V]--symmetric\f[R]: Use symmetric Here is what each flag do: - \f[CR]--symmetric\f[R]: Use symmetric
encryption; encryption;
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]--cipher-algo=AES256\f[R]: Use AES256 algorithm; - \f[CR]--cipher-algo=AES256\f[R]: Use AES256 algorithm;
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]--no-symkey-cache\f[R]: Do not save password on GPG\[cq]s cache; - \f[CR]--no-symkey-cache\f[R]: Do not save password on GPG\[cq]s cache;
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]--pinentry-mode=loopback --batch\f[R]: Do not prompt the user; - \f[CR]--pinentry-mode=loopback --batch\f[R]: Do not prompt the user;
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]--passphrase-fd 3 3<< \[dq]$PASSWORD\[dq]\f[R]: Read password - \f[CR]--passphrase-fd 3 3<< \[dq]$PASSWORD\[dq]\f[R]: Read password
without revealing it on \f[V]ps\f[R]; without revealing it on \f[CR]ps\f[R];
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]--output\f[R]: Specify output file; - \f[CR]--output\f[R]: Specify output file;
.PD 0 .PD 0
.P .P
.PD .PD
- \f[V]$INPUT\f[R]: Specify input file. - \f[CR]$INPUT\f[R]: Specify input file.
.SH EXAMPLES .SH EXAMPLES
.PP
Below there are some examples that demonstrate \f[B]backup.sh\f[R]\[cq]s Below there are some examples that demonstrate \f[B]backup.sh\f[R]\[cq]s
usage. usage.
.IP "1." 3 .IP "1." 3
Create a backup of \f[V]/etc/ssh\f[R], \f[V]/var/www\f[R] and Create a backup of \f[CR]/etc/ssh\f[R], \f[CR]/var/www\f[R] and
\f[V]/var/log\f[R] inside the \f[V]/tmp\f[R] directory using a password \f[CR]/var/log\f[R] inside the \f[CR]/tmp\f[R] directory using a
stored in \f[V]/home/op1/.backup_pw\f[R] password stored in \f[CR]/home/op1/.backup_pw\f[R]
.PP .PP
The first thing to do is to define the source paths inside a The first thing to do is to define the source paths inside a
\f[I]sources file\f[R]: \f[I]sources file\f[R]:
.IP .IP
.nf .EX
\f[C]
$> cat sources.bk $> cat sources.bk
ssh=/etc/ssh ssh=/etc/ssh
web_root=/var/www web_root=/var/www
logs=/var/log logs=/var/log
\f[R] .EE
.fi
.PP .PP
After that we can load our encryption key from the specified file inside After that we can load our encryption key from the specified file inside
a environment variable: a environment variable:
.IP .IP
.nf .EX
\f[C]
$> ENC_KEY=$(cat /home/op1/.backup_pw) $> ENC_KEY=$(cat /home/op1/.backup_pw)
\f[R] .EE
.fi
.PP .PP
Finally, we can start the backup process with: Finally, we can start the backup process with:
.IP .IP
.nf .EX
\f[C]
$> sudo backup.sh --backup sources.bk /tmp $ENC_KEY $> sudo backup.sh --backup sources.bk /tmp $ENC_KEY
\f[R] .EE
.fi
.IP "2." 3 .IP "2." 3
Extract the content of a backup made on 2023-03-14 with the password Extract the content of a backup made on 2023-03-14 with the password
`Ax98f!' `Ax98f!'
.PP .PP
To do this, we can simply issue the following command: To do this, we can simply issue the following command:
.IP .IP
.nf .EX
\f[C]
$> backup.sh --extract backup-af9a8e6bfe15-20230314.tar.gz.enc \[dq]Ax98f!\[dq] $> backup.sh --extract backup-af9a8e6bfe15-20230314.tar.gz.enc \[dq]Ax98f!\[dq]
\f[R] .EE
.fi
.IP "3." 3 .IP "3." 3
Extract the content of a backup made on 2018-04-25 using the password in Extract the content of a backup made on 2018-04-25 using the password in
\f[V]/home/john/.pw\f[R] \f[CR]/home/john/.pw\f[R]
.PP .PP
This example is very similar to the previous one, we just need to read This example is very similar to the previous one, we just need to read
the password from the text file: the password from the text file:
.IP .IP
.nf .EX
\f[C]
$> backup.sh --extract backup-af9a8e6bfe15-20180425.tar.gz.enc \[dq]$(cat /home/john/.pw)\[dq] $> backup.sh --extract backup-af9a8e6bfe15-20180425.tar.gz.enc \[dq]$(cat /home/john/.pw)\[dq]
\f[R] .EE
.fi
.SH AUTHORS .SH AUTHORS
.PP
\f[B]backup.sh\f[R] was written by Marco Cetica on late 2018. \f[B]backup.sh\f[R] was written by Marco Cetica on late 2018.
.SH BUGS .SH BUGS
.PP
Submit bug reports online at: <email@marcocetica.com> or open an issue Submit bug reports online at: <email@marcocetica.com> or open an issue
on the issue tracker of the GitHub page of this project: on the issue tracker of the GitHub page of this project:
https://github.com/ice-bit/backup.sh https://github.com/ice-bit/backup.sh

6
man.md
View File

@ -3,7 +3,7 @@ title: backup.sh
section: 1 section: 1
header: General Commands Manual header: General Commands Manual
footer: Marco Cetica footer: Marco Cetica
date: October 10, 2023 date: February 27, 2024
--- ---
# NAME # NAME
@ -98,7 +98,7 @@ You can also use **backup.sh** from a crontab rule:
``` ```
$> sudo crontab -e $> sudo crontab -e
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 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
``` ```
This will automatically run **backup.sh** every Saturday morning at 03:30 AM. This will automatically run **backup.sh** every Saturday morning at 03:30 AM.
@ -154,7 +154,7 @@ $> gpg -a \
--cipher-algo=AES256 \ --cipher-algo=AES256 \
--no-symkey-cache \ --no-symkey-cache \
--pinentry-mode=loopback \ --pinentry-mode=loopback \
--batch --passphrase-fd 3 3<<< "$PASSWORD" \ --batch --passphrase-fd "$PASSWORD" \
--output "$OUTPUT" \ --output "$OUTPUT" \
"$INPUT" "$INPUT"
``` ```

View File

@ -1,12 +1,10 @@
#!/bin/bash #!/usr/bin/env bash
# Unit tests for backup.sh # Unit tests for backup.sh
# This tool is NOT intended to be used outside # This tool is NOT intended to be used outside
# of a testing environment, please use at your own risk. # of a testing environment, please use at your own risk.
# By Marco Cetica 2023 (<email@marcocetica.com>) # By Marco Cetica 2023 (<email@marcocetica.com>)
# #
set -e
helper() { helper() {
cat <<EOF cat <<EOF
backup.sh unit testing suite. backup.sh unit testing suite.