Added integrity check option(--checksum)
All checks were successful
backup.sh / bash (push) Successful in 31s
All checks were successful
backup.sh / bash (push) Successful in 31s
This commit is contained in:
parent
39a15d2f2a
commit
baa6f68706
88
README.md
88
README.md
@ -1,14 +1,9 @@
|
|||||||
# backup.sh ![](https://github.com/ceticamarco/backup.sh/actions/workflows/backup.sh.yml/badge.svg)
|
# backup.sh ![](https://github.com/ceticamarco/backup.sh/actions/workflows/backup.sh.yml/badge.svg)
|
||||||
`backup.sh` is a POSIX compliant, modular and lightweight backup utility to save and encrypt your files.
|
`backup.sh` is a POSIX compliant, modular and lightweight backup utility to save and encrypt your files.
|
||||||
This tool is intended to be used on small scale UNIX environments such as VPS, personal servers and
|
This tool is intended to be used on small scale UNIX environments such as VPS, personal servers and
|
||||||
workstations. `backup.sh` uses [rsync](https://linux.die.net/man/1/rsync), [tar](https://linux.die.net/man/1/tar)
|
workstations. `backup.sh` uses [rsync](https://linux.die.net/man/1/rsync), [tar](https://linux.die.net/man/1/tar),
|
||||||
and [gpg](https://linux.die.net/man/1/gpg) to copy, compress and encrypt the backup.
|
[gpg](https://linux.die.net/man/1/gpg) and [sha256sum](https://linux.die.net/man/1/sha256sum)
|
||||||
|
to copy, compress, encrypt the backup and verify the backup.
|
||||||
`backup.sh` works under the following operating systems:
|
|
||||||
- GNU/Linux;
|
|
||||||
- OpenBSD
|
|
||||||
- FreeBSD;
|
|
||||||
- Apple MacOS.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
`backup.sh` consists in a single source file, to install it you can copy the script wherever you want.
|
`backup.sh` consists in a single source file, to install it you can copy the script wherever you want.
|
||||||
@ -30,18 +25,23 @@ To show the available options, you can run `backup.sh --help`, which will print
|
|||||||
```text
|
```text
|
||||||
backup.sh - POSIX compliant, modular and lightweight backup utility.
|
backup.sh - POSIX compliant, modular and lightweight backup utility.
|
||||||
|
|
||||||
Syntax: ./backup.sh [-b|-e|-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.
|
||||||
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
-c|--checksum Generate/check SHA256 of a backup.
|
||||||
-h|--help Show this helper.
|
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
||||||
|
-h|--help Show this helper.
|
||||||
|
|
||||||
|
General help with the software: https://github.com/ceticamarco/backup.sh
|
||||||
|
Report bugs to: Marco Cetica(<email@marcocetica.com>)
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, `backup.sh` supports two options: **backup creation** and **backup extraction**, the former requires
|
As you can see, `backup.sh` supports three options: **backup creation**, **backup extraction** and **checksum** to verify the
|
||||||
root permissions, while the latter does not. Let us see them in details.
|
integrity of a backup. The first option requires
|
||||||
|
root permissions, while the second one does not. The checksum option must be used in combination of one of the previous options.
|
||||||
|
|
||||||
### Backup creation
|
### Backup creation
|
||||||
To specify the directories to backup, `backup.sh` uses an associative array
|
To specify the directories to back up, `backup.sh` uses an associative array
|
||||||
defined in a text file(called _sources file_) with the following syntax:
|
defined in a text file(called _sources file_) with the following syntax:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@ -68,7 +68,7 @@ backup-ssh-<YYYYMMDD>
|
|||||||
```
|
```
|
||||||
|
|
||||||
You can add as many entries as you want, just be sure to use the proper syntax. In particular,
|
You can add as many entries as you want, just be sure to use the proper syntax. In particular,
|
||||||
the _sources file_, **should not** includes:
|
the _sources file_, **should not** include:
|
||||||
- Spaces between the label and the equal sign;
|
- Spaces between the label and the equal sign;
|
||||||
- Empty lines;
|
- Empty lines;
|
||||||
- Comments.
|
- Comments.
|
||||||
@ -88,19 +88,26 @@ In the previous example, this would be:
|
|||||||
$> sudo ./backup.sh --backup sources.bk /home/john badpw1234
|
$> sudo ./backup.sh --backup sources.bk /home/john badpw1234
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also tell `backup.sh` to generate a SHA256 file containing the hash of each file using the `-c` option.
|
||||||
|
In the previous example, this would be:
|
||||||
|
```sh
|
||||||
|
$> sudo ./backup.sh --checksum --backup sources.bk /home/john badpw1234
|
||||||
|
```
|
||||||
|
|
||||||
The backup utility will begin to copy the files defined in the _sources file_:
|
The backup utility will begin to copy the files defined in the _sources file_:
|
||||||
```text
|
```text
|
||||||
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/marco/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
File name: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
||||||
|
Checksum file: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256
|
||||||
File size: 7336400696(6.9G)
|
File size: 7336400696(6.9G)
|
||||||
File hash: 0e75ca393117f389d9e8edfea7106d98
|
|
||||||
Elapsed time: 259 seconds.
|
Elapsed time: 259 seconds.
|
||||||
```
|
```
|
||||||
|
|
||||||
After that, you will find the final backup archive in `/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc`.
|
After that, you will find the backup archive and the checksum file in
|
||||||
|
`/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc` and `/home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256`, respectively.
|
||||||
|
|
||||||
You can also use `backup.sh` from a crontab rule:
|
You can also use `backup.sh` from a crontab rule:
|
||||||
```sh
|
```sh
|
||||||
@ -114,7 +121,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.
|
adopt this practice while using the `--extract` option to avoid password leaking in shell history.
|
||||||
|
|
||||||
### Backup extraction
|
### Backup extraction
|
||||||
`backup.sh` can also extract the encrypted backup archive using the following syntax:
|
`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:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
||||||
@ -128,16 +136,31 @@ For instance:
|
|||||||
$> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234
|
$> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a new folder called `backup.sh.tmp` in your local directory. Be sure to rename any directory
|
This will create a new folder called `backup.sh.tmp` in your local directory with the following content:
|
||||||
with that name to avoid collisions. From the previous example, you should have the following directories:
|
|
||||||
```text
|
```text
|
||||||
backup-nginx-<YYYYMMDD>
|
backup-nginx-<YYYYMMDD>
|
||||||
backup-ssh-<YYYYMMDD>
|
backup-ssh-<YYYYMMDD>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**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:
|
||||||
|
```sh
|
||||||
|
$> ./backup.sh --checksum --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> <CHECKSUM_ABSOLUTE_PATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
For instance:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$> ./backup.sh --checksum --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 $PWD/backup-<hostname>-<YYYYMMDD>.sha256
|
||||||
|
```
|
||||||
|
|
||||||
|
**note:** be sure to provide the ABSOLUTE PATH of the checksum file.
|
||||||
|
|
||||||
## How does backup.sh work?
|
## How does backup.sh work?
|
||||||
**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup and _gpg_ to encrypt it.
|
**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup, _gpg_ to encrypt it and
|
||||||
|
_sha256sum_ to verify it.
|
||||||
By default, rsync is being used with the following parameters:
|
By default, rsync is being used with the following parameters:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -153,10 +176,15 @@ That is:
|
|||||||
- 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.
|
||||||
|
|
||||||
|
If specified(`--checksum` option), `backup.sh` can also generate the checksum of each file of the backup.
|
||||||
|
To do so, it uses `sha256sum(1)` to compute the hash of every single file using the SHA256 hashing algorithm.
|
||||||
|
The checksum file contains nothing but the checksums of the files, no other information about the files stored
|
||||||
|
on the backup archive is exposed on the unencrypted checksum file. This may be an issue if you want plausible
|
||||||
|
deniability(see privacy section for more information).
|
||||||
|
|
||||||
|
|
||||||
After that the backup folder is being encrypted using gpg. By default, it is used with the following parameters:
|
After that the backup folder is being encrypted using gpg. By default, it is used with the following parameters:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$> gpg -a \
|
$> gpg -a \
|
||||||
--symmetric \
|
--symmetric \
|
||||||
@ -177,6 +205,18 @@ This command encrypts the backup using the AES-256 symmetric encryption algorith
|
|||||||
- `--output`: Specify output file;
|
- `--output`: Specify output file;
|
||||||
- `$INPUT`: Specify input file.
|
- `$INPUT`: Specify input file.
|
||||||
|
|
||||||
|
## Plausible Deniability
|
||||||
|
While `backup.sh` provide some pretty strong security against bruteforce attack(assuming a strong passphrase is being used)
|
||||||
|
it should by no means considered a viable tool against a cryptanalysis investigation. Many of the copying, compressing and
|
||||||
|
encrypting operations made by `backup.sh` during the backup process can be used to invalidate plausible deniability.
|
||||||
|
In particular, you should pay attention to the following details:
|
||||||
|
|
||||||
|
1. The `--checksum` option generates an **UNENCRYPTED** checksum file containing the _digests_ of **EVERY**
|
||||||
|
file in your backup archive. If your files are known to your adversary(e.g., a banned book), they may use a rainbow table attack to
|
||||||
|
determine whether you own a given file, voiding your plausible deniability;
|
||||||
|
2. Since `backup.sh` is essentially a set of shell commands, an eavesdropper could monitor the whole backup process to extract
|
||||||
|
the name of the files or the encryption password.
|
||||||
|
|
||||||
## Unit tests
|
## Unit tests
|
||||||
`backup.sh` provides some unit tests inside the `tests.sh` script. This script generates some dummy files inside the following
|
`backup.sh` provides some unit tests inside the `tests.sh` script. This script generates some dummy files inside the following
|
||||||
directories:
|
directories:
|
||||||
|
115
backup.sh
115
backup.sh
@ -13,19 +13,23 @@
|
|||||||
# logs=/var/log/
|
# logs=/var/log/
|
||||||
#
|
#
|
||||||
# After that you can launch the script with(sample usage):
|
# After that you can launch the script with(sample usage):
|
||||||
# sudo ./backup.sh --backup sources.bk /home/john badpw1234
|
# sudo ./backup.sh --checksum --backup sources.bk /home/john badpw1234
|
||||||
#
|
#
|
||||||
# This will create an encrypted tar archive(password: 'badpw1234')
|
# This will create an encrypted tar archive(password: 'badpw1234')
|
||||||
# in '/home/john/backup-<hostname>-<YYYMMDD>.tar.gz.enc' containing
|
# in '/home/john/backup-<hostname>-<YYYYMMDD>.tar.gz.enc' containing
|
||||||
# the following three directories:
|
# the following three directories:
|
||||||
# backup-nginx-<YYYYMMDD>
|
# backup-nginx-<YYYYMMDD>
|
||||||
# backup-ssh-<YYYYMMDD>
|
# backup-ssh-<YYYYMMDD>
|
||||||
# backup-logs-<YYYYMMDD>
|
# backup-logs-<YYYYMMDD>
|
||||||
#
|
#
|
||||||
# You can then decrypt it using:
|
# as well as a SHA256 file('/home/john/backup-<hostname>-<YYYYMMDD>.sha256')
|
||||||
# ./backup.sh --extract backup-<hostname>-<YYYMMDD>.tar.gz.enc badpw1234
|
# containing the file hashes of the backup.
|
||||||
#
|
#
|
||||||
# You can read the full guide on https://github.com/ice-bit/backup.sh
|
# You can then decrypt it using:
|
||||||
|
# ./backup.sh --checksum --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 $PWD/backup-<hostname>-<YYYYMMDD>.sha256
|
||||||
|
# which will also check the integrity of the backup(optional feature).
|
||||||
|
#
|
||||||
|
# You can read the full guide on https://github.com/ceticamarco/backup.sh
|
||||||
# or on the manual page.
|
# or on the manual page.
|
||||||
# Copyright (c) 2018,2023,2024 Marco Cetica <email@marcocetica.com>
|
# Copyright (c) 2018,2023,2024 Marco Cetica <email@marcocetica.com>
|
||||||
#
|
#
|
||||||
@ -47,29 +51,23 @@ checkdeps() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum() {
|
# $1: sources.bk file
|
||||||
BACKUP_SH_FILENAME="$1"
|
# $2: output path
|
||||||
BACKUP_SH_OS="$(uname | tr '[:lower:]' '[:upper:]')"
|
# $3: password
|
||||||
|
# $4: compute sha256(0,1)
|
||||||
if [ "$BACKUP_SH_OS" = "LINUX" ]; then
|
|
||||||
RES="$(md5sum "$BACKUP_SH_FILENAME" | awk '{print $1}')"
|
|
||||||
else
|
|
||||||
RES="$(md5 -q "$BACKUP_SH_FILENAME")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$RES"
|
|
||||||
}
|
|
||||||
|
|
||||||
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_COMMAND="rsync -aPhrq --delete"
|
BACKUP_SH_COMMAND="rsync -aPhrq --delete"
|
||||||
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"
|
||||||
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"
|
||||||
|
BACKUP_SH_CHECKSUM_FILE="$BACKUP_SH_OUTPATH/backup-$(uname -n)-$BACKUP_SH_DATE.sha256"
|
||||||
|
|
||||||
# Check for root permissions
|
# Check for root permissions
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
@ -96,6 +94,13 @@ make_backup() {
|
|||||||
mkdir -p "$BACKUP_SH_SUBDIR"
|
mkdir -p "$BACKUP_SH_SUBDIR"
|
||||||
|
|
||||||
printf "Copying %s(%s/%s)\n" "$label" "$BACKUP_SH_PROGRESS" "$BACKUP_SH_TOTAL"
|
printf "Copying %s(%s/%s)\n" "$label" "$BACKUP_SH_PROGRESS" "$BACKUP_SH_TOTAL"
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy files
|
||||||
$BACKUP_SH_COMMAND "$path" "$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 < "$BACKUP_SH_SOURCES_PATH"
|
done < "$BACKUP_SH_SOURCES_PATH"
|
||||||
@ -124,20 +129,24 @@ make_backup() {
|
|||||||
BACKUP_SH_END_TIME="$(date +%s)"
|
BACKUP_SH_END_TIME="$(date +%s)"
|
||||||
BACKUP_SH_FILE_SIZE="$(find "$BACKUP_SH_FILENAME" -exec ls -l {} \; | awk '{print $5}')"
|
BACKUP_SH_FILE_SIZE="$(find "$BACKUP_SH_FILENAME" -exec ls -l {} \; | awk '{print $5}')"
|
||||||
BACKUP_SH_FILE_SIZE_H="$(find "$BACKUP_SH_FILENAME" -exec ls -lh {} \; | awk '{print $5}')"
|
BACKUP_SH_FILE_SIZE_H="$(find "$BACKUP_SH_FILENAME" -exec ls -lh {} \; | awk '{print $5}')"
|
||||||
BACKUP_SH_HASH="$(checksum "$BACKUP_SH_FILENAME")"
|
|
||||||
|
|
||||||
echo "File name: $BACKUP_SH_FILENAME"
|
echo "File name: $BACKUP_SH_FILENAME"
|
||||||
|
[ "$BACKUP_SH_SHA256" -eq 1 ] && { echo "Checksum file: $BACKUP_SH_CHECKSUM_FILE"; }
|
||||||
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"
|
|
||||||
printf "Elapsed time: %s seconds.\n" "$((BACKUP_SH_END_TIME - BACKUP_SH_START_TIME))"
|
printf "Elapsed time: %s seconds.\n" "$((BACKUP_SH_END_TIME - BACKUP_SH_START_TIME))"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1: archive file
|
||||||
|
# $2: archive password
|
||||||
|
# $3: sha256 file(optional)
|
||||||
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"
|
||||||
|
|
||||||
# Decrypt the archive
|
# Decrypt the archive
|
||||||
gpg -a \
|
gpg -a \
|
||||||
|
--quiet \
|
||||||
--decrypt \
|
--decrypt \
|
||||||
--no-symkey-cache \
|
--no-symkey-cache \
|
||||||
--pinentry-mode=loopback \
|
--pinentry-mode=loopback \
|
||||||
@ -148,7 +157,20 @@ extract_backup() {
|
|||||||
# Extract archive
|
# Extract archive
|
||||||
tar -xzf backup.sh.tar.gz 1> /dev/null 2>&1
|
tar -xzf backup.sh.tar.gz 1> /dev/null 2>&1
|
||||||
|
|
||||||
# Remove temporary files
|
# 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
|
||||||
|
# Compute sha256 for current file
|
||||||
|
sha256="$(sha256sum "$file" | awk '{print $1}')"
|
||||||
|
# Check if checksum file contains hash
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf backup.sh.tar.gz
|
rm -rf backup.sh.tar.gz
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,13 +180,14 @@ helper() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
backup.sh - POSIX compliant, modular and lightweight backup utility.
|
backup.sh - POSIX compliant, modular and lightweight backup utility.
|
||||||
|
|
||||||
Syntax: $CLI_NAME [-b|-e|-h]
|
Syntax: $CLI_NAME [-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.
|
||||||
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
-c|--checksum Generate/check SHA256 of a backup.
|
||||||
-h|--help Show this helper.
|
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
||||||
|
-h|--help Show this helper.
|
||||||
|
|
||||||
General help with the software: https://github.com/ice-bit/backup.sh
|
General help with the software: https://github.com/ceticamarco/backup.sh
|
||||||
Report bugs to: Marco Cetica(<email@marcocetica.com>)
|
Report bugs to: Marco Cetica(<email@marcocetica.com>)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@ -179,6 +202,7 @@ main() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CHECKSUM_FLAG=0
|
||||||
# Parse CLI arguments
|
# Parse CLI arguments
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
@ -192,19 +216,46 @@ main() {
|
|||||||
echo "For more informatio, try --help"
|
echo "For more informatio, try --help"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
make_backup "$BACKUP_SH_SOURCES_PATH" "$BACKUP_SH_OUTPATH" "$BACKUP_SH_PASSWORD"
|
|
||||||
|
if [ "$CHECKSUM_FLAG" -eq 1 ]; then
|
||||||
|
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
|
||||||
|
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_PATH="$2"
|
BACKUP_SH_ARCHIVE_PATH="$2"
|
||||||
BACKUP_SH_ARCHIVE_PW="$3"
|
BACKUP_SH_ARCHIVE_PW="$3"
|
||||||
|
BACKUP_SH_SHA256_FILE="$4"
|
||||||
|
|
||||||
if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ]; then
|
if [ "$CHECKSUM_FLAG" -eq 1 ]; then
|
||||||
echo "Please, specify an encrypted archive and a password."
|
if [ -z "$BACKUP_SH_ARCHIVE_PATH" ] || [ -z "$BACKUP_SH_ARCHIVE_PW" ] || [ -z "$BACKUP_SH_SHA256_FILE" ]; then
|
||||||
echo "For more informatio, try --help"
|
echo "Please, specify an encrypted archive, a password and a SHA256 file."
|
||||||
exit 1
|
echo "For more informatio, try --help"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
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
|
||||||
fi
|
fi
|
||||||
extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW"
|
|
||||||
|
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"
|
||||||
|
else
|
||||||
|
extract_backup "$BACKUP_SH_ARCHIVE_PATH" "$BACKUP_SH_ARCHIVE_PW"
|
||||||
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
|
369
backup.sh.1
369
backup.sh.1
@ -1,265 +1,406 @@
|
|||||||
.\" Automatically generated by Pandoc 3.1.8
|
.\" Automatically generated by Pandoc 2.17.1.1
|
||||||
.\"
|
.\"
|
||||||
.TH "backup.sh" "1" "February 27, 2024" "Marco Cetica" "General Commands Manual"
|
.\" Define V font for inline verbatim, using C font in formats
|
||||||
|
.\" 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 3, 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 to save and encrypt your files.
|
utility to save and encrypt your files.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
Syntax: backup.sh [-b|-e|-h]
|
\f[C]
|
||||||
|
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.
|
||||||
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
-c|--checksum Generate/check SHA256 of a backup.
|
||||||
-h|--help Show this helper.
|
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
||||||
.EE
|
-h|--help Show this helper.
|
||||||
|
\f[R]
|
||||||
|
.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
|
||||||
VPS, small servers and workstations.
|
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],
|
||||||
\f[I]gpg\f[R] to copy, compress and encrypt the backup.
|
\f[I]sha256sum\f[R] and \f[I]gpg\f[R] to copy, compress, verify and
|
||||||
|
encrypt the backup.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
\f[B]backup.sh\f[R] supports two options: \f[I]backup creation\f[R] and
|
.PP
|
||||||
\f[I]backup extraction\f[R].
|
\f[B]backup.sh\f[R] supports three options: \f[B]backup creation\f[R],
|
||||||
The former requires root permissions, while the latter does not.
|
\f[B]backup extraction\f[R] and \f[B]checksum\f[R] to verify the
|
||||||
Let us see them in details:
|
integrity of a backup.
|
||||||
|
The first option requires root permissions, while the second one does
|
||||||
|
not.
|
||||||
|
The checksum option must be used in combination of one of the previous
|
||||||
|
options.
|
||||||
.SS Backup creation
|
.SS Backup creation
|
||||||
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
|
|
||||||
following syntax:
|
|
||||||
.IP
|
|
||||||
.EX
|
|
||||||
<LABEL>=<PATH>
|
|
||||||
.EE
|
|
||||||
.PP
|
.PP
|
||||||
Where \f[CR]<LABEL>\f[R] is the name of the backup and \f[CR]<PATH>\f[R]
|
To specify the directories to back up, \f[V]backup.sh\f[R] uses an
|
||||||
is its path.
|
associative array defined in a text file(called \f[I]sources file\f[R])
|
||||||
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:
|
|
||||||
.IP
|
|
||||||
.EX
|
|
||||||
nginx=/etc/nginx/
|
|
||||||
ssh=/etc/ssh/
|
|
||||||
.EE
|
|
||||||
.PP
|
|
||||||
\f[B]backup.sh\f[R] will create two folders inside the backup archive
|
|
||||||
with the following syntax:
|
with the following syntax:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
|
<LABEL>=<PATH>
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Where \f[V]<LABEL>\f[R] is the name of the backup and \f[V]<PATH>\f[R]
|
||||||
|
is its path.
|
||||||
|
For example, if you want to back up \f[V]/etc/nginx\f[R] and
|
||||||
|
\f[V]/etc/ssh\f[R], add the following entries to the \f[I]sources
|
||||||
|
file\f[R]:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
nginx=/etc/nginx/
|
||||||
|
ssh=/etc/ssh/
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
\f[V]backup.sh\f[R] will create two folders inside the backup archive
|
||||||
|
with the following syntax:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\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
|
||||||
.EX
|
.nf
|
||||||
|
\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 sources file, \f[I]should not\f[R] includes:
|
In particular, the \f[I]sources file\f[R], \f[B]should not\f[R] include:
|
||||||
.IP
|
- Spaces between the label and the equal sign;
|
||||||
.EX
|
.PD 0
|
||||||
- Spaces between the label and the equal sign;
|
.P
|
||||||
- Empty lines;
|
.PD
|
||||||
- Comments.
|
- Empty lines;
|
||||||
.EE
|
.PD 0
|
||||||
|
.P
|
||||||
|
.PD
|
||||||
|
- Comments.
|
||||||
.PP
|
.PP
|
||||||
You can find a sample sources file at \f[CR]sources.bk\f[R](or at
|
You can find a sample \f[I]sources file\f[R] at \f[V]sources.bk\f[R](or
|
||||||
\f[CR]/usr/local/etc/sources.bk\f[R]).
|
at \f[V]/usr/local/etc/sources.bk\f[R]).
|
||||||
.PP
|
.PP
|
||||||
After having defined the sources file, you can invoke
|
After having defined the \f[I]sources file\f[R], you can invoke
|
||||||
\f[B]backup.sh\f[R] using the following syntax:
|
\f[V]backup.sh\f[R] using the following syntax:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\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[CR]<SOURCES_FILE>\f[R] is the \f[I]sources file\f[R],
|
Where \f[V]<SOURCES_FILE>\f[R] is the \f[I]sources file\f[R],
|
||||||
\f[CR]<DEST>\f[R] is the absolute path of the output of the backup
|
\f[V]<DEST>\f[R] is the absolute path of the output of the backup
|
||||||
\f[I]without trailing slashes\f[R] and \f[CR]<ENCRYPTION_PASSWORD>\f[R]
|
\f[B]without trailing slashes\f[R] and \f[V]<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
|
||||||
.EX
|
.nf
|
||||||
|
\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
|
||||||
The backup utility will begin to copy the files defined in the sources
|
You can also tell \f[V]backup.sh\f[R] to generate a SHA256 file
|
||||||
file:
|
containing the hash of each file using the \f[V]-c\f[R] option.
|
||||||
|
In the previous example, this would be:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$> sudo ./backup.sh --checksum --backup sources.bk /home/john badpw1234
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
The backup utility will begin to copy the files defined in the
|
||||||
|
\f[I]sources file\f[R]:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\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/marco/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
File name: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
||||||
|
Checksum file: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256
|
||||||
File size: 7336400696(6.9G)
|
File size: 7336400696(6.9G)
|
||||||
File hash: 0e75ca393117f389d9e8edfea7106d98
|
|
||||||
Elapsed time: 259 seconds.
|
Elapsed time: 259 seconds.
|
||||||
.EE
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
After that, you will find the final backup archive in
|
After that, you will find the backup archive and the checksum file in
|
||||||
\f[CR]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc\f[R].
|
\f[V]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc\f[R] and
|
||||||
|
\f[V]/home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256\f[R], respectively.
|
||||||
.PP
|
.PP
|
||||||
You can also use \f[B]backup.sh\f[R] from a crontab rule:
|
You can also use \f[V]backup.sh\f[R] from a crontab rule:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
$> sudo crontab -e
|
$> sudo crontab -e
|
||||||
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
|
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
|
||||||
.EE
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
This will automatically run \f[B]backup.sh\f[R] every Saturday morning
|
This will automatically run \f[V]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[CR]--extract\f[R]
|
You can also adopt this practice while using the \f[V]--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
|
||||||
\f[B]backup.sh\f[R] can also extract the encrypted backup archive using
|
|
||||||
the following syntax:
|
|
||||||
.IP
|
|
||||||
.EX
|
|
||||||
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
|
||||||
.EE
|
|
||||||
.PP
|
.PP
|
||||||
Where \f[CR]<ENCRYPTED_ARCHIVE>\f[R] is the encrypted backup and
|
\f[B]backup.sh\f[R] can also be used to extract the encrypted backup as
|
||||||
\f[CR]<ARCHIVE_PASSWORD>\f[R] is the backup password.
|
well to verify the integrity of the backup data.
|
||||||
|
To do so, use the following commands:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Where \f[V]<ENCRYPTED_ARCHIVE>\f[R] is the encrypted backup and
|
||||||
|
\f[V]<ARCHIVE_PASSWORD>\f[R] is the backup password.
|
||||||
.PP
|
.PP
|
||||||
For instance:
|
For instance:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\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[CR]backup.sh.tmp\f[R] in your
|
This will create a new folder called \f[V]backup.sh.tmp\f[R] in your
|
||||||
local directory.
|
local directory with the following content:
|
||||||
Be sure to rename any directory with that name to avoid collisions.
|
|
||||||
From the previous example, you should have the following directories:
|
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
backup-nginx-<YYYYMMDD>
|
backup-nginx-<YYYYMMDD>
|
||||||
backup-ssh-<YYYYMMDD>
|
backup-ssh-<YYYYMMDD>
|
||||||
.EE
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
\f[B]note:\f[R]: be sure to rename any directory with that name to avoid
|
||||||
|
collisions.
|
||||||
|
.PP
|
||||||
|
Instead, if you also want to verify the integrity of the backup data,
|
||||||
|
use the following commands:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$> ./backup.sh --checksum --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> <CHECKSUM_ABSOLUTE_PATH>
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
For instance:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$> ./backup.sh --checksum --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 $PWD/backup-<hostname>-<YYYYMMDD>.sha256
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
\f[B]note:\f[R] be sure to provide the ABSOLUTE PATH of the checksum
|
||||||
|
file.
|
||||||
.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, \f[I]gpg\f[R] to encrypt it and
|
||||||
|
\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
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
$> rsync -aPhrq --delete
|
$> rsync -aPhrq --delete
|
||||||
.EE
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
That is:
|
That is:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\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
|
||||||
|
If specified(\f[V]--checksum\f[R] option), \f[V]backup.sh\f[R] can 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
|
||||||
|
single file using the SHA256 hashing algorithm.
|
||||||
|
The checksum file contains nothing but the checksums of the files, no
|
||||||
|
other information about the files stored on the backup archive is
|
||||||
|
exposed on the unencrypted checksum file.
|
||||||
|
This may be an issue if you want plausible deniability(see privacy
|
||||||
|
section for more information).
|
||||||
.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
|
||||||
.EX
|
.nf
|
||||||
|
\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 \[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]
|
||||||
.EE
|
\f[R]
|
||||||
|
.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[CR]--symmetric\f[R]: Use symmetric
|
Here is what each flag do: - \f[V]--symmetric\f[R]: Use symmetric
|
||||||
encryption;
|
encryption;
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]--cipher-algo=AES256\f[R]: Use AES256 algorithm;
|
- \f[V]--cipher-algo=AES256\f[R]: Use AES256 algorithm;
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]--no-symkey-cache\f[R]: Do not save password on GPG\[cq]s cache;
|
- \f[V]--no-symkey-cache\f[R]: Do not save password on GPG\[cq]s cache;
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]--pinentry-mode=loopback --batch\f[R]: Do not prompt the user;
|
- \f[V]--pinentry-mode=loopback --batch\f[R]: Do not prompt the user;
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]--passphrase-fd 3 3<< \[dq]$PASSWORD\[dq]\f[R]: Read password
|
- \f[V]--passphrase-fd 3 3<< \[dq]$PASSWORD\[dq]\f[R]: Read password
|
||||||
without revealing it on \f[CR]ps\f[R];
|
without revealing it on \f[V]ps\f[R];
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]--output\f[R]: Specify output file;
|
- \f[V]--output\f[R]: Specify output file;
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.PD
|
.PD
|
||||||
- \f[CR]$INPUT\f[R]: Specify input file.
|
- \f[V]$INPUT\f[R]: Specify input file.
|
||||||
|
.SS Plausible Deniability
|
||||||
|
.PP
|
||||||
|
While \f[V]backup.sh\f[R] provide some pretty strong security against
|
||||||
|
bruteforce attack(assuming a strong passphrase is being used) it should
|
||||||
|
by no means considered a viable tool against a cryptanalysis
|
||||||
|
investigation.
|
||||||
|
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
|
||||||
|
plausible deniability.
|
||||||
|
In particular, you should pay attention to the following details:
|
||||||
|
.IP "1." 3
|
||||||
|
The \f[V]--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
|
||||||
|
in your backup archive.
|
||||||
|
If your files are known to your adversary(e.g., a banned book), they may
|
||||||
|
use a rainbow table attack to determine whether you own a given file,
|
||||||
|
voiding your plausible deniability;
|
||||||
|
.PD 0
|
||||||
|
.P
|
||||||
|
.PD
|
||||||
|
.IP "2." 3
|
||||||
|
Since \f[V]backup.sh\f[R] is essentially a set of shell commands, an
|
||||||
|
eavesdropper could monitor the whole backup process to extract the name
|
||||||
|
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[CR]/etc/ssh\f[R], \f[CR]/var/www\f[R] and
|
Create a backup of \f[V]/etc/ssh\f[R], \f[V]/var/www\f[R] and
|
||||||
\f[CR]/var/log\f[R] inside the \f[CR]/tmp\f[R] directory using a
|
\f[V]/var/log\f[R] inside the \f[V]/tmp\f[R] directory using a password
|
||||||
password stored in \f[CR]/home/op1/.backup_pw\f[R]
|
stored in \f[V]/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
|
||||||
.EX
|
.nf
|
||||||
|
\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
|
||||||
.EE
|
\f[R]
|
||||||
|
.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:
|
an environment variable:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\f[C]
|
||||||
$> ENC_KEY=$(cat /home/op1/.backup_pw)
|
$> ENC_KEY=$(cat /home/op1/.backup_pw)
|
||||||
.EE
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Finally, we can start the backup process with:
|
Finally, we can start the backup process with:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.nf
|
||||||
|
\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
|
||||||
.EX
|
.nf
|
||||||
|
\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 in
|
||||||
\f[CR]/home/john/.pw\f[R]
|
\f[V]/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
|
||||||
.EX
|
.nf
|
||||||
|
\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] 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
|
||||||
|
126
man.md
126
man.md
@ -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: February 27, 2024
|
date: April 3, 2024
|
||||||
---
|
---
|
||||||
|
|
||||||
# NAME
|
# NAME
|
||||||
@ -11,102 +11,107 @@ date: February 27, 2024
|
|||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
```
|
```
|
||||||
Syntax: backup.sh [-b|-e|-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.
|
||||||
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
-c|--checksum Generate/check SHA256 of a backup.
|
||||||
-h|--help Show this helper.
|
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
|
||||||
|
-h|--help Show this helper.
|
||||||
```
|
```
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
**backup.sh** is a POSIX compliant, modular and lightweight backup utility to save and encrypt your files.
|
**backup.sh** is a POSIX compliant, modular and lightweight backup utility to save and encrypt your files.
|
||||||
This tool is intended to be used on small scale UNIX environment such as VPS, small servers and workstations.
|
This tool is intended to be used on small scale UNIX environment such as VPS, small servers and workstations.
|
||||||
**backup.sh** uses _rsync_, _tar_ and _gpg_ to copy, compress and encrypt the backup.
|
**backup.sh** uses _rsync_, _tar_, _sha256sum_ and _gpg_ to copy, compress, verify and encrypt the backup.
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
**backup.sh** supports two options: _backup creation_ and _backup extraction_.
|
**backup.sh** supports three options: **backup creation**, **backup extraction** and **checksum** to verify the
|
||||||
The former requires root permissions, while the latter does not. Let us see them in details:
|
integrity of a backup. The first option requires
|
||||||
|
root permissions, while the second one does not. The checksum option must be used in combination of one of the previous options.
|
||||||
|
|
||||||
## Backup creation
|
## Backup creation
|
||||||
To specify the directories to backup, **backup.sh** uses an associative array defined in a text file(called sources file)
|
To specify the directories to back up, `backup.sh` uses an associative array
|
||||||
with the following syntax:
|
defined in a text file(called _sources file_) with the following syntax:
|
||||||
|
|
||||||
```
|
```
|
||||||
<LABEL>=<PATH>
|
<LABEL>=<PATH>
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `<LABEL>` is the name of the backup and `<PATH>` is its path.
|
Where `<LABEL>` is the name of the backup and `<PATH>` is its path. For example,
|
||||||
For example, if you want to back up _/etc/nginx_ and _/etc/ssh_, add the following entries to the sources file:
|
if you want to back up `/etc/nginx` and `/etc/ssh`, add the following entries to the _sources file_:
|
||||||
|
|
||||||
```
|
```
|
||||||
nginx=/etc/nginx/
|
nginx=/etc/nginx/
|
||||||
ssh=/etc/ssh/
|
ssh=/etc/ssh/
|
||||||
```
|
```
|
||||||
|
|
||||||
**backup.sh** will create two folders inside the backup archive with the following syntax:
|
`backup.sh` will create two folders inside the backup archive with the following syntax:
|
||||||
|
|
||||||
```
|
```
|
||||||
backup-<LABEL>-<YYYYMMDD>
|
backup-<LABEL>-<YYYYMMDD>
|
||||||
```
|
```
|
||||||
|
|
||||||
In the previous example, this would be:
|
In the previous example, this would be:
|
||||||
|
|
||||||
```
|
```
|
||||||
backup-nginx-<YYYYMMDD>
|
backup-nginx-<YYYYMMDD>
|
||||||
backup-ssh-<YYYYMMDD>
|
backup-ssh-<YYYYMMDD>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can add as many entries as you want, just be sure to use the proper syntax.
|
You can add as many entries as you want, just be sure to use the proper syntax. In particular,
|
||||||
In particular, the sources file, _should not_ includes:
|
the _sources file_, **should not** include:
|
||||||
|
- Spaces between the label and the equal sign;
|
||||||
|
- Empty lines;
|
||||||
|
- Comments.
|
||||||
|
|
||||||
- Spaces between the label and the equal sign;
|
You can find a sample _sources file_ at `sources.bk`(or at `/usr/local/etc/sources.bk`).
|
||||||
- Empty lines;
|
|
||||||
- Comments.
|
|
||||||
|
|
||||||
You can find a sample sources file at `sources.bk`(or at `/usr/local/etc/sources.bk`).
|
After having defined the _sources file_, you can invoke `backup.sh` using the following syntax:
|
||||||
|
|
||||||
After having defined the sources file, you can invoke **backup.sh** using the following syntax:
|
|
||||||
```
|
```
|
||||||
$> sudo ./backup.sh --backup <SOURCES_FILE> <DEST> <ENCRYPTION_PASSWORD>
|
$> sudo ./backup.sh --backup <SOURCES_FILE> <DEST> <ENCRYPTION_PASSWORD>
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `<SOURCES_FILE>` is the _sources file_, `<DEST>` is the absolute path of the output of the backup _without trailing slashes_
|
Where `<SOURCES_FILE>` is the _sources file_, `<DEST>` is the absolute path of the output of the backup
|
||||||
and `<ENCRYPTION_PASSWORD>` is the password to encrypt the compressed archive.
|
**without trailing slashes** and `<ENCRYPTION_PASSWORD>` is the password to encrypt the compressed archive.
|
||||||
|
|
||||||
In the previous example, this would be:
|
In the previous example, this would be:
|
||||||
|
|
||||||
```
|
```
|
||||||
$> sudo ./backup.sh --backup sources.bk /home/john badpw1234
|
$> sudo ./backup.sh --backup sources.bk /home/john badpw1234
|
||||||
```
|
```
|
||||||
|
|
||||||
The backup utility will begin to copy the files defined in the sources file:
|
You can also tell `backup.sh` to generate a SHA256 file containing the hash of each file using the `-c` option.
|
||||||
|
In the previous example, this would be:
|
||||||
|
```
|
||||||
|
$> sudo ./backup.sh --checksum --backup sources.bk /home/john badpw1234
|
||||||
|
```
|
||||||
|
|
||||||
|
The backup utility will begin to copy the files defined in the _sources file_:
|
||||||
```
|
```
|
||||||
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/marco/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
File name: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc
|
||||||
|
Checksum file: /home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256
|
||||||
File size: 7336400696(6.9G)
|
File size: 7336400696(6.9G)
|
||||||
File hash: 0e75ca393117f389d9e8edfea7106d98
|
|
||||||
Elapsed time: 259 seconds.
|
Elapsed time: 259 seconds.
|
||||||
```
|
```
|
||||||
|
|
||||||
After that, you will find the final backup archive in `/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc`.
|
After that, you will find the backup archive and the checksum file in
|
||||||
|
`/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc` and `/home/john/backup-<HOSTNAME>-<YYYYMMDD>.sha256`, respectively.
|
||||||
You can also use **backup.sh** from a crontab rule:
|
|
||||||
|
|
||||||
|
You can also use `backup.sh` from a crontab rule:
|
||||||
```
|
```
|
||||||
$> sudo crontab -e
|
$> 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) 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. In the example above, the encryption
|
||||||
In the example above, the encryption key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs.
|
key is stored in a local file(with fixed permissions) to avoid password leaking in crontab logs. You can also
|
||||||
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.
|
||||||
|
|
||||||
## Backup extraction
|
## Backup extraction
|
||||||
**backup.sh** can also extract the encrypted backup archive using the following syntax:
|
**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 --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
$> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
||||||
@ -115,20 +120,36 @@ $> ./backup.sh --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD>
|
|||||||
Where `<ENCRYPTED_ARCHIVE>` is the encrypted backup and `<ARCHIVE_PASSWORD>` is the backup password.
|
Where `<ENCRYPTED_ARCHIVE>` is the encrypted backup and `<ARCHIVE_PASSWORD>` is the backup password.
|
||||||
|
|
||||||
For instance:
|
For instance:
|
||||||
|
|
||||||
```
|
```
|
||||||
$> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234
|
$> ./backup.sh --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a new folder called `backup.sh.tmp` in your local directory.
|
This will create a new folder called `backup.sh.tmp` in your local directory with the following content:
|
||||||
Be sure to rename any directory with that name to avoid collisions. From the previous example, you should have the following directories:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
backup-nginx-<YYYYMMDD>
|
backup-nginx-<YYYYMMDD>
|
||||||
backup-ssh-<YYYYMMDD>
|
backup-ssh-<YYYYMMDD>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**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:
|
||||||
|
```
|
||||||
|
$> ./backup.sh --checksum --extract <ENCRYPTED_ARCHIVE> <ARCHIVE_PASSWORD> <CHECKSUM_ABSOLUTE_PATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
For instance:
|
||||||
|
|
||||||
|
```
|
||||||
|
$> ./backup.sh --checksum --extract backup-<hostname>-<YYYYMMDD>.tar.gz.enc badpw1234 $PWD/backup-<hostname>-<YYYYMMDD>.sha256
|
||||||
|
```
|
||||||
|
|
||||||
|
**note:** be sure to provide the ABSOLUTE PATH of the checksum file.
|
||||||
|
|
||||||
## How does backup.sh work?
|
## How does backup.sh work?
|
||||||
**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup and _gpg_ to encrypt it.
|
**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup, _gpg_ to encrypt it and
|
||||||
|
_sha256sum_ to verify it.
|
||||||
By default, rsync is being used with the following parameters:
|
By default, rsync is being used with the following parameters:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -144,17 +165,22 @@ That is:
|
|||||||
- 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.
|
||||||
|
|
||||||
|
If specified(`--checksum` option), `backup.sh` can also generate the checksum of each file of the backup.
|
||||||
|
To do so, it uses `sha256sum(1)` to compute the hash of every single file using the SHA256 hashing algorithm.
|
||||||
|
The checksum file contains nothing but the checksums of the files, no other information about the files stored
|
||||||
|
on the backup archive is exposed on the unencrypted checksum file. This may be an issue if you want plausible
|
||||||
|
deniability(see privacy section for more information).
|
||||||
|
|
||||||
|
|
||||||
After that the backup folder is being encrypted using gpg. By default, it is used with the following parameters:
|
After that the backup folder is being encrypted using gpg. By default, it is used with the following parameters:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$> gpg -a \
|
$> gpg -a \
|
||||||
--symmetric \
|
--symmetric \
|
||||||
--cipher-algo=AES256 \
|
--cipher-algo=AES256 \
|
||||||
--no-symkey-cache \
|
--no-symkey-cache \
|
||||||
--pinentry-mode=loopback \
|
--pinentry-mode=loopback \
|
||||||
--batch --passphrase-fd "$PASSWORD" \
|
--batch --passphrase "$PASSWORD" \
|
||||||
--output "$OUTPUT" \
|
--output "$OUTPUT" \
|
||||||
"$INPUT"
|
"$INPUT"
|
||||||
```
|
```
|
||||||
@ -168,6 +194,19 @@ This command encrypts the backup using the AES-256 symmetric encryption algorith
|
|||||||
- `--output`: Specify output file;
|
- `--output`: Specify output file;
|
||||||
- `$INPUT`: Specify input file.
|
- `$INPUT`: Specify input file.
|
||||||
|
|
||||||
|
## Plausible Deniability
|
||||||
|
While `backup.sh` provide some pretty strong security against bruteforce attack(assuming a strong passphrase is being used)
|
||||||
|
it should by no means considered a viable tool against a cryptanalysis investigation. Many of the copying, compressing and
|
||||||
|
encrypting operations made by `backup.sh` during the backup process can be used to invalidate plausible deniability.
|
||||||
|
In particular, you should pay attention to the following details:
|
||||||
|
|
||||||
|
1. The `--checksum` option generates an **UNENCRYPTED** checksum file containing the _digests_ of **EVERY**
|
||||||
|
file in your backup archive. If your files are known to your adversary(e.g., a banned book), they may use a rainbow table attack to
|
||||||
|
determine whether you own a given file, voiding your plausible deniability;
|
||||||
|
2. Since `backup.sh` is essentially a set of shell commands, an eavesdropper could monitor the whole backup process to extract
|
||||||
|
the name of the files or the encryption password.
|
||||||
|
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
Below there are some examples that demonstrate **backup.sh**'s usage.
|
Below there are some examples that demonstrate **backup.sh**'s usage.
|
||||||
|
|
||||||
@ -183,7 +222,7 @@ web_root=/var/www
|
|||||||
logs=/var/log
|
logs=/var/log
|
||||||
```
|
```
|
||||||
|
|
||||||
After that we can load our encryption key from the specified file inside a environment variable:
|
After that we can load our encryption key from the specified file inside an environment variable:
|
||||||
|
|
||||||
```
|
```
|
||||||
$> ENC_KEY=$(cat /home/op1/.backup_pw)
|
$> ENC_KEY=$(cat /home/op1/.backup_pw)
|
||||||
@ -196,7 +235,6 @@ $> sudo backup.sh --backup sources.bk /tmp $ENC_KEY
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2. Extract the content of a backup made on 2023-03-14 with the password 'Ax98f!'
|
2. Extract the content of a backup made on 2023-03-14 with the password 'Ax98f!'
|
||||||
|
|
||||||
To do this, we can simply issue the following command:
|
To do this, we can simply issue the following command:
|
||||||
|
8
tests.sh
8
tests.sh
@ -5,6 +5,8 @@
|
|||||||
# 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.
|
||||||
@ -49,11 +51,13 @@ create_files() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execute_backup() {
|
execute_backup() {
|
||||||
./backup.sh -b sources.bk "$PWD" badpw
|
./backup.sh -c -b sources.bk "$PWD" badpw
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_backup() {
|
extract_backup() {
|
||||||
./backup.sh -e "$PWD"/backup-*-*.tar.gz.enc badpw
|
host="$(uname -n)"
|
||||||
|
date="$(date +'%Y%m%d')"
|
||||||
|
./backup.sh -c -e "$PWD"/backup-"$host"-"$date".tar.gz.enc badpw "$PWD"/backup-"$host"-"$date".sha256
|
||||||
}
|
}
|
||||||
|
|
||||||
test_backup() {
|
test_backup() {
|
||||||
|
Loading…
Reference in New Issue
Block a user