#!/usr/bin/python
#
# Plugin to monitor fail2ban blacklists.
# Parses iptables output. Must be run as a user that may do such. Probably root.
#
# Requires: python, probably 2.3 or so :)
# 
# Written by Lasse Karstensen <lasse.karstensen@gmail.com> September 2007.
# Parameters understood:
# 	config   (required)
# 	autoconf (optional)
#
#%# family=auto
#%# capabilities=autoconf

libdir="/usr/share/fail2ban"
iptablesbin="/sbin/iptables"

import sys, os, ConfigParser


def get_fail2ban_checks(configfile="/etc/fail2ban.conf"):
    confReader = ConfigParser.ConfigParser()
    confReader.read(configfile)
    res = []
    for section in confReader.sections():
        # basic configuration, not essential for us so we skip it.
        if section in ["MAIL"]:
            continue
        if confReader.has_option(section, "enabled"):
	    val = confReader.get(section, "enabled")
	    if val.lower() == "true":
	        res.append(section)
    return res

def list_iptables(chain):
    global iptablesbin
    cmd = "%s -n -L fail2ban-%s" % (iptablesbin, chain)
    num = 0
    for line in os.popen(cmd):
        line = line.strip()
	if line.split()[0] == "DROP":
	    num = num + 1
    return num

def print_config():
    # noisy
    print 'graph_title Fail2ban blacklist'
    print 'graph_info This graph shows the number of host blocked by fail2ban.'
    print 'graph_category network'
    print 'graph_vlabel Count'

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

    for checkname in get_fail2ban_checks():
        checkname_sane = checkname_sanitize(checkname)
        print '%s.label Rules in chain %s' % (checkname_sane, checkname_sane)
        print '%s.min 0' % checkname_sane

def checkname_sanitize(name):
    new = ""
    from string import digits, letters
    for char in name:
        if char not in letters+digits:
	    new += "_"
        else:
	    new += char
    return new

def main():
   if len(sys.argv) > 1 and sys.argv[1] == "autoconf":
       if os.path.isdir(libdir):
           print "yes"
	   sys.exit(0)
       else: 
           print "no"
           sys.exit(1)

   sys.path.append(libdir)
   if len(sys.argv) > 1 and sys.argv[1] == "config":
       print_config()
       sys.exit(0)

   for checkname in get_fail2ban_checks():
       num = list_iptables(checkname)
       print "%s.value %s" % (checkname_sanitize(checkname), num)


if __name__ == "__main__": 
    main()
