From 5e92209e5b284e0f0d99c30e555cc498a39c396e Mon Sep 17 00:00:00 2001 From: mh Date: Mon, 12 Oct 2015 23:23:44 +0200 Subject: introduce gpg checks --- files/plugins/check_gpg | 113 ++++++++++++++++++++++++++++++++++++++++++++ manifests/init.pp | 8 ++-- manifests/plugins/gpg.pp | 43 +++++++++++++++++ manifests/service/gpgkey.pp | 43 +++++++++++++++++ 4 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 files/plugins/check_gpg create mode 100644 manifests/plugins/gpg.pp create mode 100644 manifests/service/gpgkey.pp diff --git a/files/plugins/check_gpg b/files/plugins/check_gpg new file mode 100644 index 0000000..bf4b930 --- /dev/null +++ b/files/plugins/check_gpg @@ -0,0 +1,113 @@ +#!/bin/bash +# +# Nagios plugin that checks whether a key ID has expired, or will expire within +# a certain time. +# +# note: the plugin will issue a critical state if the required key has been +# revoked. +# +# usage: check_gpg [-w ] [--gnupg-homedir ] +# +# is any PGP key ID that GnuPG accepts with "gpg --list-key " +# +# The option -w parameter lets you specify the number of days within which key +# expiry will trigger a warning. e.g. if expires within +# days, make nagios issue a warning. +# +# num_days must be an integer value +# +# optionally, if the keyring directory you want GPG to use is not located in +# the user's ~/.gnupg, you can specify the path to the keyring directory with +# the --gnupg-homedir parameter. +# +# Thanks a bunch to Daniel Kahn Gillmor for providing example commands that +# made up most of the core of this plugin. +# +# Copyleft Gabriel Filion +# +# This plugin is released under the GPL v3+ license. To get a copy of the +# license text visit: https://www.gnu.org/licenses/gpl-3.0.txt +# +SECS_IN_DAY=86400 + +function debug () { + if [ -n "$DEBUG" ]; then + echo "$1" >&2 + fi +} + +debug "got args: $*" + +now=$(date +%s) +debug "current timestamp: $now" + +warning_threshold= +homedir= +for arg in $*; do + case $arg in + "-w") + if [ -z "$2" ]; then + echo "UNKNOWN: argument -w got no value. integer needed" + exit 3 + fi + if [ "`echo $2 | egrep ^[[:digit:]]+$`" = "" ]; then + echo "UNKNOWN: invalid value '$2' passed to -w. integer needed" + exit 3 + fi + warning_threshold=$(( $now + ($2*$SECS_IN_DAY) )) + debug "setting warning_threshold to '$warning_threshold'" + + shift 2 + ;; + "--gnupg-homedir") + if [ -z "$2" ]; then + echo "UNKNOWN: argument --gnupg-homedir got no value. path needed" + exit 3 + fi + if [ ! -d "$2" ]; then + echo "UNKNOWN: homedir '$2' does not exist or is not a directory" + exit 3 + fi + homedir="--homedir $2" + debug "setting homedir to '$homedir'" + + shift 2 + ;; + esac +done + +if [ -z "$1" ]; then + echo "UNKNOWN: must provide a key ID" + exit 3 +fi +key="$1" + +# GPG is too stupid to error out when asked to refresh a key that's not in the +# local keyring so we need to perform another call to verify this first. +output=$( { gpg $homedir --list-key "$key" >/dev/null && gpg $homedir --refresh "$key" >/dev/null; } 2>&1 ) +if [ $? -ne 0 ]; then + echo "UNKNOWN: $output" + exit 3 +fi + +if [ "$(gpg $homedir --check-sig "$key" | grep "^rev!")" != "" ]; then + echo "CRITICAL: key '$key' has been revoked!" + exit 1 +fi + +for expiry in $(gpg $homedir --with-colons --fixed-list-mode --list-key "$key" 2>/dev/null | awk -F: '/^pub:/{ print $7 }'); +do + debug "expiry value: $expiry" + + if [ "$now" -gt "$expiry" ] ; then + printf "CRITICAL: %s has expired on %s\n" "$key" "$(date -d "$expiry seconds")"; + exit 1; + fi; + if [ -n "$warning_threshold" ] && [ "$warning_threshold" -gt "$expiry" ]; then + remaining=$(( ($expiry-$now) / $SECS_IN_DAY )) + printf "WARNING: %s expires in %s days\n" "$key" "$remaining"; + exit 2; + fi +done + +echo "OK: key '$key' has not expired." diff --git a/manifests/init.pp b/manifests/init.pp index 7b747d9..e80525e 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -22,6 +22,7 @@ class nagios( $manage_munin = false, $service_atboot = true, $purge_resources = true, + $gpgkey_checks = {}, ) { case $nagios::httpd { 'absent': { } @@ -32,15 +33,16 @@ class nagios( case $::operatingsystem { 'centos': { $cfgdir = '/etc/nagios' - include nagios::centos + include ::nagios::centos } 'debian': { $cfgdir = '/etc/nagios3' - include nagios::debian + include ::nagios::debian } default: { fail("No such operatingsystem: ${::operatingsystem} yet defined") } } if $manage_munin { - include nagios::munin + include ::nagios::munin } + create_resources('nagios::service::gpgkey',$gpgkey_checks) } diff --git a/manifests/plugins/gpg.pp b/manifests/plugins/gpg.pp new file mode 100644 index 0000000..d8c1d40 --- /dev/null +++ b/manifests/plugins/gpg.pp @@ -0,0 +1,43 @@ +# check_gpg from +# https://github.com/lelutin/nagios-plugins/blob/master/check_gpg +class nagios::plugins::gpg { + require ::gnupg + nagios::plugin{'check_gpg': + source => 'nagios/plugins/check_gpg', + } + + $gpg_home = '/var/local/nagios_gpg_homedir' + file{ + $gpg_home: + ensure => 'directory', + owner => nagios, + group => nagios, + mode => '0600', + require => Nagios::Plugin['check_gpg']; + '/etc/cron.daily/update_nagios_gpgkeys': + content => "!#/bin/bash +function exec() { + cmd=\$1 + outout=\$(su - nagios -s /bin/bash -c 'gpg --homedir ${gpg_home} --logger-fd 1 \${cmd}') + if [ \$? -gt 0 ]; then + echo \$output + exit 1 + fi +} + +gpg('--with-fingerprint --list-keys --with-colons') | grep \"^pub\" -A 1 | tail -n 1 | cut -f10 -d\":\" | sort --random-sort | while read key; do + gpg(\"--recv-keys \${key}\") +done +", + owner => root, + group => 0, + mode => '0700', + require => File[$gpg_home]; + } + nagios_command { + 'check_gnupg': + command_line => "\$USER1\$/check_gpg --gnupg-homedir ${gpg_home} -w \$ARG1\$ \$ARG2\$", + require => Nagios::Plugin['check_gpg'], + } +} + diff --git a/manifests/service/gpgkey.pp b/manifests/service/gpgkey.pp new file mode 100644 index 0000000..0c271f4 --- /dev/null +++ b/manifests/service/gpgkey.pp @@ -0,0 +1,43 @@ +# define a gpgkey to be watched +define nagios::service::gpgkey( + $ensure = 'present', + $warning = '14', + $key_info = undef, +){ + validate_slength($name,40,40) + require ::nagios::plugins::gpg + $gpg_home = $nagios::plugins::gpg::gpg_home + + exec{"manage_key_${name}": } + nagios::service{ + "check_gpg_${name}": + ensure => $ensure; + } + + if $ensure == 'present' { + Exec["manage_key_${name}"]{ + command => "gpg --homedir ${gpg_home} --recv-keys ${name}", + unless => "gpg --homedir ${gpg_home} --list-keys ${name}", + before => Nagios::Service["check_gpg_${name}"], + } + + Nagios::Service["check_gpg_${name}"]{ + check_command => "check_gpg!${warning}!${name}", + } + if $key_info { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name} - Info: ${key_info}", + } + } else { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name}", + } + } + } else { + Exec["manage_key_${name}"]{ + command => "gpg --batch --homedir ${gpg_home} --delete-key ${name}", + onlyif => "gpg --homedir ${gpg_home} --list-keys ${name}", + require => Nagios::Service["check_gpg_${name}"], + } + } +} -- cgit v1.2.3