diff --git a/Makefile b/Makefile index 399a49e..64334da 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ SHELL=/bin/sh BIN=tools +PKGNAME=stack_blackbox + all: @echo 'Menu:' @echo ' make packages Make all RPM packages' @@ -12,3 +14,22 @@ packages: install: @echo 'To install, copy the files from bin to somewhere in your PATH.' @echo 'Or, if you use RPMs, "make packages" and install the result.' + +packages-debug: + @echo BUILD: + @PKGRELEASE=99 make packages + @echo ITEMS TO BE PACKAGED: + find ~/rpmbuild-$(PKGNAME)/installroot -type f + @echo ITEMS ACTUALLY IN PACKAGE: + @rpm -qpl $$(cat ~/rpmbuild-$(PKGNAME)/bin-packages.txt) + +local: + @PKGRELEASE=1 make packages + -@sudo rpm -e $(PKGNAME) + sudo rpm -i $$(cat ~/rpmbuild-$(PKGNAME)/bin-packages.txt) + +lock: + sudo yum versionlock add $(PKGNAME) + +unlock: + sudo yum versionlock clear diff --git a/README.md b/README.md index 16ac801..f2d2b08 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ After deploying an update to your Puppet Master, the master runs a script that d Passwords are kept in hieradata/blackbox.yaml.gpg, which is decrypted to become hieradata/blackbox.yaml. This data can be read by hiera. This file is encrypted/decrypted just like any other blackbox file. **Key management:** -The Puppet Masters have GPG keys with no passphrase so that they can decrypt the file unattended. That means having root access on a puppet master gives you the ability to find out all our secrets. That's ok because if you have root access to the puppet master, you own the world anyway. +The Puppet Masters have GPG keys with no passphrase so that they can decrypt the file unattended. That means having root access on a puppet master gives you the ability to find out all our secrets. That is ok because if you have root access to the puppet master, you own the world anyway. The secret files are encrypted such that any one key on a list of keys can decrypt them. That is, when encrypting it is is "encrypted for multiple users". Each person that should have acecss to the secrets should have a key and be on the key list. There should also be a key for account that deploys new code to the Puppet master. @@ -38,7 +38,7 @@ What does this look like to the typical sysadmin? * Decrypt the file so it is editable: -``bin/blackbox_edit_start.sh FILENAME`` +``bin/blackbox_edit_start FILENAME`` (You will need to enter your GPG passphrase.) @@ -48,7 +48,7 @@ What does this look like to the typical sysadmin? * Re-encrypt the file: -``bin/blackbox_edit_end.sh FILENAME`` +``bin/blackbox_edit_end FILENAME`` * Commit the changes. @@ -108,7 +108,7 @@ How to enroll a new file into the system? * Add the file to the system: ``` -bin/blackbox_register_new_file.sh path/to/file.name.key +bin/blackbox_register_new_file path/to/file.name.key ``` How to indoctrinate a new user into the system? @@ -154,7 +154,7 @@ Add your keyname to the list of keys: cd keyrings/live gpg --homedir=. --import ~/.gnupg/pubkey.txt cd ../.. -blackbox_addadmin.sh $KEYNAME +blackbox_addadmin $KEYNAME ``` Check all these updates into the VCS: @@ -175,7 +175,7 @@ Ask someone that already has access to re-encrypt the data files. This gives you ``` gpg --import keyrings/live/pubring.gpg -bin/blackbox_update_all_files.sh +bin/blackbox_update_all_files ``` Push the re-encrypted files: @@ -246,20 +246,20 @@ Make a new file and register it: ``` rm -f foo.txt.gpg foo.txt echo This is a test. >foo.txt -blackbox_register_new_file.sh foo.txt +blackbox_register_new_file foo.txt ``` Decrypt it: ``` -blackbox_edit_start.sh foo.txt.gpg +blackbox_edit_start foo.txt.gpg cat foo.txt echo This is the new file contents. >foo.txt ``` Re-encrypt it: ``` -blackbox_edit_end.sh foo.txt.gpg +blackbox_edit_end foo.txt.gpg ls -l foo.txt* ``` @@ -377,7 +377,7 @@ Back on SECUREHOST, add the new email address to keyrings/live/blackbox-admins.t ``` cd /path/to/the/repo -blackbox_addadmin.sh $KEYNAME +blackbox_addadmin $KEYNAME ``` Verify that secring.gpg is a zero-length file. If it isn't, you have @@ -398,7 +398,7 @@ git commit -m"Adding key for KEYNAME" pubring.gpg trustdb.gpg blackbox-admins.tx Regenerate all encrypted files with the new key: ``` -blackbox_update_all_files.sh +blackbox_update_all_files git status git commit -m"updated encryption" -a git push @@ -410,7 +410,7 @@ On NEWMASTER, import the keys and decrypt the files: sudo -u svc_sadeploy bash # Become the role account. gpg --import /etc/puppet/keyrings/live/pubring.gpg export PATH=$PATH:/path/to/blackbox/bin -blackbox_postinstall.sh +blackbox_postinstall sudo -u puppet cat /etc/puppet/hieradata/blackbox.yaml # or any encrypted file. ``` diff --git a/bin/blackbox_common.sh b/bin/_blackbox_common.sh similarity index 87% rename from bin/blackbox_common.sh rename to bin/_blackbox_common.sh index ec00a33..60ac962 100755 --- a/bin/blackbox_common.sh +++ b/bin/_blackbox_common.sh @@ -1,32 +1,38 @@ +#!/usr/bin/env bash # # Common constants and functions used by the blackbox_* utilities. # -KEYRINGDIR=keyrings/live +# Usage: +# . _blackbox_common.sh + +# Where in the VCS repo should the blackbox data be found? +: ${BLACKBOXDATA:=keyrings/live} ; # If BLACKBOXDATA not set, set it. + +set -e + +# Outputs a string that is the base directory of this VCS repo. +# By side-effect, sets the variable VCS_TYPE to either 'git', 'hg', +# or 'unknown'. +function _determine_vcs_base_and_type() { + if hg root 2>/dev/null ; then + VCS_TYPE=hg + elif git rev-parse --show-toplevel 2>/dev/null ; then + VCS_TYPE=git + else + echo /dev/null + VCS_TYPE=unknown + fi +} + +REPOBASE=$(_determine_vcs_base_and_type) +KEYRINGDIR="$REPOBASE/$BLACKBOXDATA" BB_ADMINS="${KEYRINGDIR}/blackbox-admins.txt" BB_FILES="${KEYRINGDIR}/blackbox-files.txt" SECRING="${KEYRINGDIR}/secring.gpg" PUBRING="${KEYRINGDIR}/pubring.gpg" -# Exit with error if the environment is not right. -function fail_if_bad_environment() { - # Current checked: - # Nothing. - - : - - # TODO: Consider: cd $(git rev-parse --show-toplevel) - # And: hg root - - ## Are we in the base directory. - #if [[ ! $(pwd) =~ \/puppet$ ]]; then - # echo 'ERROR: Please run this script from the base directory.' - # echo 'Exiting...' - # exit 1 - #fi -} - # Exit with error if a file exists. function fail_if_exists() { if [[ -f "$1" ]]; then @@ -183,19 +189,9 @@ function enumerate_subdirs() { done <"$listfile" | sort -u } -# Are we in git, hg, or other repo? +# Are we in git, hg, or unknown repo? function which_vcs() { - if [[ -d .git ]]; then - echo git - elif [[ -d .hg ]]; then - echo hg - elif git rev-parse --git-dir > /dev/null 2>&1 ; then - echo git - elif hg status >/dev/null 2>&1 ; then - echo hg - else - echo other - fi + echo "$REPO_TYPE" } # Is this file in the current repo? diff --git a/bin/blackbox_addadmin b/bin/blackbox_addadmin new file mode 100755 index 0000000..04afb8b --- /dev/null +++ b/bin/blackbox_addadmin @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# +# blackbox_addadmin -- Add an admin to the system +# +# +# Example: +# blackbox_addadmin tal@example.com +# + +. _blackbox_common.sh + +# Add the email address to the BB_ADMINS file. Remove any duplicates. + +# The file must exist for sort to act as we expect. +touch "$BB_ADMINS" +sort -fdu -o "$BB_ADMINS" <(echo "$1") "$BB_ADMINS" diff --git a/bin/blackbox_addadmin.sh b/bin/blackbox_addadmin.sh deleted file mode 100755 index 9ddb662..0000000 --- a/bin/blackbox_addadmin.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd keyrings/live -touch blackbox-admins.txt -sort -fdu -o blackbox-admins.txt <(echo "$1") blackbox-admins.txt diff --git a/bin/blackbox_edit_end.sh b/bin/blackbox_edit_end similarity index 82% rename from bin/blackbox_edit_end.sh rename to bin/blackbox_edit_end index fe9c65e..07f33f8 100755 --- a/bin/blackbox_edit_end.sh +++ b/bin/blackbox_edit_end @@ -1,13 +1,11 @@ -#!/bin/bash +#!/usr/bin/env bash # -# blackbox_edit_end.sh -- Re-encrypt file after edits. +# blackbox_edit_end -- Re-encrypt file after edits. # -source blackbox_common.sh -set -e +. _blackbox_common.sh -fail_if_bad_environment unencrypted_file=$(get_unencrypted_filename "$1") encrypted_file=$(get_encrypted_filename "$1") echo ========== PLAINFILE "$unencrypted_file" diff --git a/bin/blackbox_edit_start.sh b/bin/blackbox_edit_start similarity index 91% rename from bin/blackbox_edit_start.sh rename to bin/blackbox_edit_start index 8d0e616..30f2ee4 100755 --- a/bin/blackbox_edit_start.sh +++ b/bin/blackbox_edit_start @@ -4,10 +4,7 @@ # blackbox_edit_start.sh -- Decrypt a file for editing. # -source blackbox_common.sh -set -e - -fail_if_bad_environment +. _blackbox_common.sh for param in """$@""" ; do unencrypted_file=$(get_unencrypted_filename "$param") diff --git a/bin/blackbox_postdeploy.sh b/bin/blackbox_postdeploy similarity index 61% rename from bin/blackbox_postdeploy.sh rename to bin/blackbox_postdeploy index 6567a8a..3898471 100755 --- a/bin/blackbox_postdeploy.sh +++ b/bin/blackbox_postdeploy @@ -4,14 +4,16 @@ # blackbox_postdeploy.sh -- Decrypt all blackbox files. # -: ${BASEDIR:=/etc/puppet} ; -: ${CHGRP:=chgrp} ; +# Since this is often run in a security-critical situation, we +# force /usr/bin and /bin to the front of the PATH. +export PATH=/usr/bin:/bin:"$PATH" -cd "$BASEDIR" -export PATH=/usr/bin:/bin:"$BASEDIR"/bin:"$PATH" +. _blackbox_common.sh -source blackbox_common.sh -set -e +# If we aren't in a repo, assume /etc/puppet. +if [[ "$REPOBASE" = "/dev/null" ]]; then + REPOBASE=/etc/puppet +fi prepare_keychain diff --git a/bin/blackbox_register_new_file.sh b/bin/blackbox_register_new_file similarity index 71% rename from bin/blackbox_register_new_file.sh rename to bin/blackbox_register_new_file index 6154d38..48b00df 100755 --- a/bin/blackbox_register_new_file.sh +++ b/bin/blackbox_register_new_file @@ -3,15 +3,13 @@ # # blackbox_register_new_file.sh -- Enroll a new file in the blackbox system. # -# Takes a previously unencrypted file and enters it into the blackbox -# system. It will be kept in HG as an encrypted file. On deployment -# to the puppet masters, it will be decrypted. The puppet masters -# refer to the unencrypted filename. +# Takes a previously unencrypted file and enrolls it into the blackbox +# system. It will be kept in the repo as an encrypted file. On deployment +# to systems that need the plaintext (unencrypted) versions, run +# blackbox_postdeploy.sh to decrypt all the files. -source blackbox_common.sh -set -e +. _blackbox_common.sh -fail_if_bad_environment unencrypted_file=$(get_unencrypted_filename "$1") encrypted_file=$(get_encrypted_filename "$1") @@ -30,21 +28,18 @@ prepare_keychain encrypt_file "$unencrypted_file" "$encrypted_file" add_filename_to_cryptlist "$unencrypted_file" -# TODO(tlim): The code below should be rewritten to check -# for HG vs. GIT use and DTRT depending. - # Is the unencrypted file already in HG? (ie. are we correcting a bad situation) SECRETSEXPOSED=$(is_in_vcs ${unencrypted_file}) echo "========== CREATED: ${encrypted_file}" echo "========== UPDATING REPO:" shred_file "$unencrypted_file" -# NOTE(tlim): Because we use $VCSCMD, we can only use commands that -# work for both git and hg. VCSCMD=$(which_vcs) if $SECRETSEXPOSED ; then rm_from_vcs "$unencrypted_file" $VCSCMD add "$encrypted_file" + # NOTE(tlim): Because we use $VCSCMD as a command, we can only use commands + # that work for both git and hg. COMMIT_FILES="$BB_FILES $encrypted_file $unencrypted_file" else COMMIT_FILES="$BB_FILES $encrypted_file" @@ -52,6 +47,6 @@ fi echo 'NOTE: "already tracked!" messages are safe to ignore.' $VCSCMD add $BB_FILES $encrypted_file $VCSCMD commit -m"registered in blackbox: ${unencrypted_file}" $COMMIT_FILES -echo "========== UPDATING HG: DONE" +echo "========== UPDATING VCS: DONE" echo "Local repo updated. Please push when ready." echo " $VCSCMD push" diff --git a/bin/start b/bin/blackbox_start similarity index 89% rename from bin/start rename to bin/blackbox_start index 106eb9e..bba4e80 100755 --- a/bin/start +++ b/bin/blackbox_start @@ -4,9 +4,7 @@ # blackbox_edit_start.sh -- Decrypt a file for editing. # -source blackbox_common.sh - -fail_if_bad_environment +. _blackbox_common.sh for param in """$@""" ; do unencrypted_file=$(get_unencrypted_filename "$param") diff --git a/bin/blackbox_update_all_files.sh b/bin/blackbox_update_all_files similarity index 80% rename from bin/blackbox_update_all_files.sh rename to bin/blackbox_update_all_files index 023eff9..3208916 100755 --- a/bin/blackbox_update_all_files.sh +++ b/bin/blackbox_update_all_files @@ -4,10 +4,7 @@ # blackbox_edit_end.sh -- Re-encrypt file after edits. # -source blackbox_common.sh -set -e - -fail_if_bad_environment +. _blackbox_common.sh if [[ -z $GPG_AGENT_INFO ]]; then echo 'WARNING: You probably want to run gpg-agent as' @@ -53,8 +50,12 @@ done fail_if_keychain_has_secrets echo '========== COMMITING TO HG:' -hg commit -m'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' ) +VCSCMD=$(which_vcs) +$VCSCMD commit -m'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' ) +# NOTE(tlim): Because we use $VCSCMD as a command, we can only use commands +# that work for both git and hg. That's pretty lazy. We should add +# a function to _blackbox_common.sh that commits a file. echo '========== DONE.' echo 'Likely next step:' -echo ' hg push' +echo " ${VCSCMD} push" diff --git a/tools/rpm_filelist.txt b/tools/rpm_filelist.txt index 6f6520c..47fd19f 100644 --- a/tools/rpm_filelist.txt +++ b/tools/rpm_filelist.txt @@ -1,9 +1,9 @@ -exec /usr/blackbox/bin/blackbox_addadmin bin/blackbox_addadmin.sh -exec /usr/blackbox/bin/blackbox_common bin/blackbox_common.sh -exec /usr/blackbox/bin/blackbox_edit_end bin/blackbox_edit_end.sh -exec /usr/blackbox/bin/blackbox_edit_start bin/blackbox_edit_start.sh -exec /usr/blackbox/bin/blackbox_postdeploy bin/blackbox_postdeploy.sh -exec /usr/blackbox/bin/blackbox_register_new_file bin/blackbox_register_new_file.sh -exec /usr/blackbox/bin/blackbox_update_all_files bin/blackbox_update_all_files.sh -exec /usr/blackbox/bin/blackbox_start bin/start +exec /usr/blackbox/bin/blackbox_addadmin bin/blackbox_addadmin +exec /usr/blackbox/bin/_blackbox_common.sh bin/_blackbox_common.sh +exec /usr/blackbox/bin/blackbox_edit_end bin/blackbox_edit_end +exec /usr/blackbox/bin/blackbox_edit_start bin/blackbox_edit_start +exec /usr/blackbox/bin/blackbox_postdeploy bin/blackbox_postdeploy +exec /usr/blackbox/bin/blackbox_register_new_file bin/blackbox_register_new_file +exec /usr/blackbox/bin/blackbox_update_all_files bin/blackbox_update_all_files +exec /usr/blackbox/bin/blackbox_start bin/blackbox_start read /etc/profile.d/usrblackbox.sh tools/profile.d-usrblackbox.sh