The Problem

I love shell scripts. Anything that can be automated by scripts I am all for it. Whenever I find myself having to do some task a few times I realize it is time for a script. I also love the convenience of backing data to “the cloud.”  However, I am not a fan of the inherent security and privacy risks cloud storage poses. I know there are services out there that purport to offer “zero knowledge” secure cloud storage; a prime example being Spider Oak One. I admit that I personally use Spider Oak and thus far have found their service to meet expectations.  However, from time to time I find myself with data where prudence (or paranoia, such a gray line between the two) compels me to insist on an additional layer of security.

Based on my risk tolerance and my threat environment the compromise between security and convenience that works for me is to take the files I feel need extra protection while in cloud storage and encrypt them.  The encrypted files are then uploaded to my Spider Oak One account; which, if claims are true, is also encrypted with Spider Oak One not retaining the keys thus unable to decrypt my account contents. If later this proves false, well at least the files I encrypted beforehand are still strongly encrypted and theoretically secure.

However, I am lazy and I hate having to decrypt, work on the data, encrypt and sync. So I dreamed up a way to create a “secure” folder where the encryption, decryption, syncing encrypted files would be automated. Also as an added bonus, this would help (not prevent) in situations where I forgot to secure the data. The automation would guard against my ADD in those moments I get distracted, walk away from the computer, and forget to lock down the data.

The Solution

Requirements

Ubuntu 16.04+ (or similar OS)
gpg 2.2.4
libgcrypt 1.8.1
shred 8.28
A keypair on your keyring; preferably a unique key dedicated for this purpose. For added security set a passphrase so even if someone has access to your system they cannot just automatically decrypt using the key.

I created two files; encrypt.sh and decrypt.sh (code below). Each file requires execution privileges (e.g. chmod + x encrypt.sh, etc). For ease of use, I moved the two files into /usr/bin this way they can be called directly in the terminal from any folder (of course this assumes /usr/bin is in your $PATH which it should be).

So the workflow goes as follows:

I have set my back up to run daily at 1:00AM. I’ve scheduled a user cronjob to run either on @reboot or 12:00AM by calling encrypted.sh. Thus whenever the system is rebooted or at 12:00AM the contents of the /home/user/secure-folder are encrypted using the gpg key “secure”. So when the backup runs everything should be encrypted.

Outside of 12:00AM and 1:00AM I can run decrypt.sh. Since my key has a passphrase set it will prompt me for the passphrase, I enter it in, and voila the files are unlocked. To secure I just run encrypt.sh; or if I forget it will happen at 12:00AM. In a panic, a reboot should do it.

#! /bin/bash
for filename in /home/user/secure-folder/*.*; do  #Main For - Go to the folder which holds
                                                  #the files you want secured and loop
                                                  #through them.
  if [[ ! ${filename: -4} == ".gpg" ]]; then      #GPG If - file ends in .gpg skip it so we
                                                  #don't re-encrypt anything
    gpg -e -r secure $filename                    #Encrypt the file using the "secure"
                                                  #key
    shred $filename                               #Shred the unencrypted file
    rm $filename                                  #Delete the shredded unencrypted file 
  fi                                              #End GPG If
done                                              #End Main For
#! /bin/bash
#Start if - Let's test to see if there are any encrypted files, if not direct the no
#files found error to /dev/null and end.
if [ ! -z "$(ls -A /home/user/secure-folder/*.gpg 2> /dev/null)" ]; then 

  for filename in /home/user/secure-folder/*.gpg; do #Main For - Go to the folder
                                                     #which holds the files you
                                                     #want secured and loop
                                                     #through them.
    decrypt_filename=${filename%.*} #gpg appends .gpg to encrypted files get
                                    #the file name minus the .gpg.

    #Here we decrypt the file and if decryption failed, such as in a bad
    #phrase being entered, we store that into a variable.
    stderr=$(gpg -d -o $decrypt_filename $filename 2>&1 | grep 'decryption failed')

    if [[ $stderr == '' ]]; then  #Err Check If
      shred $filename  #If no errors shred the encrypted file
      rm $filename     #Delete the shredded encrypted file
    fi #End Err Check If
  done  #End Main For
fi  #End Start If

Limitations

Of course, this method is not foolproof nor is it all that clever. However, I do find it just a tad bit helpful for my purposes. Your threat environment or needs may be such that this trick is useless and that is ok. The two main limitations, specific to this method, I have thought of (besides the obvious ones like passphrase compromise, etc):

In a hard power down situation, any unencrypted files will likely remain on the disk in that state. Assuming your home folder and/or drive is not encrypted an attacker will likely get access to the files via booting from another disk and mounting the drive. This one can be mitigated by encrypting your drive and/or your home folder.

You may think I make a pretty powerful assumption that the cronjob will fire at 12:00AM but I have left one important thing out. In my Spider Oak Software, I limit the syncing of the “secure” folder to only the *.gpg files I am working on. If those files are not there then nothing in that folder gets backed up.  If you find this hole unacceptable an easy fix would be to have two folders; say a “secure” and “open” folder. Upon successful encryption the secure files are moved to the secure folder; it is this folder and this folder only that the backup scheduler pulls from. Likewise, during decryption, the files are removed from the secure folder and put into the open folder.