#!/usr/bin/env python # encoding: utf-8 # # fail2ban-subnets, ban subnets from which IP are repeat offenders # # Copyright (C) 2015 Raphaƫl Beamonte # # This file is part of TraktForVLC. TraktForVLC 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, version 2. # # 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, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # or see . from datetime import datetime import glob import gzip import logging import os.path import re import subprocess import time # Path of logfile to analyze (accepts jokers) filepath = '/var/log/fail2ban.log*' # Maximum time to look back for our analyze findtime = 4 * 4 * 7 * 86400 # Maximum number of bans in the period before reporting the range maxretry = 50 # Minimum number of ips in the incriminated range min_ips = 5 # Time format used in fail2ban logs timeformat = '%Y-%m-%d %H:%M:%S,%f' # Whether or not to exclude from report already banned subnets. # This prevents the 'already banned' messages in fail2ban logs, # it could however let a delay before banning again those ranges # after restarting fail2ban. A larger findtime option in the subnets # jail is recommanded when this option is activated. excludeban = True # Jail used in fail2ban for this script subnetsjail = 'subnets' # List of jails we don't want to match (for instance if you use recidive) donotmatchjail = [ 'recidive', ] # Fail regex to use to check if a line matches. Variables %(time)s # and %(donotmatchjail)s can be used to insert previously mentionned # parameters. failregex = ('%(time)s fail2ban\.actions(?:[\s\t]*\[[0-9]+\])?:' + '(?: [A-Z]+)?[\s\t]+\[(?!%(donotmatchjail)s\])(?P.*)\] ' + 'Ban (?P(?:[0-9]{1,3}\.){3}[0-9]{1,3})$') # Where to store this scripts' logfile logfile = '/var/log/fail2ban-subnets.log' ###### ###### END OF CONFIGURATION ###### ## Version __version_info__ = (0, 2, 0, '', 0) __version__ = "%d.%d.%d%s" % __version_info__[:4] ## Initialize logging logging.basicConfig( format="%(asctime)s %(name)s: %(levelname)s %(message)s", level=logging.INFO, filename=logfile) logger = logging.getLogger(os.path.basename(__file__)) # To humanize time def human_readable_time(secs): mins, secs = divmod(secs, 60) hours, mins = divmod(mins, 60) days, hours = divmod(hours, 24) weeks, days = divmod(days, 7) readable = [] for t, s in ( (weeks, 'weeks'), (days, 'days'), (hours, 'hours'), (mins, 'mins'), (secs, 'secs'), ): if t: readable.append('%d %s' % (t, s)) return ' '.join(readable) logger.info("started with an analysis over %s" % human_readable_time(findtime)) # Function to log the subnets to ban def logban(ipsubnet): data = { 'ban': ipsubnet['ban'], 'subnet': '%s/%s' % ipsubnet['subnet'], 'ipn': ipsubnet['ipn'], 'iplist': ipsubnet['iplist'], } logger.warning("subnet %(subnet)s has been banned " "%(ban)d times with %(ipn)d ips" % data) ## TIME REGEX PREPARATION timereplace = { '%Y': '[0-9]{4}', '%m': '(?:0?[0-9]|1[0-2])', '%d': '(?:[0-2]?[0-9]|3[0-1])', '%H': '(?:[0-1]?[0-9]|2[0-3])', '%M': '(?:[0-5]?[0-9])', '%S': '(?:[0-5]?[0-9])', '%f': '[0-9]{3}', } timeregex_txt = '(?P