Added integrity check option(--checksum)

This commit is contained in:
2024-04-03 08:55:06 +02:00
parent 39a15d2f2a
commit baa6f68706
5 changed files with 490 additions and 216 deletions

126
man.md
View File

@@ -3,7 +3,7 @@ title: backup.sh
section: 1
header: General Commands Manual
footer: Marco Cetica
date: February 27, 2024
date: April 3, 2024
---
# NAME
@@ -11,102 +11,107 @@ date: February 27, 2024
# SYNOPSIS
```
Syntax: backup.sh [-b|-e|-h]
Syntax: ./backup.sh [-b|-c|-e|-h]
options:
-b|--backup SOURCES DEST PASS Backup folders from SOURCES file.
-e|--extract ARCHIVE PASS Extract ARCHIVE using PASS.
-h|--help Show this helper.
-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.
-h|--help Show this helper.
```
# DESCRIPTION
**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.
**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
**backup.sh** supports two options: _backup creation_ and _backup extraction_.
The former requires root permissions, while the latter does not. Let us see them in details:
**backup.sh** supports three options: **backup creation**, **backup extraction** and **checksum** to verify the
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
To specify the directories to backup, **backup.sh** uses an associative array defined in a text file(called sources file)
with the following syntax:
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:
```
<LABEL>=<PATH>
```
Where `<LABEL>` is the name of the backup and `<PATH>` is its path.
For example, if you want to back up _/etc/nginx_ and _/etc/ssh_, add the following entries to the sources file:
Where `<LABEL>` is the name of the backup and `<PATH>` is its path. For example,
if you want to back up `/etc/nginx` and `/etc/ssh`, add the following entries to the _sources file_:
```
nginx=/etc/nginx/
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>
```
In the previous example, this would be:
```
backup-nginx-<YYYYMMDD>
backup-ssh-<YYYYMMDD>
```
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:
You can add as many entries as you want, just be sure to use the proper syntax. In particular,
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;
- Empty lines;
- Comments.
You can find a sample _sources file_ at `sources.bk`(or at `/usr/local/etc/sources.bk`).
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>
```
Where `<SOURCES_FILE>` is the _sources file_, `<DEST>` is the absolute path of the output of the backup _without trailing slashes_
and `<ENCRYPTION_PASSWORD>` is the password to encrypt the compressed archive.
Where `<SOURCES_FILE>` is the _sources file_, `<DEST>` is the absolute path of the output of the backup
**without trailing slashes** and `<ENCRYPTION_PASSWORD>` is the password to encrypt the compressed archive.
In the previous example, this would be:
```
$> 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 ssh(2/2)
Compressing 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 hash: 0e75ca393117f389d9e8edfea7106d98
Elapsed time: 259 seconds.
```
After that, you will find the final backup archive in `/home/john/backup-<HOSTNAME>-<YYYYMMDD>.tar.gz.enc`.
You can also use **backup.sh** from a crontab rule:
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:
```
$> 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
```
This will automatically run **backup.sh** every Saturday morning at 03:30 AM.
In the example above, the encryption 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.
This will automatically run `backup.sh` every Saturday morning at 03:30 AM. In the example above, the encryption
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.
## 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>
@@ -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.
For instance:
```
$> ./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 with that name to avoid collisions. From the previous example, you should have the following directories:
This will create a new folder called `backup.sh.tmp` in your local directory with the following content:
```
backup-nginx-<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?
**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:
```
@@ -144,17 +165,22 @@ That is:
- q: quiet mode: reduces the amount of information rsync produces;
- 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:
```
$> gpg -a \
--symmetric \
--cipher-algo=AES256 \
--no-symkey-cache \
--pinentry-mode=loopback \
--batch --passphrase-fd "$PASSWORD" \
--batch --passphrase "$PASSWORD" \
--output "$OUTPUT" \
"$INPUT"
```
@@ -168,6 +194,19 @@ This command encrypts the backup using the AES-256 symmetric encryption algorith
- `--output`: Specify output 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
Below there are some examples that demonstrate **backup.sh**'s usage.
@@ -183,7 +222,7 @@ web_root=/var/www
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)
@@ -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!'
To do this, we can simply issue the following command: