#!@@BASH@@
# -*- sh -*-
: <<=cut

=head1 NAME

fail2ban - Plugin to monitor fail2ban blacklists

=head1 APPLICABLE SYSTEMS

All systems with "bash" and "fail2ban"

=head1 CONFIGURATION

The following is the default configuration

  [fail2ban]
  env.client /usr/bin/fail2ban-client
  env.config_dir /etc/fail2ban

The user running this plugin needs read and write access to the
fail2ban communications socket.  You will need to add this:

  [fail2ban]
  user root

Warning or critical thresholds can be configured via environment
variables either globally ("warning" and "critical")) or separately for
each field ("foo_warning" or "foo_critical").

=head1 INTERPRETATION

This plugin shows a graph with one line per active fail2ban jail, each
showing the number of blacklisted addresses for that jail.

In addition, a line with the total number of blacklisted addresses is
displayed.

=head1 MAGIC MARKERS

  #%# family=auto
  #%# capabilities=autoconf

=head1 VERSION

  1.0.20090423

=head1 BUGS

Needs bash, due zo using bashisms to avoid running external programs.

=head1 AUTHOR

Stig Sandbeck Mathisen <ssm@fnord.no>

=head1 LICENSE

GPLv2

=cut

. "$MUNIN_LIBDIR/plugins/plugin.sh"

##############################
# Configurable variables
client=${client:-/usr/bin/fail2ban-client}
config_dir=${config_dir:-/etc/fail2ban}

##############################
# Functions

# Run fail2ban
run_fail2ban() {
    "$client" -c "$config_dir" "$@"
}

# List jails, one on each line
list_jails() {
    run_fail2ban status | while read -r line; do
        case $line in
            *'Jail list:'*)
                line="${line##*Jail list*:}"
                line="${line//[ $'\t']/}"
                if [ -n "$line" ]; then echo "${line//,/$'\n'}"; fi
                ;;
        esac
    done
}

# Print the munin values
values() {
    list_jails | while read -r jail; do
        run_fail2ban status "$jail" | while read -r line; do
            case $line in
                *'Currently banned'*)
                    line="${line##*Currently banned:}"
                    num="${line//[ $'\t']/}"
                    fieldname=$(clean_fieldname "$jail")
                    echo "${fieldname}.value $num"
                    ;;
            esac
        done
    done
}

# Print the munin config
config() {
    echo 'graph_title Hosts blacklisted by fail2ban'
    echo 'graph_info This graph shows the number of host blacklisted by fail2ban'
    echo 'graph_category network'
    echo 'graph_vlabel Number of hosts'

    echo 'graph_args --base 1000 -l 0'
    echo 'graph_total total'

    list_jails | while read -r jail; do
        fieldname=$(clean_fieldname "$jail")
        echo "${fieldname}.label $jail"
        print_thresholds "${fieldname}" warning critical
    done
}

# Print autoconfiguration hint
autoconf() {
    if [ -e "$client" ]; then
        if [ -x "$client" ]; then
            if run_fail2ban ping >/dev/null; then
                echo "yes"
            else
                echo "no (fail2ban-server does not respond to ping)"
            fi
        else
            echo "no (${client} is not executable)"
        fi
    else
        echo "no (${client} not found)"
    fi
    exit
}

##############################
# Main

case $1 in
    config)
        config
        ;;
    autoconf)
        autoconf
        ;;
    *)
        values
        ;;
esac
