Skip to content

Instantly share code, notes, and snippets.

@richinseattle
Created July 10, 2018 19:57
Show Gist options
  • Select an option

  • Save richinseattle/69fa8b197ace3b7c9214118cddec4849 to your computer and use it in GitHub Desktop.

Select an option

Save richinseattle/69fa8b197ace3b7c9214118cddec4849 to your computer and use it in GitHub Desktop.
Backup & Encrypt tar files with OpenSSL
#!/bin/sh
#1. POSIX shell
#2. tar
#3. openssl (libressl should work)
#4. srm (to clean up afterwards)
#Tested on FreeBSD 11.1 only but should work elsewhere.
# tarsnack (the taste of tarsnap in 70 lines or less).
# using a certificate to encrypt a compressed 'tar' archive file.
# TODO: add this as a cron job.
# TODO: move the file via SSH to some place safe (rotating set of USB drives or SD cards will do for now).
# Certificate and private key generated as follows:
#> openssl genrsa -rand -genkey -out cert.key 2048
#> openssl req -new -x509 -days 365 -key cert.key -out cert.crt -sha256
# cert.key is the *private* key which should be stored elsewhere; needed only for restore.
# everything has the same suffix.
export Suffix=`date +'%Y-%m-%d'`
export Machine=`hostname`
export Nonce=${Machine}-${Suffix}.key
export Payload=${Machine}-${Suffix}.tar
export Package=${Machine}-${Suffix}.tar
export Certificate=~/cert.crt
export PubKey=cert.pem
export Target=/usr/home
export Wipe='srm --dod'
export Exclude=~/exclude.txt
# 'find' gathers everything under /usr/home/ while excluding some files and folders.
# Uses pax for compressed archive.
# sadly, pax does not have an exclude option like tar so some ugliness follows.
echo 'Creating ...' ${Payload}
tar -czvf /tmp/${Payload} --exclude-from ${Exclude} ${Target}
# everything in /tmp from here on out.
chdir /tmp
# generate 128 byte random nonce
echo 'Creating ...' ${Nonce}
openssl rand -base64 128 -out ${Nonce}
# encrypt the PAX file with the nonce.
echo 'Encrypting payload ...' ${Payload}
openssl enc -aes-256-cbc -salt -in ${Payload} -out ${Payload}.enc -pass file:${Nonce}
# extract the public key
echo 'Extracting pubkey ...' ${PubKey} ' from certificate ' ${Certificate}
openssl x509 -pubkey -noout -in ${Certificate} > ${PubKey}
# encrypt the nonce
echo 'Encrypting nonce ...' ${Nonce}
openssl rsautl -encrypt -inkey ${PubKey} -pubin -in ${Nonce} -out ${Nonce}.enc
# clean up - pubkey derived from certificate so no need to keep it around.
# can replace 'srm' with 'wipe', 'shred', 'bcwipe', 'sdelete', etc.
echo 'Cleanup ...' ${Nonce} ' and ' ${PubKey} ' and ' ${Payload}
${Wipe} ${PubKey}
${Wipe} ${Nonce}
${Wipe} ${Payload}
# combine the encrypted secrect decoder ring with the encrypted payload for convenience.
echo 'Creating restore script ...'
# this will decrypt the tar file given the private key.
# echo '#!\bin\sh' > ./restore.sh
echo 'Nonce='${Nonce} >> ./restore.sh
echo 'Payload='${Payload} >> ./restore.sh
echo 'openssl rsautl -decrypt -inkey $1 -in ${Nonce}.enc -out ${Nonce}' >> ./restore.sh
echo 'openssl enc -d -aes-256-cbc -in ${Payload}.enc -out ${Payload} -pass file:${Nonce}' >> ./restore.sh
echo "echo \'done.\'" >> ./restore.sh
echo "Creating package ... ${Package}"
tar -cvf ${Package} ${Nonce}.enc ${Payload}.enc restore.sh
echo "Cleanup ... ${Nonce} and ${Payload}"
${Wipe} ${Nonce}.enc
${Wipe} ${Payload}.enc
${Wipe} restore.sh
echo "Please pick up your package: ${Package}"
chdir -
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment