#!/bin/sh



# Check fail2ban bans plugin for Nagios.

# Written by Chad Phillips (chad@apartmentlines.com)

# Modified by Sebastian Kirschner (sebastian.kirschner@drahtlos-dsl.de)

# Last Modified: 2010-10-18



FAIL2BAN="/usr/bin/fail2ban-client status "



PROGPATH=`dirname $0`

REVISION=`echo '$Revision: 1.2 $' | sed -e 's/[^0-9.]//g'`

DATETIME=`date "+%Y-%m-%d %H:%M:%S"`

TAB="   "



. $PROGPATH/utils.sh



print_usage() {

    echo "

Usage: check_bans -j <jail> [-b <max_ban>]

Usage: check_bans --help | -h



Description:



This plugin checks a fail2ban server for active bans, and issues

alerts if any defined thresholds are exceeded.  Performance data is also

returned for bans.



Tested to work on Linux.



The following arguments are accepted:



  -j          Name of the jail



  -b              (Optional) Generate a critical message if the defined number

                  of bans is exceeded.



  --help | -h     Print this help and exit.



Examples:



Check bans, with no concern about limits.



  check_bans -j <jail>



Check bans.  Issue a critical if there are more than 15 active bans.



  check_bans -j <jail> -b 15



Caveats:



This plugin calls the fail2ban executable directly, so make sure that the user

executing this script has appropriate permissions!  Usually the fail2ban binary

can only be run by root. To grant the nagios user

permissions to execute the script, try something like the following in your

/etc/sudoers file:

  nagios ALL=(ALL) NOPASSWD: /path/to/plugins/directory/check_bans



Then call the plugin using sudo:

  /path/to/sudo check_bans

"

}



print_help() {

    print_usage

    echo "Check fail2ban bans for jails  plugin for Nagios."

    echo ""

}



# Sets the exit status for the plugin.  This is done in such a way that the

# status can only go in one direction: OK -> WARNING -> CRITICAL.

set_exit_status() {

        new_status=$1

        # Nothing needs to be done if the state is already critical, so exclude

        # that case.

        case $exitstatus

        in

                $STATE_WARNING)

                        # Only upgrade from warning to critical.

                        if [ "$new_status" = "$STATE_CRITICAL" ]; then

                                exitstatus=$new_status;

                        fi

                ;;

                $STATE_OK)

                        # Always update state if current state is OK.

                        exitstatus=$new_status;

                ;;

        esac

}



# Ensures that a call to the failban server returns successfully. Exits

# critical if not.

check_fail2ban_result() {

        if [ "$1" != "0" ]; then

                echo "CRITICAL: $2"

                exit $STATE_CRITICAL

        fi

}



# Defaults.

exitstatus=$STATE_OK

bans_critical=-1



# Grab the command line arguments.

while test -n "$1"; do

    case "$1" in

        --help)

            print_help

            exit $STATE_OK

            ;;

        -h)

            print_help

            exit $STATE_OK

            ;;

    -j)

        jail=$2

        shift

        ;;

        -b)

            bans_critical=$2

            shift

            ;;

        -x)

            exitstatus=$2

            shift

            ;;

        --exitstatus)

            exitstatus=$2

            shift

            ;;

        *)

            echo "Unknown argument: $1"

            print_usage

            exit $STATE_UNKNOWN

            ;;

    esac

    shift

done



if [ "$bans_critical" != "-1" ] && ([ ! "$bans_critical" ] || [ `echo "$bans_critical" | grep [^0-9]` ]); then

        echo "Number of bans critical value must be a number."

        exit $STATE_UNKNOWN

fi





# Fetch the data from fail2ban.

command_output=$FAIL2BAN$jail

check_fail2ban_result $? "$command_output"



# Parse the data

data=`$command_output | tail -n 3`

active_bans=`echo "$data" | cut -d- -f2 | cut -d: -f2 | head -n 1` 



# Test for critical bans.

if [ "$bans_critical" != "-1" ] && [ "$active_bans" -gt "$bans_critical" ]; then

        set_exit_status $STATE_CRITICAL

fi





case $exitstatus

in

        $STATE_CRITICAL)

                exit_message="CRITICAL";

        ;;

        $STATE_WARNING)

                exit_message="WARNING";

        ;;

        $STATE_OK)

                exit_message="OK";

        ;;

        *)

                echo "UNKNOWN"

                exit $STATE_UNKNOWN;



        ;;

esac



echo "${exit_message}: $active_bans active bans | Bans=${active_bans}";



exit $exitstatus




