Skip to main content
1 of 3
Vlastimil Burián
  • 1.8k
  • 2
  • 11
  • 28

Long-term archiving + encrypting shell script [Linux / Cygwin]

Yesterday, I very quickly, in an hour, wrote the very first version of my Long-term archiving + encrypting shell script.

I am aware it may have too many flaws, but none of them really prevent it from normal operation, so before I take another step and restructure it with printf and better error reporting, structure, exit codes, etc. I would like you to have a look first.

What is does:

  1. It archives a given directory into a tarball.

  2. It compresses (with maximum effort) that tarball using xz.

  3. It encrypts that xz archive using openssl and AES-256.

  4. It creates and checks the created SHA-512 sum file.

  5. It then decrypts the created file to a temporary file.

  6. Finally, it compares the decrypted file with the original xz archive.

I am prepared to waste time and effort in order to be 100% sure before burning my precious data to Blu-ray M-disc.

I know I should not have to do steps 5 and 6 just because there is almost a 0% chance for the data to get corrupted in the process. But since I have a rather large NVMe SSD drive, and relatively fast CPU, it should not be so shocking that I wrote it with motto better safe than sorry.


#!/bin/sh

[ -z "$1" ] && echo "You need to give me one directory!" && exit 1

[ ! -d "$1" ] && echo "This is not a directory!" && exit 1

[ ! -w "$PWD" ] && echo "The current directory is not writable by you!" && exit 1

dir=$(basename "$1")
today=$(date +%Y-%m-%d)

backupdir="${dir}_${today}"
# backupdir="${dir}"

backupfile="${backupdir}.tar"

bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red="$bold$red"
bold_yellow="$bold$yellow"

echo
echo "${bold_yellow}1/6: TAR is archiving your directory '${bold_red}$dir${bold_yellow}' into '${bold_red}$backupfile${bold_yellow}'${nocolor}"
echo

if ! tar -cf "$backupfile" "$1" --totals
then
    echo "TAR failed to archive your directory"
    exit 1
fi

echo
echo "${bold_yellow}2/6: XZ is compressing your '${bold_red}$backupfile${bold_yellow}' into '${bold_red}$backupfile.xz${bold_yellow}'${nocolor}"
echo

if ! xz --format=xz --check=sha256 -9 --threads=8 --keep --verbose --verbose --extreme "$backupfile"
then
    echo "XZ failed to compress your backup file"
    exit 1
fi

echo
echo "${bold_yellow}3/6: OpenSSL is encrypting your '${bold_red}$backupfile.xz${bold_yellow}' into '${bold_red}$backupfile.xz.enc${bold_yellow}'${nocolor}"
echo

if ! pv -W "$backupfile.xz" | openssl enc -aes-256-cbc -md sha256 -salt -out "$backupfile.xz.enc" -pass file:/home/vlastimil/.blablablabla 2> /dev/null
then
    echo "OpenSSL failed to encrypt your compressed file"
    exit 1
fi

echo
echo "${bold_yellow}4/6: sha512sum is creating hash file '${bold_red}$backupfile.xz.enc.SHA512SUM${bold_yellow}'${nocolor}"
echo

if ! sha512sum -b "$backupfile.xz.enc" > "$backupfile.xz.enc.SHA512SUM"
then
    echo "sha512sum failed to compute hashsum file"
    exit 1
fi

sha512sum -c "$backupfile.xz.enc.SHA512SUM"

echo
echo "${bold_yellow}5/6: Decrypting your '${bold_red}$backupfile.xz.enc${bold_yellow}' into a temporary file '${bold_red}$backupfile.xz.dec${bold_yellow}'${nocolor}"
echo

if ! pv -W "$backupfile.xz.enc" | openssl enc -aes-256-cbc -md sha256 -salt -out "$backupfile.xz.dec" -d -pass file:/home/vlastimil/.blablablabla 2> /dev/null
then
    echo "OpenSSL failed to decrypt your encrypted file"
    exit 1
fi

echo
echo "${bold_yellow}6/6: Comparing your un-encrypted, compressed, archived, directory file '${bold_red}$backupfile.xz${bold_yellow}' with a temporary file '${bold_red}$backupfile.xz.dec${bold_yellow}'${nocolor}"
echo

if ! cmp "$backupfile.xz" "$backupfile.xz.dec"
then
    echo "Failed to compare files"
    exit 1
else
    echo "Your directory '${bold_red}$dir${nocolor}' has been successfully stored as '${bold_red}$backupfile.xz.enc${nocolor}'"
    rm "$backupfile.xz.dec"
    rm "$backupfile.xz"
    rm "$backupfile"
fi
Vlastimil Burián
  • 1.8k
  • 2
  • 11
  • 28