Freyja's Blog

Using passwords in script, securely!

Keeping passwords inside of scripts safe from prying eyes.

Storing passwords in plaintext (sorta)

I came across an issue recently wherein I wanted to automate a backup process that requires three different passwords. I had just discovered borg backup and wanted to use it in place of the periodic rsync -azvh --delete that I was doing. The rsync method would just sync my home folder to a USB ssd, and one of my two fileservers. This worked, but didn’t have the deduplication or archiving benefits of borg. It also required me to mount my fileservers vis nfs which is another manual step in the backup process.

Borg backup works by copying data in blocks. Its much smarter than rsync, and you can encrypt the backups on the fly. For remote backups, they recommend using ssh. They allow you to put the encryption passphrase in an environment variable for automation. I wanted to use borg to backup to three different locations at the push of a button, without storing the backup encryption passphrases in plaintext or entering them every time I run a backup.

Through some trial and error, I settled upon writing my script - passhprases and all - then writing another script that encrypts it with my gpg key, and sticks it into yet another script that will first decrypt the encrypted script then pipe it directly to bash. That looks like this:

#!/bin/bash

## This will stop the script if there's no script.sh file in the root dir.
set -e
mv script.sh script.sh


GPG_ID='ENTER_YOUR_GPG_ID'

cat script.sh | gpg --encrypt --armor -r $GPG_ID | base64 --wrap 0 > script.gpg.b64

printf "#!/bin/bash\n\nSCRIPT=\"$(cat script.gpg.b64)\"\n\necho \$SCRIPT | base64 -d | gpg --decrypt --quiet | bash\n\n" > script.obf

chmod +x script.obf

rm script.gpg.b64

Now I can take any script with passwords in it, and obfuscate it behind a gpg passphrase! How neat!