New version!

- Fixed bug related to Bash version that affected Darwin systems;
- Fixed bug with file existence check;
- Fixed minor issues;
- Fixed various typos;
- Added verbose mode;
- Added packages for Debian and RHEL.
This commit is contained in:
2024-10-21 12:05:16 +02:00
parent 2bb255840d
commit e783c2a176
8 changed files with 242 additions and 254 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
deb/

View File

@@ -6,17 +6,22 @@ workstations. `backup.sh` uses [rsync](https://linux.die.net/man/1/rsync), [tar]
to copy, compress, encrypt the backup and verify the backup. to copy, compress, encrypt the backup and verify the backup.
## Installation ## Installation
`backup.sh` consists in a single source file, to install it you can copy the script wherever you want. `backup.sh` is a single source file, to install it you can copy the script wherever you want. Alternatively, if you
Alternatively, you can install the script, the default sources file and the man file using the following command: are running a DEB/RPM distribution, you can install it with the following command:
```sh
$> sudo apt install ./bin/backup.sh-1.0.0.x86_64.deb # Debian
$> sudo dnf install ./bin/backup.sh-1.0.0-2.x86_64.rpm # RHEL
```
For any other UNIX system, you can use the following command:
```sh ```sh
$> sudo make install $> sudo make install
``` ```
This will copy `backup.sh` into `/usr/local/bin/backup.sh`, `sources.bk` into `/usr/local/etc/sources.bk` and This will copy `backup.sh` into `/usr/local/bin/backup.sh`, `sources.bk` into `/usr/local/etc/sources.bk` and
`backup.sh.1` into `/usr/share/man/man1/backup.sh.1`. To uninstall the program along with the sample _sources file_ and the manual page, `backup.sh.1` into `/usr/share/man/man1/backup.sh.1`. To uninstall the program along with the sample _sources file_ and the manual page, you can issue `sudo make uninstall`.
you can issue `sudo make uninstall`.
At this point you still need to install the following dependencies: At this point you still need to install the following dependencies:
- `Bash` - `Bash(v>=4)`
- `rsync` - `rsync`
- `tar` - `tar`
- `gpg` - `gpg`
@@ -24,13 +29,14 @@ At this point you still need to install the following dependencies:
## Usage ## Usage
To show the available options, you can run `backup.sh --help`, which will print out the following message: To show the available options, you can run `backup.sh --help`, which will print out the following message:
```text ```text
backup.sh - POSIX compliant, modular and lightweight backup utility. backup.sh v1.0.0 - POSIX compliant, modular and lightweight backup utility.
Syntax: ./backup.sh [-b|-c|-e|-h] Syntax: ./backup.sh [-b|-e|-c|-V|-h]
options: options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file. -b|--backup SOURCES DEST PASS Backup folders from SOURCES file.
-c|--checksum Generate/check SHA256 of a backup.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS. -e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
-c|--checksum Generate/check SHA256 of a backup.
-V|--verbose Enable verbose mode.
-h|--help Show this helper. -h|--help Show this helper.
General help with the software: https://github.com/ceticamarco/backup.sh General help with the software: https://github.com/ceticamarco/backup.sh
@@ -121,6 +127,8 @@ This will automatically run `backup.sh` every Saturday morning at 03:30 AM. In t
key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs. You can also key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs. You can also
adopt this practice while using the `--extract` option to avoid password leaking in shell history. adopt this practice while using the `--extract` option to avoid password leaking in shell history.
By default `backup.sh` is very quiet, to add some verbosity to the output, be sure to use the `-V`(`--verbose`) option.
### Backup extraction ### Backup extraction
`backup.sh` can also be used to extract and to verify the encrypted backup. `backup.sh` can also be used to extract and to verify the encrypted backup.
To do so, use the following commands: To do so, use the following commands:

View File

@@ -37,6 +37,11 @@
set -e set -e
checkdeps() { checkdeps() {
if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
echo "This version of Bash is not supported."
exit 1
fi
# Check if dependencies are installed # Check if dependencies are installed
missing_dep=0 missing_dep=0
deps="rsync tar gpg" deps="rsync tar gpg"
@@ -66,13 +71,20 @@ gethash() {
# $2: output path # $2: output path
# $3: password # $3: password
# $4: compute sha256(0,1) # $4: compute sha256(0,1)
# $5: verbosity flag(0,1)
make_backup() { make_backup() {
BACKUP_SH_SOURCES_PATH="$1" BACKUP_SH_SOURCES_PATH="$1"
BACKUP_SH_OUTPATH="$2" BACKUP_SH_OUTPATH="$2"
BACKUP_SH_PASS="$3" BACKUP_SH_PASS="$3"
BACKUP_SH_SHA256="$4" BACKUP_SH_SHA256="$4"
BACKUP_SH_VERBOSE="$5"
if [ "$BACKUP_SH_VERBOSE" -eq 1 ]; then
BACKUP_SH_COMMAND="rsync -aPhr --delete"
else
BACKUP_SH_COMMAND="rsync -aPhrq --delete" BACKUP_SH_COMMAND="rsync -aPhrq --delete"
fi
BACKUP_SH_DATE="$(date +'%Y%m%d')" BACKUP_SH_DATE="$(date +'%Y%m%d')"
BACKUP_SH_FOLDER="backup.sh.tmp" BACKUP_SH_FOLDER="backup.sh.tmp"
BACKUP_SH_OUTPUT="$BACKUP_SH_OUTPATH/$BACKUP_SH_FOLDER" BACKUP_SH_OUTPUT="$BACKUP_SH_OUTPATH/$BACKUP_SH_FOLDER"
@@ -119,8 +131,13 @@ make_backup() {
# Compress backup directory # Compress backup directory
echo "Compressing backup..." echo "Compressing backup..."
if [ "$BACKUP_SH_VERBOSE" -eq 1 ]; then
tar -cvzf "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" \
-C "$BACKUP_SH_OUTPATH" "$BACKUP_SH_FOLDER"
else
tar -czf "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" \ tar -czf "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" \
-C "$BACKUP_SH_OUTPATH" "$BACKUP_SH_FOLDER" > /dev/null 2>&1 -C "$BACKUP_SH_OUTPATH" "$BACKUP_SH_FOLDER" > /dev/null 2>&1
fi
# Encrypt backup directory # Encrypt backup directory
echo "Encrypting backup..." echo "Encrypting backup..."
@@ -151,10 +168,12 @@ make_backup() {
# $1: archive file # $1: archive file
# $2: archive password # $2: archive password
# $3: sha256 file(optional) # $3: sha256 file(optional)
# $4: verbosity flag(0,1)
extract_backup() { extract_backup() {
BACKUP_SH_ARCHIVE_PATH="$1" BACKUP_SH_ARCHIVE_PATH="$1"
BACKUP_SH_ARCHIVE_PW="$2" BACKUP_SH_ARCHIVE_PW="$2"
BACKUP_SH_SHA256_FILE="$3" BACKUP_SH_SHA256_FILE="$3"
BACKUP_SH_VERBOSE="$4"
# Decrypt the archive # Decrypt the archive
gpg -a \ gpg -a \
@@ -167,7 +186,11 @@ extract_backup() {
"$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PATH"
# Extract archive # Extract archive
tar -xzf backup.sh.tar.gz 1> /dev/null 2>&1 if [ "$BACKUP_SH_VERBOSE" -eq 1 ]; then
tar -xzvf backup.sh.tar.gz
else
tar -xzf backup.sh.tar.gz > /dev/null 2>&1
fi
# If specified, use SHA256 file to compute checksum of files # If specified, use SHA256 file to compute checksum of files
if [ -n "$BACKUP_SH_SHA256_FILE" ]; then if [ -n "$BACKUP_SH_SHA256_FILE" ]; then
@@ -179,10 +202,11 @@ extract_backup() {
SHA256="$(gethash "$file")" SHA256="$(gethash "$file")"
# Check if checksum file contains hash # 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 rm -rf backup.sh.tar.gz backup.sh.tmp
printf "[FATAL] - integrity error for '%s'.\n" "$file"
exit 1 exit 1
fi fi
printf "[OK] - integrity check for '%s' passed.\n" "$file"
done done
shopt -u globstar dotglob shopt -u globstar dotglob
fi fi
@@ -194,13 +218,14 @@ helper() {
CLI_NAME="$1" CLI_NAME="$1"
cat <<EOF cat <<EOF
backup.sh - POSIX compliant, modular and lightweight backup utility. backup.sh v1.0.0 - POSIX compliant, modular and lightweight backup utility.
Syntax: $CLI_NAME [-b|-c|-e|-h] Syntax: $CLI_NAME [-b|-e|-c|-V|-h]
options: options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file. -b|--backup SOURCES DEST PASS Backup folders from SOURCES file.
-c|--checksum Generate/check SHA256 of a backup.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS. -e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
-c|--checksum Generate/check SHA256 of a backup.
-V|--verbose Enable verbose mode.
-h|--help Show this helper. -h|--help Show this helper.
General help with the software: https://github.com/ceticamarco/backup.sh General help with the software: https://github.com/ceticamarco/backup.sh
@@ -219,6 +244,7 @@ main() {
fi fi
CHECKSUM_FLAG=0 CHECKSUM_FLAG=0
VERBOSE_FLAG=0
# Parse CLI arguments # Parse CLI arguments
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
@@ -233,20 +259,11 @@ main() {
exit 1 exit 1
fi fi
if [ "$CHECKSUM_FLAG" -eq 1 ]; then
[ -f "$BACKUP_SH_SOURCES_PATH" ] || { echo "Sources file does not exist"; exit 1; } [ -f "$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 make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD" "$CHECKSUM_FLAG" "$VERBOSE_FLAG"
else
make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD" 0
fi
exit 0 exit 0
;; ;;
-c|--checksum)
[ $# -eq 1 ] && { echo "Use this option with '--backup' or '--extract'"; exit 1; }
CHECKSUM_FLAG=1
shift 1
;;
-e|--extract) -e|--extract)
BACKUP_SH_ARCHIVE_FILE="$2" BACKUP_SH_ARCHIVE_FILE="$2"
BACKUP_SH_ARCHIVE_PW="$3" BACKUP_SH_ARCHIVE_PW="$3"
@@ -261,21 +278,33 @@ main() {
else else
if [ -z "$BACKUP_SH_ARCHIVE_FILE" ] || [ -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 "Please, specify an encrypted archive and a password."
echo "For more informatio, try --help" echo "For more information, try --help"
exit 1 exit 1
fi fi
fi fi
# Check whether backup file exists or not
[ -f "$BACKUP_SH_ARCHIVE_FILE" ] || { echo "Backup file does not exist"; exit 1; }
if [ "$CHECKSUM_FLAG" -eq 1 ]; then if [ "$CHECKSUM_FLAG" -eq 1 ]; then
[ -f "$BACKUP_SH_SHA256_FILE" ] || { echo "Checksum file does not exist"; exit 1; } [ -f "$BACKUP_SH_SHA256_FILE" ] || { echo "Checksum file does not exist"; exit 1; }
[ -f "$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" "$VERBOSE_FLAG"
extract_backup "$BACKUP_SH_ARCHIVE_FILE" "$BACKUP_SH_ARCHIVE_PW" "$BACKUP_SH_SHA256_FILE"
else else
extract_backup "$BACKUP_SH_ARCHIVE_FILE" "$BACKUP_SH_ARCHIVE_PW" extract_backup "$BACKUP_SH_ARCHIVE_FILE" "$BACKUP_SH_ARCHIVE_PW" "" "$VERBOSE_FLAG"
fi fi
exit 0 exit 0
;; ;;
-c|--checksum)
[ $# -eq 1 ] && { echo "Use '--checksum' with '--backup' or '--extract'"; exit 1; }
CHECKSUM_FLAG=1
shift 1
;;
-V|--verbose)
[ $# -eq 1 ] && { echo "Use '--verbose' with '--backup' or '--extract'"; exit 1; }
VERBOSE_FLAG=1
shift 1
;;
-h|--help) -h|--help)
helper "$0" helper "$0"
exit 0 exit 0

View File

@@ -1,39 +1,24 @@
.\" Automatically generated by Pandoc 2.17.1.1 .\" Automatically generated by Pandoc 3.5
.\" .\"
.\" Define V font for inline verbatim, using C font in formats .TH "backup.sh" "1" "October 21, 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" "April 4, 2024" "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.
utility to save and encrypt your files.
.SH SYNOPSIS .SH SYNOPSIS
.IP .IP
.nf .EX
\f[C] Syntax: ./backup.sh [\-b|\-e|\-c|\-V|\-h]
Syntax: ./backup.sh [-b|-c|-e|-h]
options: options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file. \-b|\-\-backup SOURCES DEST PASS Backup folders from SOURCES file.
-c|--checksum Generate/check SHA256 of a backup. \-e|\-\-extract ARCHIVE PASS Extract ARCHIVE using PASS.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS. \-c|\-\-checksum Generate/check SHA256 of a backup.
-h|--help Show this helper. \-V|\-\-verbose Enable verbose mode.
\f[R] \-h|\-\-help Show this helper.
.fi
General help with the software: https://github.com/ceticamarco/backup.sh
Report bugs to: Marco Cetica(<email\[at]marcocetica.com>)
.EE
.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
@@ -42,7 +27,6 @@ VPS, small servers and workstations.
\f[I]sha256sum\f[R] and \f[I]gpg\f[R] to copy, compress, verify and \f[I]sha256sum\f[R] and \f[I]gpg\f[R] to copy, compress, verify and
encrypt the backup. encrypt the backup.
.SH OPTIONS .SH OPTIONS
.PP
\f[B]backup.sh\f[R] supports three options: \f[B]backup creation\f[R], \f[B]backup.sh\f[R] supports three options: \f[B]backup creation\f[R],
\f[B]backup extraction\f[R] and \f[B]checksum\f[R] to verify the \f[B]backup extraction\f[R] and \f[B]checksum\f[R] to verify the
integrity of a backup. integrity of a backup.
@@ -51,163 +35,142 @@ not.
The checksum option must be used in combination of one of the previous The checksum option must be used in combination of one of the previous
options. options.
.SS Backup creation .SS Backup creation
.PP To specify the directories to back up, \f[CR]backup.sh\f[R] uses an
To specify the directories to back up, \f[V]backup.sh\f[R] uses an
associative array defined in a text file(called \f[I]sources file\f[R]) associative array defined in a text file(called \f[I]sources file\f[R])
with the following syntax: with the 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[V]/etc/nginx\f[R] and For example, if you want to back up \f[CR]/etc/nginx\f[R] and
\f[V]/etc/ssh\f[R], add the following entries to the \f[I]sources \f[CR]/etc/ssh\f[R], add the following entries to the \f[I]sources
file\f[R]: file\f[R]:
.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[V]backup.sh\f[R] will create two folders inside the backup archive \f[CR]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> .EE
\f[R]
.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> .EE
\f[R]
.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 \f[I]sources file\f[R], \f[B]should not\f[R] include: In particular, the \f[I]sources file\f[R], \f[B]should not\f[R] include:
- Spaces between the label and the equal sign; \- Spaces between the label and the equal sign;
.PD 0 .PD 0
.P .P
.PD .PD
- Empty lines; \- Empty lines;
.PD 0 .PD 0
.P .P
.PD .PD
- Comments. \- Comments.
.PP .PP
You can find a sample \f[I]sources file\f[R] at \f[V]sources.bk\f[R](or You can find a sample \f[I]sources file\f[R] at \f[CR]sources.bk\f[R](or
at \f[V]/usr/local/etc/sources.bk\f[R]). at \f[CR]/usr/local/etc/sources.bk\f[R]).
.PP .PP
After having defined the \f[I]sources file\f[R], you can invoke After having defined the \f[I]sources file\f[R], you can invoke
\f[V]backup.sh\f[R] using the following syntax: \f[CR]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> .EE
\f[R]
.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[B]without trailing slashes\f[R] and \f[V]<ENCRYPTION_PASSWORD>\f[R] \f[B]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 .EE
\f[R]
.fi
.PP .PP
You can also tell \f[V]backup.sh\f[R] to generate a SHA256 file You can also tell \f[CR]backup.sh\f[R] to generate a SHA256 file
containing the hash of each file using the \f[V]-c\f[R] option. containing the hash of each file using the \f[CR]\-c\f[R] option.
In the previous example, this would be: In the previous example, this would be:
.IP .IP
.nf .EX
\f[C] $> sudo ./backup.sh \-\-checksum \-\-backup sources.bk /home/john badpw1234
$> sudo ./backup.sh --checksum --backup sources.bk /home/john badpw1234 .EE
\f[R]
.fi
.PP .PP
The backup utility will begin to copy the files defined in the The backup utility will begin to copy the files defined in the
\f[I]sources file\f[R]: \f[I]sources file\f[R]:
.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...
Encrypting backup... Encrypting backup...
File name: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc File name: /home/john/backup\-<HOSTNAME>\-<YYYYMMDD>.tar.gz.enc
Checksum file: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256 Checksum file: /home/john/backup\-<HOSTNAME>\-<YYYYMMDD>.sha256
File size: 7336400696(6.9G) File size: 7336400696(6.9G)
Elapsed time: 259 seconds. Elapsed time: 259 seconds.
\f[R] .EE
.fi
.PP .PP
After that, you will find the backup archive and the checksum file in After that, you will find the backup archive and the checksum file in
\f[V]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc\f[R] and \f[CR]/home/john/backup\-<HOSTNAME>\-<YYYYMMDD>.tar.gz.enc\f[R] and
\f[V]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256\f[R], respectively. \f[CR]/home/john/backup\-<HOSTNAME>\-<YYYYMMDD>.sha256\f[R],
respectively.
.PP .PP
You can also use \f[V]backup.sh\f[R] from a crontab rule: You can also use \f[CR]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) bash -c \[aq]/usr/local/bin/backup.sh -b /usr/local/etc/sources.bk /home/john $EKEY\[aq] > /dev/null 2>&1 .EE
\f[R]
.fi
.PP .PP
This will automatically run \f[V]backup.sh\f[R] every Saturday morning This will automatically run \f[CR]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
.PP .PP
By default \f[CR]backup.sh\f[R] is very quiet, to add some verbosity to
the output, be sure to use the \f[CR]\-V\f[R](\f[CR]\-\-verbose\f[R])
option.
.SS Backup extraction
\f[B]backup.sh\f[R] can also be used to extract and to verify the \f[B]backup.sh\f[R] can also be used to extract and to verify the
encrypted backup. encrypted backup.
To do so, use the following commands: To do so, use the following commands:
.IP .IP
.nf .EX
\f[C] $> ./backup.sh \-\-extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> .EE
\f[R]
.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 .EE
\f[R]
.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 with the following content: local directory with the following content:
.IP .IP
.nf .EX
\f[C] backup\-nginx\-<YYYYMMDD>
backup-nginx-<YYYYMMDD> backup\-ssh\-<YYYYMMDD>
backup-ssh-<YYYYMMDD> .EE
\f[R]
.fi
.PP .PP
\f[B]note\f[R]: be sure to rename any directory with that name to avoid \f[B]note\f[R]: be sure to rename any directory with that name to avoid
collisions. collisions.
@@ -215,48 +178,39 @@ collisions.
If you also want to verify the integrity of the backup data, use the If you also want to verify the integrity of the backup data, use the
following commands: following commands:
.IP .IP
.nf .EX
\f[C] $> ./backup.sh \-\-checksum \-\-extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> <CHECKSUM_ABSOLUTE_PATH>
$> ./backup.sh --checksum --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> <CHECKSUM_ABSOLUTE_PATH> .EE
\f[R]
.fi
.PP .PP
For instance: For instance:
.IP .IP
.nf .EX
\f[C] $> ./backup.sh \-\-checksum \-\-extract backup\-<hostname>\-<YYYYMMDD>.tar.gz.enc badpw1234 backup\-<hostname>\-<YYYYMMDD>.sha256
$> ./backup.sh --checksum --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 backup-<hostname>-<YYYYMMDD>.sha256 .EE
\f[R]
.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, \f[I]gpg\f[R] to encrypt it and \f[I]tar\f[R] to compress the backup, \f[I]gpg\f[R] to encrypt it and
\f[I]sha256sum\f[R] to verify it. \f[I]sha256sum\f[R] to verify 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 .EE
\f[R]
.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. .EE
\f[R]
.fi
.PP .PP
If specified(\f[V]--checksum\f[R] option), \f[V]backup.sh\f[R] can also If specified(\f[CR]\-\-checksum\f[R] option), \f[CR]backup.sh\f[R] can
generate the checksum of each file of the backup. also generate the checksum of each file of the backup.
To do so, it uses \f[V]sha256sum(1)\f[R] to compute the hash of every To do so, it uses \f[CR]sha256sum(1)\f[R] to compute the hash of every
single file using the SHA256 hashing algorithm. single file using the SHA256 hashing algorithm.
The checksum file contains nothing but the checksums of the files, no The checksum file contains nothing but the checksums of the files, no
other information about the files stored on the backup archive is other information about the files stored on the backup archive is
@@ -267,60 +221,59 @@ section for more information).
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 \[dq]$PASSWORD\[dq] \[rs]
--batch --passphrase \[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
without revealing it on \f[V]ps\f[R]; password 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.
.SS Plausible Deniability .SS Plausible Deniability
.PP While \f[CR]backup.sh\f[R] provide some pretty strong security against
While \f[V]backup.sh\f[R] provide some pretty strong security against
bruteforce attack(assuming a strong passphrase is being used) it should bruteforce attack(assuming a strong passphrase is being used) it should
by no means considered a viable tool against a cryptanalysis by no means considered a viable tool against a cryptanalysis
investigation. investigation.
Many of the copying, compressing and encrypting operations made by Many of the copying, compressing and encrypting operations made by
\f[V]backup.sh\f[R] during the backup process can be used to invalidate \f[CR]backup.sh\f[R] during the backup process can be used to invalidate
plausible deniability. plausible deniability.
In particular, you should pay attention to the following details: In particular, you should pay attention to the following details:
.IP "1." 3 .IP "1." 3
The \f[V]--checksum\f[R] option generates an \f[B]UNENCRYPTED\f[R] The \f[CR]\-\-checksum\f[R] option generates an \f[B]UNENCRYPTED\f[R]
checksum file containing the \f[I]digests\f[R] of \f[B]EVERY\f[R] file checksum file containing the \f[I]digests\f[R] of \f[B]EVERY\f[R] file
in your backup archive. in your backup archive.
If your files are known to your adversary(e.g., a banned book), they may If your files are known to your adversary(e.g., a banned book), they may
@@ -330,74 +283,64 @@ voiding your plausible deniability;
.P .P
.PD .PD
.IP "2." 3 .IP "2." 3
Since \f[V]backup.sh\f[R] is essentially a set of shell commands, an Since \f[CR]backup.sh\f[R] is essentially a set of shell commands, an
eavesdropper could monitor the whole backup process to extract the name eavesdropper could monitor the whole backup process to extract the name
of the files or the encryption password. of the files or the encryption password.
.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 singleFile=/home/john/file.txt
\f[R] logs=/var/log/
.fi .EE
.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
an environment variable: an 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 .EE
\f[R]
.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] .EE
\f[R]
.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
\f[V]/home/john/.pw\f[R] in \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] .EE
\f[R]
.fi
.SH AUTHORS .SH AUTHORS
.PP \f[B]backup.sh\f[R] is being developed by Marco Cetica since late 2018.
\f[B]backup.sh\f[R] was written by Marco Cetica on late 2018.
.SH BUGS .SH BUGS
.PP Submit bug reports at: \c
Submit bug reports online at: <email@marcocetica.com> or open an issue .MT email@marcocetica.com
on the issue tracker of the GitHub page of this project: .ME \c
https://github.com/ice-bit/backup.sh \ or open an issue on the issue tracker of the GitHub page of this
project: https://github.com/ice\-bit/backup.sh

Binary file not shown.

Binary file not shown.

25
man.md
View File

@@ -3,20 +3,24 @@ title: backup.sh
section: 1 section: 1
header: General Commands Manual header: General Commands Manual
footer: Marco Cetica footer: Marco Cetica
date: April 4, 2024 date: October 21, 2024
--- ---
# NAME # NAME
**backup.sh** - POSIX compliant, modular and lightweight backup utility to save and encrypt your files. **backup.sh** - POSIX compliant, modular and lightweight backup utility.
# SYNOPSIS # SYNOPSIS
``` ```
Syntax: ./backup.sh [-b|-c|-e|-h] Syntax: ./backup.sh [-b|-e|-c|-V|-h]
options: options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file. -b|--backup SOURCES DEST PASS Backup folders from SOURCES file.
-c|--checksum Generate/check SHA256 of a backup.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS. -e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
-c|--checksum Generate/check SHA256 of a backup.
-V|--verbose Enable verbose mode.
-h|--help Show this helper. -h|--help Show this helper.
General help with the software: https://github.com/ceticamarco/backup.sh
Report bugs to: Marco Cetica(<email@marcocetica.com>)
``` ```
# DESCRIPTION # DESCRIPTION
@@ -109,6 +113,8 @@ This will automatically run `backup.sh` every Saturday morning at 03:30 AM. In t
key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs. You can also key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs. You can also
adopt this practice while using the `--extract` option to avoid password leaking in shell history. adopt this practice while using the `--extract` option to avoid password leaking in shell history.
By default `backup.sh` is very quiet, to add some verbosity to the output, be sure to use the `-V`(`--verbose`) option.
## Backup extraction ## Backup extraction
**backup.sh** can also be used to extract and to verify the encrypted backup. **backup.sh** can also be used to extract and to verify the encrypted backup.
To do so, use the following commands: To do so, use the following commands:
@@ -216,9 +222,10 @@ The first thing to do is to define the source paths inside a _sources file_:
``` ```
$> cat sources.bk $> cat sources.bk
ssh=/etc/ssh ssh=/etc/ssh/
web_root=/var/www web_root=/var/www/
logs=/var/log singleFile=/home/john/file.txt
logs=/var/log/
``` ```
After that we can load our encryption key from the specified file inside an environment variable: After that we can load our encryption key from the specified file inside an environment variable:
@@ -252,8 +259,8 @@ $> backup.sh --extract backup-af9a8e6bfe15-20180425.tar.gz.enc "$(cat /home/john
``` ```
# AUTHORS # AUTHORS
**backup.sh** was written by Marco Cetica on late 2018. **backup.sh** is being developed by Marco Cetica since late 2018.
# BUGS # BUGS
Submit bug reports online at: <email@marcocetica.com> or open an issue Submit bug reports at: <email@marcocetica.com> or open an issue
on the issue tracker of the GitHub page of this project: https://github.com/ice-bit/backup.sh on the issue tracker of the GitHub page of this project: https://github.com/ice-bit/backup.sh

View File

@@ -51,13 +51,13 @@ create_files() {
} }
execute_backup() { execute_backup() {
./backup.sh -c -b sources.bk "$PWD" badpw ./backup.sh -V -c -b sources.bk "$PWD" badpw
} }
extract_backup() { extract_backup() {
host="$(uname -n)" host="$(uname -n)"
date="$(date +'%Y%m%d')" date="$(date +'%Y%m%d')"
./backup.sh -c -e "$PWD"/backup-"$host"-"$date".tar.gz.enc badpw "$PWD"/backup-"$host"-"$date".sha256 ./backup.sh -V -c -e "$PWD"/backup-"$host"-"$date".tar.gz.enc badpw "$PWD"/backup-"$host"-"$date".sha256
} }
test_backup() { test_backup() {