diff options
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | files/openssl_test_file | 1 | ||||
-rwxr-xr-x | run.sh | 87 | ||||
-rw-r--r-- | utils/echo | 54 | ||||
-rw-r--r-- | utils/identify | 55 | ||||
-rw-r--r-- | utils/syscheck | 48 |
6 files changed, 251 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..2124dd0 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +Distributed configuration tool +============================== +This is tool for distributed configuration. It provides the way to distribute +configuration trough git to every host. + +It's a set of shell scripts intended for setting hosts. diff --git a/files/openssl_test_file b/files/openssl_test_file new file mode 100644 index 0000000..4de8759 --- /dev/null +++ b/files/openssl_test_file @@ -0,0 +1 @@ +U2FsdGVkX1/PZaRNKDDLHnuGz2rsTJZY/CdJVs90ktI= @@ -0,0 +1,87 @@ +#!/bin/sh +set -e + +# Go to root directory +cd "$(dirname $0)" +# Include utilities +. utils/echo + +REQ_OPS= + +while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + # TODO + ;; + --verbose|-v) + echo_verbose + 1 + ;; + --quiet|-q) + echo_verbose - 1 + ;; + --operation|-o) + shift + REQ_OPS="$REQ_OPS $1" + ;; + --key) + KEY_FILE="" + ;; + esac + shift +done + +# Load host configuration +[ -f hosts/"$(hostname)" ] || echo_die "No configuration for host $(hostname) found." +. hosts/"$(hostname)" + +# Run system sanity checks +. utils/syscheck +# Identify some variables from system +. utils/identify + +# Include enabled operations +for OPT in $OPERATIONS; do + if [ -f ops/"$OPT" ]; then + . ops/"$OPT" + else + echo_die "No operation $OPT." + fi +done + +# TODO do we want to have some explicit sorting? + +# Check if operations need some update +if [ -z "$REQ_OPS" ]; then + for OPT in $OPERATIONS; do + if ! "$OPT"_check; then + echo_info "Scheduled: $OPT" + REQ_OPS="$REQ_OPS $OPT" + fi + done +fi +if [ -z "$REQ_OPS" ]; then + echo_info "All operations are in check." + exit +fi + +# Run preparations +for OPT in $REQ_OPS; do + if "$OPT"_prepare; then + PREP_OPS="$PREP_OPS $OPT" + else + echo_error "Preparation failed for $OPT. Skipping." + fi +done + +# Now apply operations +for OPT in $PREP_OPS; do + if ! "$OPT"_apply; then + echo_error "Operation $OPT application failed! Please check what happened." + break + fi +done + +# And at the end run cleanups on all operations we ever executed +for OPT in $REQ_OPS; do + "$OPT"_clean || echo_warn "Cleanup of operation $OPT failed." +done diff --git a/utils/echo b/utils/echo new file mode 100644 index 0000000..c936f63 --- /dev/null +++ b/utils/echo @@ -0,0 +1,54 @@ +# vim:ft=sh:noexpandtab +# Various echo functions + +ECHO_VERBOSE=0 + +echo_info() { + set +x + [ $ECHO_VERBOSE -ge 0 ] || return + echo -e "\e[1;34m$@\e[0m" >&2 + [ $ECHO_VERBOSE -lt 3 ] || set -x +} + +echo_warn() { + set +x + [ $ECHO_VERBOSE -ge -1 ] || return + echo -e "\e[1;33m$@\e[0m" >&2 + [ $ECHO_VERBOSE -lt 3 ] || set -x +} + +echo_error() { + set +x + [ $ECHO_VERBOSE -ge -2 ] || return + echo -e "\e[1;31m$@\e[0m" >&2 + [ $ECHO_VERBOSE -lt 3 ] || set -x +} + +echo_die() { + set +x + if [ $ECHO_VERBOSE -ge -2 ]; then + echo -e "\e[1;31m$@\e[0m" >&2 + fi + [ $ECHO_VERBOSE -lt 3 ] || set -x + # Suicide + kill $$ +} + +echo_dbg() { + set +x + [ $ECHO_VERBOSE -ge 1 ] || return + echo -e "\e[1;90m$@\e[0m" >&2 + [ $ECHO_VERBOSE -lt 3 ] || set -x +} + +echo_trace() { + set +x + [ $ECHO_VERBOSE -ge 2 ] || return + echo -e "\e[1;90m$@\e[0m" >&2 + [ $ECHO_VERBOSE -lt 3 ] || set -x +} + +echo_verbose() { + ECHO_VERBOSE=$(expr $ECHO_VERBOSE $1 $2) + [ $ECHO_VERBOSE -ge 3 ] && set -x || set +x +} diff --git a/utils/identify b/utils/identify new file mode 100644 index 0000000..2223d8f --- /dev/null +++ b/utils/identify @@ -0,0 +1,55 @@ +# vim:ft=sh:noexpandtab +# Identify and set some variables that can be used later by operations + +# Variables: +# DC_OS - Operation system kernel name (uname -s) +# DC_OS_VERSION - Version of kernel used (uname -r) +# DC_ARCH - Machine architecture (uname -m) +# DC_DISTRIBUTION - Distribution of operation system +# DC_INIT - Init system used (service manager) +# On Archlinux: +# DC_PACAUR - This is set to "true" if pacaur is installed on archlinux + +DC_OS="$(uname -s)" +DC_OS_VERSION="$(uname -r)" +DC_ARCH="$(uname -m)" + +if [ "$DC_OS" = "Linux" ]; then + if [ -f /etc/arch-release ]; then + DC_DISTRIBUTION="arch" + elif [ -f /etc/turris-version ]; then + DC_DISTRIBUTION="turris" + elif [ -f /etc/os-release ]; then + # Use as DISTRIBUTION ID field + DC_DISTRIBUTION="$(sed -nE 's/^ID=(.*)/\1/p' /etc/os-release)" + else + DC_DISTRIBUTION="unknown" + fi + # Identify init (only systemd and openrc are supported on linux) + if pidof systemd >/dev/null; then + # Systemd is running on accessed machine + DC_INIT="systemd" + elif pidof procd >/dev/null; then + DC_INIT="procd" + elif rc-status -v 2>/dev/null >/dev/null; then + DC_INIT="openrc" + else + DC_INIT="unknown" + fi + echo_dbg "Detected Linux. Distribution $DC_DISTRIBUTION. With $DC_INIT init system." +elif [ "$DC_OS" = "FreeBSD" ]; then + DC_DISTRIBUTION="FreeBSD" # This makes no sense on FreeBSD so set same as OS + DC_INIT="FreeBSD" + echo_dbg "Detected FreeBSD." +else + echo_die "Unknown or unsupported kernel detected on accessed machine." +fi + +# Archlinux +DC_PACAUR=false +if [ "$DC_DISTRIBUTION" = "arch" ]; then + if which pacaur >/dev/null; then + DC_PACAUR=true + echo_dbg "Accessed machine has pacaur" + fi +fi diff --git a/utils/syscheck b/utils/syscheck new file mode 100644 index 0000000..a0c29a0 --- /dev/null +++ b/utils/syscheck @@ -0,0 +1,48 @@ +# vim:ft=sh:noexpandtab +# System sanity checks + +# Check that we are root (this tool can be run only as root) +# TODO uncomment +# [ "$(id -u)" = "0" ] || echo_die "Distconfig have to be run as root." + +# We have sudo or su +which sudo >/dev/null || which su >/dev/null || echo_die "There is no sudo or su command." + +# Check that we are not using csh or tcsh +# Note: variable shell should be defined only on csh or tcsh (note lowercase) +[ -z "$shell" ] || echo_die "Distconfig doesn't support csh nor tcsh." + +# Check that we have gpg +which gpg >/dev/null || echo_die "There is no gpg command." + +# Check that trunk is signed using correct key +# TODO + +# Check root owner (should be root) +# TODO uncomment +#[ "$(stat -c '%u')" = 0 ] || echo_die "Root directory of distconfig isn't owned by root! Investigate why!" + +# Check access right to root (only root should have access) +# TODO uncomment +#[ "$(stat -c '%a')" = "700" ] || echo_die "Root directory of distconfig has incorect access rights. 700 expected!" + +# Check that we have openssl +which openssl >/dev/null || echo_die "There is no openssl command." + +# Check that we can decrypt using openssl and aes-192-cbc +OPENSSL_TEST_PASSWORD="XduF2T_opDknbzN0EyJJCBFyS1i6yaBU5Beb6IZkFVHWZGWOIZCF1Cc0zrupjEaV" +[ "$(openssl aes-192-cbc -d -a -k "$OPENSSL_TEST_PASSWORD" < files/openssl_test_file)" = "It works!" ] || \ + echo_die "Test message couldn't been decrypted." + +# Check that we have key file +[ -n "$KEY_FILE" ] || echo_die "No key specified. Please pass --key." + +# Check that given key works with our machinery +# TODO + +# Check that we have internet connection +DC_INTERNET=true +if ! ping -c 5 -w 30 cynerd.cz >/dev/null; then + echo_warn "No internet connection detected. All operations requiring internet connection will be skipped" + DC_INTERNET=false +fi |