summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Kinkade <nkinkade@creativecommons.org>2014-05-23 09:59:46 -0400
committerNathan Kinkade <nkinkade@creativecommons.org>2014-05-23 09:59:46 -0400
commitd8a455efd41afdbefe6065e48df90ee2fb636dcb (patch)
tree4c83e0196bcc3e20672c9b8accbc672a48ccd734
Initial commit.
-rw-r--r--README10
-rwxr-xr-xcheck_sign_aide.sh107
-rwxr-xr-xcheck_sign_aide_wrapper.sh28
3 files changed, 145 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..4f9a0ff
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+These are a couple of scripts used to manage the digital signing of AIDE
+databases. The script check_sign_aide.sh is installed on one central server,
+where the various signatures will be managed and stored. The script uses SSH
+to login to each remote server using public-key authentication. Because these
+operations need to happen as root on each remote machine, root's
+authorized_keys file on each remote machine should have a forced command
+something like the following for the key of the central server handling the
+signing:
+
+command="/root/bin/check_sign_aide_wrapper.sh",no-port-forwarding,no-X11-forwarding,no-pty,from="server.example.com"
diff --git a/check_sign_aide.sh b/check_sign_aide.sh
new file mode 100755
index 0000000..7549b33
--- /dev/null
+++ b/check_sign_aide.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+if [ ! $1 ]; then
+ echo "You must at least provide an argument for which action to take."
+ exit
+fi
+
+DOMAIN="example.com"
+SIGNATURE_DIR="/root/aide_sigs"
+SSH_KEY="/path/to/private/key"
+
+ALL_SERVERS="\
+ server1.example.com \
+ server2.example.com \
+ server3.example.com \
+"
+
+# if a 2nd argument was passed then assume a list of servers was passed, else
+# just perform the operation on all servers
+if [ $2 ]; then
+ SERVERS=${@:2}
+else
+ SERVERS=$ALL_SERVERS
+fi
+
+# File extension for each of the AIDE files we sign
+AIDE_FILES="db bin cron conf"
+
+# Public GPG key we'll use to sign the files
+GPG_KEY="0xA1A1A1A1"
+
+export RSYNC_RSH="ssh -i ${SSH_KEY}"
+
+# Fetch the AIDE files to be checked or signed
+# To understand how/why this works, please see the file
+# check_sign_aide_wrapper.sh, which will be installed on
+# each remote machine.
+fetch_files () {
+ for aide_file in $AIDE_FILES
+ do
+ rsync -az $1:fetch-$aide_file ./aide.$aide_file
+ done
+}
+
+# Check the digital signatures of each AIDE file
+check_sigs () {
+ for aide_file in $AIDE_FILES
+ do
+ gpg --verify ./aide.$aide_file.sig &> /dev/null
+ if [ $? -ne 0 ]; then
+ echo "The signature of aide.${aide_file} for ${1} was bad!"
+ fi
+ done
+}
+
+# Create new digital signature for each AIDE file
+sign_files () {
+ for aide_file in $AIDE_FILES
+ do
+ gpg -u $GPG_KEY -sb --yes ./aide.$aide_file &> /dev/null
+ if [ $? -ne 0 ]; then
+ echo "Failed to sign aide.${aide_file} for ${1}!"
+ fi
+ done
+}
+
+# Copy the new AIDE database (aide.new.db) onto the old one (aide.db). This is
+# necessary when AIDE reports some files which have changed, and we want to
+# acknowldge the changes, and not receive reports about these same changes day
+# after day.
+copy_db () {
+ ssh -i $SSH_KEY $1 'copy-db'
+}
+
+for server in $SERVERS
+do
+
+ # This allows you to pass in a list of servers using only their
+ # hostname and not the FQDN. This just reduces typing if you have to
+ # pass in a list of 4 or 5 servers.
+ echo $server | grep -q '\.' || server="${server}.${DOMAIN}"
+
+ cd $SIGNATURE_DIR/$server
+ if [ $? -ne 0 ]; then
+ echo "Failed to cd to ${SIGNATURE_DIR}/${server}!"
+ exit
+ fi
+
+ case $1 in
+ check)
+ fetch_files $server
+ check_sigs $server
+ ;;
+ sign)
+ fetch_files $server
+ sign_files $server
+ ;;
+ copydb)
+ copy_db $server
+ fetch_files $server
+ sign_files $server
+ ;;
+ *)
+ echo "FAIL! FAIL! FAIL!"
+ esac
+
+done
diff --git a/check_sign_aide_wrapper.sh b/check_sign_aide_wrapper.sh
new file mode 100755
index 0000000..3eb3955
--- /dev/null
+++ b/check_sign_aide_wrapper.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+COMMAND=$(echo $SSH_ORIGINAL_COMMAND | cut -d' ' -f1)
+if [ $COMMAND = "rsync" ]; then
+ ACTION=$(echo $SSH_ORIGINAL_COMMAND | cut -d' ' -f6)
+else
+ ACTION=$COMMAND
+fi
+
+case "$ACTION" in
+ fetch-db)
+ exec rsync --server --sender -az . /var/lib/aide/aide.db
+ ;;
+ fetch-bin)
+ exec rsync --server --sender -az . /usr/bin/aide
+ ;;
+ fetch-cron)
+ exec rsync --server --sender -az . /etc/cron.daily/aide
+ ;;
+ fetch-conf)
+ exec rsync --server --sender -az . /etc/default/aide
+ ;;
+ copy-db)
+ cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
+ ;;
+ *)
+ echo "FAIL! FAIL! FAIL!"
+esac