diff --git a/README.md b/README.md index 19bec20..ac216a9 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,12 @@ `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 workstations. `backup.sh` uses [rsync](https://linux.die.net/man/1/rsync), [tar](https://linux.die.net/man/1/tar) -and [openssl](https://linux.die.net/man/1/openssl) to copy, compress and encrypt the backup. +and [gpg](https://linux.die.net/man/1/gpg) to copy, compress and encrypt the backup. -While `backup.sh` should work in any POSIX compliant environment, the official supported operating systems are: +While `backup.sh` should work in any POSIX compliant environment, +`backup.sh` should work in any POSIX compliant environment, and it's successfully being used on - GNU/Linux; +- OpenBSD - FreeBSD; - Apple MacOS. @@ -22,7 +24,7 @@ you can issue `sudo make uninstall`. At this point you still need to install the following dependencies: - `rsync` - `tar` -- `openssl` +- `gpg` ## Usage To show the available options, you can run `backup.sh --help`, which will print out the following message: @@ -91,11 +93,15 @@ The backup utility will begin to copy the files defined in the _sources file_: ```text Copying nginx(1/2) Copying ssh(2/2) -Compressing and encrypting backup... -Elapsed time: 10 seconds. +Compressing backup... +Encrypting backup... +File name: /home/marco/backup--.tar.gz.enc +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--.tar.gz.enc`. +After that, you will find the final backup archive in `/home/john/backup--.tar.gz.enc`. You can also use `backup.sh` from a crontab rule: ```sh @@ -120,7 +126,7 @@ Where `` is the encrypted backup and `` is For instance: ```sh -$> ./backup.sh --extract backup--.tar.gz.enc badpw1234 +$> ./backup.sh --extract backup--.tar.gz.enc badpw1234 ``` This will create a new folder called `backup.sh.tmp` in your local directory. Be sure to rename any directory @@ -131,44 +137,46 @@ backup-ssh- ``` -## How does `backup.sh` work? -`backup.sh` uses **rsync** to copy the files, **tar** to compress the backup and **openssl** -to encrypt it. By default, rsync is being used with the following parameters: -```sh +## How does backup.sh work? +**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup and _gpg_ to encrypt it. +By default, rsync is being used with the following parameters: + +``` $> rsync -aPhrq --delete ``` That is: -- `-a`: **archive mode**: rsync copies files recursively while preserving as much metadata -as possible; -- `-P`: **progress/partial**, this allows rsync to resume interrupted transfers and to -shows progress information; -- `-h`: **human readable output**: rsync shows output numbers in a more readable way; -- `-r`: **recursive mode**: forces rsync to copy directories and their content; -- `-q`: **quiet mode**: reduces the amount of information rsync produces; -- `--delete`: **delete mode**: forces rsync to delete any extraneous files at the -destination dir. + - 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; + - h: human readable output, rsync shows output numbers in a more readable way; + - r: recursive mode: forces rsync to copy directories and their content; + - q: quiet mode: reduces the amount of information rsync produces; + - delete: delete mode: forces rsync to delete any extraneous files at the destination dir. -After that the backup folder is being encrypred using openssl. By default, it is used -with the following parameters: -```sh -$> openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -k "$PASSWORD" > file.tar.gz.enc +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 3 3<<< "$PASSWORD" \ + --output "$OUTPUT" \ + "$INPUT" ``` -This command encrypts the backup using the AES-256-CBC symmetric encryption algorithm with a 256bit -key. Here is what each option means: -- `enc`: **encrypt mode**: tell openssl to use encryption functionality; -- `-aes-256-cbc`: **encryption algorithm**: this option tells openssl which encryption algorithm to use; -- `-md sha512`: **hashing algorithm**: this option tells openssl which hashing algorithm to use for key derivation, -i.e., converting the text-based password(`$PASSWORD`) into an encryption key; -- `-pbkdf2`: **key deriving algorithm**: this option tells openssl which key deriving algorithm to use. In this case -we use the _password-based key derivation function 2_ algorithm; -- `-iter 100000`: **number of iterations**: this options tells openssl the number of iteration to use for the key derivation -function; -- `-salt`: **enable salting**: this option tells openssl to add a random salt to the key derivation process in order to -avoid rainbow table based attacks. +This command encrypts the backup using the AES-256 symmetric encryption algorithm with a 256bit key. Here is what each flag do: + - `--symmetric`: Use symmetric encryption; + - `--cipher-algo=AES256`: Use AES256 algorithm; + - `--no-symkey-cache`: Do not save password on GPG's cache; + - `--pinentry-mode=loopback --batch`: Do not prompt the user; + - `--passphrase-fd 3 3<< "$PASSWORD"`: Read password without revealing it on `ps`; + - `--output`: Specify output file; + - `$INPUT`: Specify input file. ## Unit tests `backup.sh` provides some unit tests inside the `tests.sh` script. This script generates some dummy files inside the following diff --git a/backup.sh b/backup.sh index e70decb..d257c63 100755 --- a/backup.sh +++ b/backup.sh @@ -34,8 +34,10 @@ set -e # Check if dependencies are installed missing_dep=0 -for dep in rsync tar openssl ; do - if ! command -v $dep > /dev/null 2>&1; then +deps=("rsync" "tar" "gpg") + +for dep in "${deps[@]}"; do + if ! command -v "$dep" > /dev/null 2>&1; then echo "Cannot find '$dep', please install it." missing_dep=1 fi @@ -93,14 +95,25 @@ make_backup() { BACKUP_SH_PROGRESS=$((BACKUP_SH_PROGRESS+1)) done - # Compress and encrypt backup directory - echo "Compressing and encrypting backup..." - tar -cz -C "$BACKUP_SH_OUTPATH" $BACKUP_SH_FOLDER | \ - openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -k "$BACKUP_SH_PASS" \ - > "$BACKUP_SH_FILENAME" + # Compress backup directory + echo "Compressing backup..." + tar -czf "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" \ + -C "$BACKUP_SH_OUTPUT/" . > /dev/null 2>&1 + + # Encrypt backup directory + echo "Encrypting backup..." + gpg -a \ + --symmetric \ + --cipher-algo=AES256 \ + --no-symkey-cache \ + --pinentry-mode=loopback \ + --batch --passphrase-fd 3 3<<< "$BACKUP_SH_PASS" \ + --output "$BACKUP_SH_FILENAME" \ + "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" > /dev/null 2>&1 # Remove temporary files rm -rf "$BACKUP_SH_OUTPUT" + rm -rf "$BACKUP_SH_OUTPATH/backup.sh.tar.gz" # Print file name, file size, file hash and elapsed time, BACKUP_SH_END_TIME="$(date +%s)" @@ -118,10 +131,20 @@ extract_backup() { BACKUP_SH_ARCHIVE_PATH="$1" BACKUP_SH_ARCHIVE_PW="$2" - (openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -d \ - -in "$BACKUP_SH_ARCHIVE_PATH" \ - -k "$BACKUP_SH_ARCHIVE_PW" | tar xvz) > /dev/null 2>&1 \ - || (echo "Unable to extract backup." && exit 1) + # Decrypt the archive + gpg -a \ + --decrypt \ + --no-symkey-cache \ + --pinentry-mode=loopback \ + --batch --passphrase-fd 3 3<<<"$BACKUP_SH_ARCHIVE_PW" \ + --output backup.sh.tar.gz \ + "$BACKUP_SH_ARCHIVE_PATH" + + # Extract archive + tar -xzf backup.sh.tar.gz 1> /dev/null 2>&1 + + # Remove temporary files + rm -rf backup.sh.tar.gz } helper() { diff --git a/man.md b/man.md index 9419302..c162cb7 100644 --- a/man.md +++ b/man.md @@ -3,11 +3,11 @@ title: backup.sh section: 1 header: General Commands Manual footer: Marco Cetica -date: March 14, 2023 +date: October 10, 2023 --- # NAME -**backup.sh** is a POSIX compliant, modular and lightweight backup utility to save and encrypt your files. +**backup.sh** - POSIX compliant, modular and lightweight backup utility to save and encrypt your files. # SYNOPSIS ``` @@ -21,7 +21,7 @@ options: # 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 _openssl_ to copy, compress and encrypt the backup. +**backup.sh** uses _rsync_, _tar_ and _gpg_ to copy, compress and encrypt the backup. # OPTIONS **backup.sh** supports two options: _backup creation_ and _backup extraction_. @@ -88,7 +88,7 @@ Compressing and encrypting backup... Elapsed time: 10 seconds. ``` -After that, you will find the final backup archive in `/home/john/backup--.tar.gz.enc`. +After that, you will find the final backup archive in `/home/john/backup--.tar.gz.enc`. You can also use **backup.sh** from a crontab rule: @@ -112,7 +112,7 @@ Where `` is the encrypted backup and `` is For instance: ``` -$> ./backup.sh --extract backup--.tar.gz.enc badpw1234 +$> ./backup.sh --extract backup--.tar.gz.enc badpw1234 ``` This will create a new folder called `backup.sh.tmp` in your local directory. @@ -124,7 +124,7 @@ backup-ssh- ``` ## How does backup.sh work? -**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup and _openssl_ to encrypt it. +**backup.sh** uses _rsync_ to copy the files, _tar_ to compress the backup and _gpg_ to encrypt it. By default, rsync is being used with the following parameters: ``` @@ -141,28 +141,31 @@ That is: - delete: delete mode: forces rsync to delete any extraneous files at the destination dir. -After that the backup folder is being encrypred using openssl. 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: ``` -$> openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -k "$PASSWORD" > file.tar.gz.enc +$> gpg -a \ + --symmetric \ + --cipher-algo=AES256 \ + --no-symkey-cache \ + --pinentry-mode=loopback \ + --batch --passphrase-fd 3 3<<< "$PASSWORD" \ + --output "$OUTPUT" \ + "$INPUT" ``` -This command encrypts the backup using the AES-256-CBC symmetric encryption algorithm with a 256bit key. Here is what each option means: - - - enc: encrypt mode: tell openssl to use encryption functionality; - - aes-256-cbc: encryption algorithm: this option tells openssl which encryption algorithm to use; - - md sh512: hashing algorithm: this option tells openssl which hashing algorithm to use for key derivation, - i.e., converting the text-based password(`$PASSWORD`) into an encryption key; - - pbkdf2: key deriving algorithm: this option tells openssl which key deriving algorithm to use. In this case - we use the _password-based key derivation function 2_ algorithm; - - iter 100000: number of iterations: this options tells openssl the number of iteration to use for the key derivation - function; - - salt: enable salting: this option tells openssl to add a random salt to the key derivation process in order to - avoid rainbow table based attacks. +This command encrypts the backup using the AES-256 symmetric encryption algorithm with a 256bit key. Here is what each flag do: + - `--symmetric`: Use symmetric encryption; + - `--cipher-algo=AES256`: Use AES256 algorithm; + - `--no-symkey-cache`: Do not save password on GPG's cache; + - `--pinentry-mode=loopback --batch`: Do not prompt the user; + - `--passphrase-fd 3 3<< "$PASSWORD"`: Read password without revealing it on `ps`; + - `--output`: Specify output file; + - `$INPUT`: Specify input file. # EXAMPLES -Below there are some examples that demostrate **backup.sh**'s usage. +Below there are some examples that demonstrate **backup.sh**'s usage. 1. Create a backup of `/etc/ssh`, `/var/www` and `/var/log` inside the `/tmp` directory using a password stored in `/home/op1/.backup_pw`