#!/bin/bash
#
# Plugin to monitor the number of hosts in /etc/hosts.deny
# that are denied access to sshd

# Copyright (C) 2010 Lothar Schmidt, l.munin@scarydevilmonastery.net
#                                    Bushmills on #munin, irc.freenode.net
#                                    latest versions on http://scarydevilmonastery.net/munin.cgi
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of    
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# ------------------------------------------------------------------------------------------------------
# 20100310  v1.01  ls
#               as threatened, shows now "temperatures" of active hosts.deny lines. Recent additions are 
#               displayed in bright red, turning to blue as older the addition rules are.
#               This requires denyhosts to add line to hosts.deny in a specific format. Also, times are currently
#               hardcoded, and not a lot of flexibility adjusting them through parameters.
#               A line in hosts.deny should come with a comment, looking like:
#               # DenyHosts: Sat Mar  6 01:11:57 2010 | sshd: 87.101.51.198
#               8 graphs are drawn from that depicting number of rules in 24 h increments. Different colours are
#               assigned to graphs which are <24h, 24-48h, 48-72h ... old. The last (coldest) graph shows rules 
#               which have been added > 168h ago.
#               I'm considerering to change age granularity to hours, rather than days, and plot many graphs (64 or 128,
#               which are nice for colour calculations), showing more of a colour cloud than discernible areas. 
#               The plugin must have permission to read /etc/hosts.deny, of course.
# 20100308, v1.0, ls 
#               Will probably add multiple stacked graphs, indicative for addition/removal date of denies,
#               instead of a boring single area graph.
# ------------------------------------------------------------------------------------------------------

#%# family=manual
#%# capabilities=autoconf

# ------------------------------------------------------------------------------------------------------
DENY="/etc/hosts.deny"
STATEDIR="/var/lib/munin/plugin-state"                       # directory where plugin can keep their working files
NAME="$(basename $0)"                                        # component of naming temporary files
STATEFILE="$STATEDIR/$NAME.state"
COLOUR=(FF0000 DA0024 B60048 91006D 6D0091 4800B6 2400DA 0000FF)  # hot to cold colours
# ------------------------------------------------------------------------------------------------------

run_autoconf()  {
        RUN="no"
        which grep denyhosts basename > /dev/null && RUN="yes"             # only run when grep and denyhost are present
        echo "$RUN"
}


run_config()  {
cat << EOF
graph_title denied sshd access in $DENY
graph_args --base 1000 -l 0
graph_vlabel Hosts denied
graph_category services
age0.label added last 24h
age0.draw AREA
age0.colour ${COLOUR[0]}
EOF
for AGE in {1..7}; do
cat << EOF
age${AGE}.label older than $((AGE*24))h
age${AGE}.draw STACK
age${AGE}.colour ${COLOUR[$AGE]}
EOF
done
}


run_fetch()   {
   TOTAL=0
   NOW=$(date +%s)
   sed -n 's/^\# DenyHosts: //;s/ | .*//gp' $DENY |         # strip all but date
   while read DATE; do 
      echo $(((NOW - $(date -d "$DATE" +%s))/86400))        # calculate rule age
   done > $STATEFILE                                        # rather than going through temp file, the age could be
   for AGE in {0..6} ; do                                   # used to increment an array element with that index.
      COUNT="$(grep -c "^$AGE$" $STATEFILE)"                # That'd save grepping for counting from temp file.
      echo "age${AGE}.value $COUNT"                         # produce values for all but oldest
      ((TOTAL+=COUNT))
   done
   echo "age7.value $(($(grep -c . $STATEFILE)-TOTAL))"     # all non-printed are older
   rm $STATEFILE
}

run_${1:-"fetch"}
exit 0
