Browse Source

Initial commit

R. Alex Matevish 5 years ago
commit
946d22b26c
3 changed files with 182 additions and 0 deletions
  1. 4 0
      .gitignore
  2. 98 0
      README.md
  3. 80 0
      run.sh

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+stash.tar.gz
+stash
+.ramdisk_id
+.me

+ 98 - 0
README.md

@@ -0,0 +1,98 @@
+# gpg-stash
+
+A simple in-memory-stash for credentials and other things you'd want to keep safe.
+
+Rather than shipping credentials between computers on a thumbdrive/`scp`, you can instead keep an encrypted tarball that can be passed over an unknown network and decrypted locally to a ramdisk.
+
+The primary motivations for this stash are:
+
+- Security when moving keys and credentials between computers
+- Never letting unencrypted keys hit the harddrive
+- Easy support for a git-based workflow
+
+## The Workflow
+
+The idea behind this `gpg-stash` is to have a git repository which has a simple script (`run.sh`) to run common tasks, and an encrypted tarball which contains the things you want to safely stash.
+
+When you want to access the stash, it can be decrypted to a ramdisk which won't leave traces the harddrive, and is automatically removed on shutdown.
+
+To add an file to the stash you can decrypt it, add the file to the stash, and re-encrypt the tarball. It can then be commited and pushed so that other computers you use can pull down the latest changes.
+
+## Getting Started
+
+To create the initial tar ball we need two things:
+
+1. the stash directory to encrypt
+2. the recipient (you, most likely) to be set
+
+**To set the recipient** (which should be you, as you'll need the private key with the recipient name to decrypt the encrypted tarball), run:
+
+```
+./run.sh -m my@privkey.id
+```
+
+**To create the initial stash directory**, run:
+
+```
+./run.sh -i
+```
+
+This will create a directory on a ramdisk which you can load up with anything you want in the initial encrypted tarball.
+
+**To encrypt the files in the stash directory**, run:
+
+```
+./run.sh -e
+```
+
+which will create/update the encrypted tarball (`stash.tar.gz.gpg`)  with the files you added. This command outputs the list of files added, so ***make sure it's all there.***
+
+**You can remove the stash directory** by removing the ramdisk by running:
+
+```
+./run.sh -r
+```
+
+**To decrypt the files in the stash directory**, run:
+
+```
+./run.sh -d
+```
+
+This creates a ramdisk, formats it with APFS, links it locally to `./stash` and extracts the contents of the encrypted tarball into it. 
+
+## Caveat Emptor
+
+This tool is intended to be used by people who have some grasp of OpenPGP and encryption in general.
+
+It's very easy to inadvertantly publish a secret key, encrypt under a key and throw it away, or blow off your leg (cryptographically speaking, hopefully). 
+
+I take no responsibility for your actions, though if you open open up an issue I'm happy to assist the best I can.
+
+### Good ideas (probably)
+
+***- Don't add unencrypted secrets to your commits!***
+
+The `.gitignore` file should take care of this, but do some due diligence when commiting.
+
+***- You should still have password-encrypted keys in the tarball***
+
+Once we decrypt the tarball it's accessible like any other part of the file system, even if it's on a ramdisk.
+
+***- It's best not to expose your tarball publically***
+
+While you're protected by whatever encryption you've configured it's still a fairly large risk - defense in depth includes to not letting your encrypted tarball hit the public internet.
+
+***- If your encryption key is compromised, everything in your encrypted tarball is compromised as well***
+
+This should go without saying, but imagine the case where you lose a key. "Cool, no problem", you say, "I'll just generate a new key and encrypt the tarball under that!" 
+
+While that protects the new tarball, the old one (with your stash contents) can be decrypted with your compromised key.
+
+***- Don't put your prodution DB credentials in your encrypted tarball***
+
+This tool intended for personal keys and if the idea of having *all* the keys to the kingdom in one place that lives on multiple computers doesn't scare you, it should.
+
+A secure host behind a firewall distributing keys to your cloud servers might be a single point of failure but it's a known point of failure and can be sufficiently hardened/audited. This is an encrypted tarball you're using to keep your keys in sync accross your work and personal laptops.
+
+> Defense in depth is your friend

+ 80 - 0
run.sh

@@ -0,0 +1,80 @@
+#!/bin/bash -e
+
+
+RAMDISK_FILE=".ramdisk_id"
+RAMDISK_VOLUME_NAME="stash"
+STASH_FILE="stash.tar.gz.gpg"
+STASH_DIR="stash"
+ME_FILE=".me"
+
+function mk_ramdisk() {
+  if [ -f "$RAMDISK_FILE" ]; then
+    echo "Run ./run.sh -r to remove the existing ramdisk";
+    exit 1;
+  fi
+
+  echo "Making ramdisk...";
+  hdiutil attach -nomount ram://65536 > $RAMDISK_FILE;
+
+  cat $RAMDISK_FILE;
+
+  echo "Formatting ramdisk";
+  diskutil partitionDisk $(cat $RAMDISK_FILE) 1 GPTFormat APFS "$RAMDISK_VOLUME_NAME" "100%";
+
+  echo "Linking ramdisk to stash dir"
+  ln -s "/Volumes/$RAMDISK_VOLUME_NAME" $STASH_DIR;
+}
+
+
+
+while getopts "miedr" opt; do
+  case $opt in
+    m)
+      if [ -f "$ME_FILE" ]; then
+          echo "Remove the existing $ME_FILE if you want to set the recipient key (which should probably be you)";
+          exit 1;
+      fi
+      echo $2 > "$ME_FILE";
+      ;;
+    i)
+      echo "Creating initial stash directory"
+      mk_ramdisk
+      ;;
+    e)
+      if [ ! -d "$STASH_DIR" ]; then
+          echo "Run ./run.sh -d to decrypt the stash change the contents before encrypting";
+          exit 1;
+      elif [ ! -f "$ME_FILE" ]; then
+          echo "Run ./run.sh -m to set the recipient key before encrypting";
+          exit 1;
+      fi
+    
+      echo "Encrypting...";
+      ME=$(cat $ME_FILE);
+      tar --exclude=".*" -zcv $STASH_DIR/* | gpg2 --encrypt -r $ME - > "$STASH_FILE";
+      ;;
+    d)
+      mk_ramdisk;
+      echo "Decrypting...";
+      gpg2 --decrypt "$STASH_FILE" | tar -zxvf - -C $STASH_DIR --strip-components=1;
+      ;;
+    r)
+      if [ ! -f "$RAMDISK_FILE" ]; then
+          echo "Can't remove ramdisk - $RAMDISK_FILE not found";
+          exit 1;
+      fi
+
+      echo "Unmounting ramdisk...";
+      hdiutil detach -force $(cat $RAMDISK_FILE);
+      rm $RAMDISK_FILE $STASH_DIR;
+      ;;
+    \?)
+      echo "Invalid option: -$OPTARG" >&2
+      exit 1
+      ;;
+    :)
+      echo "Option -$OPTARG requires an argument." >&2
+      exit 1
+      ;;
+  esac
+done