#!/bin/bash # # Script to edit secrets for a host. # # This script is used by an administrator on his/hers local machine. The # general principle is for this script to ssh to the target host, decrypt # the secrets and allow changes to be made, and then fetch the encrypted # secrets from the host and add it to the Cosmos repository on the # administrators machine. # # Funnily enough, this script will execute itself (with the argument # '--on-host') on the target host in order to do the decryption etc. Don't # allow this to confuse you and everything will be fine. # set -e umask 077 LAST_OUTPUT_FILENAME="/root/.last_edit-secrets_output" if [[ "x${EDITOR}" != "x" ]]; then declare -r REMOTE_EDITOR="${EDITOR}" else declare -r REMOTE_EDITOR='/usr/bin/vim.tiny' fi if [ "x$1" = "x" ]; then echo "Syntax: $0 -l OR fqdn" exit 1 fi if [ "x$1" != "x-l" ]; then host=$(echo $1 | sed -e 's!/*$!!') # remove trailing slashes if [ ! -d $host ]; then echo "$0: No host-directory for '$host' found - execute in top-level cosmos dir" exit 1 fi # Execute this very script, on a remote host TMPFILE=$(mktemp edit-secrets.$$.XXXXXXX) if [ ! -f $TMPFILE ]; then echo "$0: Failed creating temporary file" exit 1 fi TMPFILE2=$(mktemp edit-secrets.$$.XXXXXXX) if [ ! -f $TMPFILE2 ]; then echo "$0: Failed creating temporary file" exit 1 fi trap "rm -f $TMPFILE $TMPFILE2" EXIT ssh -t root@$host EDITOR="${REMOTE_EDITOR}" /var/cache/cosmos/repo/edit-secrets -l scp -q root@$host:$LAST_OUTPUT_FILENAME $TMPFILE if grep ^"STATUS=UPDATED" $TMPFILE > /dev/null; then # extract the path of the file that should be updated in the Cosmos repo save_to="${host}/overlay/etc/hiera/data/secrets.yaml.asc" mkdir -p "`dirname $save_to`" # extract the GPG output perl -e '$a = 0; while (<>) { $a = 1 if ($_ =~ /-+BEGIN PGP MESSAGE-+/); print $_ if $a; $a = 0 if ($_ =~ /-+END PGP MESSAGE-+/); }' < $TMPFILE > $TMPFILE2 if ! grep "END PGP MESSAGE" $TMPFILE2 > /dev/null; then echo "$0: Failed extracting PGP output from file $TMPFILE into $TMPFILE2" exit 1 fi # use cat to preserve permissions etc. cat $TMPFILE > $save_to git add $save_to echo "" echo "$save_to updated" echo "" else echo "" echo "Not updated" echo "" fi rm $TMPFILE $TMPFILE2 exit 0 fi # # Local execution on a host # SECRETFILE=/etc/hiera/data/secrets.yaml.asc GNUPGHOME=/etc/hiera/gpg/ export GNUPGHOME GPG=`which gpg2 || true` if [ ! -x "$GPG" ]; then GPG=`which gpg || true` if [ ! -x "$GPG" ]; then echo "$0: gpg2 or gpg not found" exit 1 fi fi TMPFILE=$(mktemp --tmpdir=/dev/shm) TMPFILE2=$(mktemp --tmpdir=/dev/shm) if [ ! -f $TMPFILE ]; then echo "$TMPFILE" echo "$0: Failed creating temporary file" exit 1 fi if [ ! -f $TMPFILE2 ]; then echo "$TMPFILE2" echo "$0: Failed creating temporary file 2" exit 1 fi trap "rm -f $TMPFILE $TMPFILE2" EXIT if ! $GPG --list-secret-keys | grep -q ^"sec\s"; then echo "$0: Secret key does not exist (in $GNUPGHOME)." echo "" echo "Generate it with /var/cache/cosmos/model/pre-tasks.d/040hiera-gpg" echo "" exit 1 fi if [ -s $SECRETFILE ]; then $GPG -d $SECRETFILE > $TMPFILE fi cp $TMPFILE $TMPFILE2 sensible-editor $TMPFILE rm -f ${TMPFILE}~ ${TMPFILE2}~ echo "" echo "" status=0 cmp -s $TMPFILE $TMPFILE2 || status=1 if [ $status -eq 0 ]; then ( echo "STATUS=NOT_CHANGED" ) > $LAST_OUTPUT_FILENAME echo "" echo "$0: No changes detected" else # figure out this hosts gpg key id recipient=$($GPG --list-secret-key | grep ^sec | head -1 | awk '{print $2}' | cut -d / -f 2) save_to="`hostname --fqdn`/overlay${SECRETFILE}" echo "" ( echo "STATUS=UPDATED" echo "" ) > $LAST_OUTPUT_FILENAME $GPG --output - --armor --recipient $recipient --sign --encrypt $TMPFILE >> $LAST_OUTPUT_FILENAME echo "" echo "GPG output saved in $LAST_OUTPUT_FILENAME - save it in Cosmos as" echo "" echo " $save_to" echo "" fi