- Changed Fail2Ban in order to handle several log files

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@50 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.6
Cyril Jaquier 2005-02-18 13:30:54 +00:00
parent 2c778a9b76
commit 2e5bfe5bb6
14 changed files with 298 additions and 169 deletions

View File

@ -4,9 +4,15 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
Fail2Ban (version 0.1.2) 11/21/2004
Fail2Ban (version 0.3.0) 02/??/2005
=============================================================
ver. 0.3.0 (02/??/2005) - alpha
----------
- Re-writting of parts of the code in order to handle several
log files with different rules
- Removed sshd.py because it is no more needed
ver. 0.1.2 (11/21/2004) - beta
----------
- Add ipfw and ipfwadm support. The rules are taken from

View File

@ -12,5 +12,6 @@ firewall/ipfwadm.py
logreader/__init__.py
logreader/logreader.py
logreader/parser.py
logreader/sshd.py
confreader/__init__.py
confreader/configreader.py
config/fail2ban.conf.default

2
README
View File

@ -79,7 +79,7 @@ options:
-b start fail2ban in background
-d start fail2ban in debug mode
-e <INTF> ban IP on the INTF interface
-f <FILE> read password failure from FILE
-c <FILE> read configuration file FILE
-h display this help message
-i <IP(s)> IP(s) to ignore
-l <FILE> log message in FILE

View File

@ -16,10 +16,6 @@ background = false
# and bypass root user test.
debug = false
# pwdfailfile: the path of the file which contains the
# password failure log.
pwdfailfile = /var/log/pwdfail/current
# logfile: the path of the file for logging messages of
# fail2ban.
logfile = /var/log/fail2ban.log
@ -44,3 +40,40 @@ interface = eth0
# log file). 1 is a good value.
polltime = 1
# You can define a new section for each log file to check for
# password failure.
[Apache]
# logfile: file to monitor.
logfile = log-test/apache
# timeregex: regular expression which have to match the
# timestamp of an Apache log event.
# [Wed Jan 05 15:08:01 2005]
timeregex = \S{3} \S{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}
# timepattern: indicates the "timeregex" fields signification.
# See syntax here: http://rgruet.free.fr/PQR2.3.html#timeModule
timepattern = %%a %%b %%d %%H:%%M:%%S %%Y
# failregex: regular expression which have to match the
# message written in the log file in case of password failure.
failregex = authentication failure
[SSH]
# logfile: file to monitor.
logfile = log-test/current
# timeregex: regular expression which have to match the
# timestamp of an Apache log event.
# Mar 7 17:53:28
timeregex = \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}
# timepattern: indicates the "timeregex" fields signification.
# See syntax here: http://rgruet.free.fr/PQR2.3.html#timeModule
timepattern = %%b %%d %%H:%%M:%%S
# failregex: regular expression which have to match the
# message written in the log file in case of password failure.
failregex = Authentication failure

25
confreader/__init__.py Normal file
View File

@ -0,0 +1,25 @@
# This file is part of Fail2Ban.
#
# Fail2Ban 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 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban 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 Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision$
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -24,32 +24,34 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from parser import Parser
import os, sys, time
class Sshd(Parser):
""" OpenSSH daemon log parser. Contains specific code for sshd.
from ConfigParser import *
class ConfigReader:
""" Reads a log file and reports information about IP that make password
failure, bad user or anything else that is considered as doubtful login
attempt.
"""
_instance = None
# This is the pattern to look for.
pattern = "Failed password|Illegal user"
optionValues = ("logfile", "timeregex", "timepattern", "failregex")
def __init__(self, confPath):
self.confPath = confPath
self.configParser = SafeConfigParser()
def openConf(self):
self.configParser.read(self.confPath)
def getSections(self):
return self.configParser.sections()
def getLogOptions(self, sec):
values = dict()
for option in self.optionValues:
v = self.configParser.get(sec, option)
values[option] = v
return values
def getInstance():
""" We use a singleton.
"""
if not Sshd._instance:
Sshd._instance = Sshd()
return Sshd._instance
getInstance = staticmethod(getInstance)
def parseLogLine(self, line):
""" Matches sshd bad login attempt. Returns the IP and the
log time.
"""
if self.getLogMatch(self.pattern, line):
matchIP = self.getLogIP(line)
if matchIP:
return [matchIP, self.getLogTime(line)]
else:
return False

View File

@ -44,6 +44,7 @@ from firewall.ipfw import Ipfw
from firewall.ipfwadm import Ipfwadm
from logreader.logreader import LogReader
from version import version
from confreader.configreader import ConfigReader
def usage():
print "Usage: fail2ban.py [OPTIONS]"
@ -54,7 +55,7 @@ def usage():
print " -b start fail2ban in background"
print " -d start fail2ban in debug mode"
print " -e <INTF> ban IP on the INTF interface"
print " -f <FILE> read password failure from FILE"
print " -c <FILE> read configuration file FILE"
print " -h display this help message"
print " -i <IP(s)> IP(s) to ignore"
print " -l <FILE> log message in FILE"
@ -167,15 +168,12 @@ if __name__ == "__main__":
logSys = log4py.Logger().get_instance()
logSys.set_formatstring("%T %L %M")
# Config file
configParser = SafeConfigParser()
configParser.read("/etc/fail2ban.conf")
conf = dict()
conf["verbose"] = False
conf["background"] = False
conf["debug"] = False
conf["pwdfailfile"] = "/var/log/pwdfail/current"
conf["conffile"] = "/etc/fail2ban.conf"
conf["apachefile"] = "log-test/current"
conf["logging"] = False
conf["logfile"] = "/var/log/fail2ban.log"
conf["maxretry"] = 3
@ -185,6 +183,21 @@ if __name__ == "__main__":
conf["firewall"] = "iptables"
conf["polltime"] = 1
# Reads the command line options.
try:
optList, args = getopt.getopt(sys.argv[1:], 'hvbdc:l:t:i:r:e:w:')
except getopt.GetoptError:
usage()
# Pre-parsing of command line options for the -c option
for opt in optList:
if opt[0] == "-c":
conf["conffile"] = opt[1]
# Config file
configParser = SafeConfigParser()
configParser.read(conf["conffile"])
# background
try:
conf["background"] = configParser.getboolean("DEFAULT", "background")
@ -205,16 +218,6 @@ if __name__ == "__main__":
logSys.warn("debug option not in config file")
logSys.warn("Using default value")
# pwdfailfile
try:
conf["pwdfailfile"] = configParser.get("DEFAULT", "pwdfailfile")
except ValueError:
logSys.warn("pwdfailfile option should be a string")
logSys.warn("Using default value")
except NoOptionError:
logSys.warn("pwdfailfile option not in config file")
logSys.warn("Using default value")
# logfile
try:
conf["logfile"] = configParser.get("DEFAULT", "logfile")
@ -265,7 +268,7 @@ if __name__ == "__main__":
logSys.warn("interface option not in config file")
logSys.warn("Using default value")
# interface
# firewall
try:
conf["firewall"] = configParser.get("DEFAULT", "firewall")
except ValueError:
@ -285,12 +288,6 @@ if __name__ == "__main__":
logSys.warn("polltime option not in config file")
logSys.warn("Using default value")
# Reads the command line options.
try:
optList, args = getopt.getopt(sys.argv[1:], 'hvbdf:l:t:i:r:e:w:')
except getopt.GetoptError:
usage()
for opt in optList:
if opt[0] == "-h":
usage()
@ -302,8 +299,6 @@ if __name__ == "__main__":
conf["debug"] = True
if opt[0] == "-e":
conf["interface"] = opt[1]
if opt[0] == "-f":
conf["pwdfailfile"] = opt[1]
if opt[0] == "-l":
conf["logging"] = True
conf["logfile"] = opt[1]
@ -359,22 +354,35 @@ if __name__ == "__main__":
if not conf["debug"]:
sys.exit(-1)
logSys.debug("logFilePath is "+conf["pwdfailfile"])
logSys.debug("ConfFile is "+conf["conffile"])
logSys.debug("BanTime is "+`conf["bantime"]`)
logSys.debug("retryAllowed is "+`conf["maxretry"]`)
# Reads the config file and create a LogReader instance for
# each log file to check.
confReader = ConfigReader(conf["conffile"]);
confReader.openConf()
logList = list()
for t in confReader.getSections():
l = confReader.getLogOptions(t)
lObj = LogReader(logSys, l["logfile"], l["timeregex"],
l["timepattern"], l["failregex"])
lObj.openLogFile()
logList.append(lObj)
# Creates one instance of Iptables (thanks to Pyhton dynamic
# features) and one of LogReader.
fireWallObj = eval(fireWallName)
fireWall = fireWallObj(conf["bantime"], logSys, conf["interface"])
logFile = LogReader(conf["pwdfailfile"], logSys, conf["bantime"])
# We add 127.0.0.1 to the ignore list has we do not want
# to be ban ourself.
logFile.addIgnoreIP("127.0.0.1")
for element in logList:
element.addIgnoreIP("127.0.0.1")
while len(ignoreIPList) > 0:
ip = ignoreIPList.pop()
logFile.addIgnoreIP(ip)
for element in logList:
element.addIgnoreIP(ip)
logSys.info("Fail2Ban v"+version+" is running")
# Main loop
@ -390,12 +398,19 @@ if __name__ == "__main__":
# If the log file has not been modified since the
# last time, we sleep for 1 second. This is active
# polling so not very effective.
if not logFile.isModified():
isModified = False
for element in logList:
if element.isModified():
isModified = True
if not isModified:
time.sleep(conf["polltime"])
continue
# Gets the failure list from the log file.
failList = logFile.getPwdFailure()
failList = dict()
for element in logList:
failList.update(element.getFailures())
# We iterate the failure list and ban IP that make
# *retryAllowed* login failures.

102
log-test/apache Normal file
View File

@ -0,0 +1,102 @@
[Mon Jan 03 05:02:15 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:20 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:20 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:21 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:22 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:22 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:22 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msadc
[Mon Jan 03 05:02:22 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/\xe0
[Mon Jan 03 05:02:23 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msdac
[Mon Jan 03 05:02:23 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/msdac
[Mon Jan 03 05:02:24 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/PBServer
[Mon Jan 03 05:02:24 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/PBServer
[Mon Jan 03 05:02:27 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/Rpc
[Mon Jan 03 05:02:27 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/Rpc
[Mon Jan 03 05:02:27 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/samples
[Mon Jan 03 05:02:27 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/samples
[Mon Jan 03 05:02:28 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts..\xc1\x9c..
[Mon Jan 03 05:02:28 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:28 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:28 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:32 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:32 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:33 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:33 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:33 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:34 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:34 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:38 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:38 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:38 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:38 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:39 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 05:02:39 2005] [error] [client 81.83.248.17] File does not exist: /var/www/jaquier.dyndns.org/htdocs/scripts
[Mon Jan 03 11:08:29 2005] [error] [client 128.178.150.127] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Mon Jan 03 20:08:52 2005] [error] [client 83.76.202.195] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:19:50 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:19:55 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:01 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:05 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:08 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:12 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:16 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:22 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:26 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:28 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 15:20:38 2005] [error] [client 213.221.138.70] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 20:54:59 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 20:55:04 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 20:55:29 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 21:34:29 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Tue Jan 04 21:34:32 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 00:17:41 2005] [error] [client 217.251.126.37] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 00:18:03 2005] [error] [client 217.251.126.37] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 00:18:12 2005] [error] [client 217.251.126.37] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:24:38 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:24:40 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:24:46 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:24:48 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:25:58 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:26:34 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 01:26:37 2005] [error] [client 81.63.51.202] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 10:13:02 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 10:13:07 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 10:13:10 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 10:17:07 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 14:41:40 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 14:41:45 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 14:41:47 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 14:41:51 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 14:55:30 2005] [error] [client 212.101.4.200] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:03:44 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:03:48 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:03:52 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:03:57 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:06:45 2005] [error] [client 212.101.4.200] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Mar 05 15:07:28 2005] [error] [client 192.168.0.128] user cyril: authentication failure for "/phpinfo": Password Mismatch
[Wed Jan 05 15:08:01 2005] [error] [client 192.168.0.128] user not found: /phpinfo
[Wed Jan 05 15:10:45 2005] [crit] [client 192.168.0.128] (13)Permission denied: /var/www/jaquier.dyndns.org/htdocs/css/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://earth/phpinfo
[Wed Jan 05 15:10:45 2005] [crit] [client 192.168.0.128] (13)Permission denied: /var/www/jaquier.dyndns.org/htdocs/images/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://earth/phpinfo
[Wed Jan 05 15:10:45 2005] [error] [client 192.168.0.128] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:11:09 2005] [error] [client 192.168.0.128] user test not found: /phpinfo
[Wed Jan 05 15:11:10 2005] [error] [client 192.168.0.128] user test not found: /phpinfo
[Wed Jan 06 15:11:11 2005] [error] [client 192.168.0.128] user test not found: /phpinfo
[Wed Jan 06 15:11:13 2005] [error] [client 192.168.0.128] user test not found: /phpinfo
[Wed Jan 06 15:11:14 2005] [error] [client 192.168.0.128] user test not found: /phpinfo
[Wed Jan 05 15:11:15 2005] [crit] [client 192.168.0.128] (13)Permission denied: /var/www/jaquier.dyndns.org/htdocs/css/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://earth/phpinfo
[Wed Jan 05 15:11:15 2005] [crit] [client 192.168.0.128] (13)Permission denied: /var/www/jaquier.dyndns.org/htdocs/images/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://earth/phpinfo
[Wed Jan 05 15:11:15 2005] [error] [client 192.168.0.128] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:12:32 2005] [error] [client 212.101.4.200] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:48 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:51 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:52 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:52 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:54 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:56 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:13:59 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:14:20 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:14:24 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:14:29 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Jan 05 15:14:34 2005] [error] [client 192.168.0.129] File does not exist: /var/www/jaquier.dyndns.org/htdocs/favicon.ico
[Wed Mar 05 15:08:28 2005] [error] [client 192.168.0.128] user cyril: authentication failure for "/phpinfo": Password Mismatch
[Wed Mar 05 15:09:28 2005] [error] [client 192.168.0.128] user cyril: authentication failure for "/phpinfo": Password Mismatch

View File

@ -1,4 +1,5 @@
- Last output repeated 2 times -
Oct 7 11:47:08 [sshd] Failed password for illegal user test from 69.182.27.122 port 34015 ssh2
Oct 7 11:47:09 [sshd] Failed password for illegal user guest from 69.182.27.122 port 34068 ssh2
Oct 7 11:47:11 [sshd] Failed password for illegal user admin from 69.182.27.122 port 34127 ssh2
Jan 7 17:53:15 [sshd] (pam_unix) 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=62.220.137.36 user=kevin
Jan 7 17:53:26 [sshd] (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=62.220.137.36 user=kevin
Mar 7 17:53:28 [sshd] error: PAM: Authentication failure for kevin from 62.220.137.36
Mar 7 17:55:28 [sshd] error: PAM: Authentication failure for kevin from 62.220.137.36
Mar 7 17:57:28 [sshd] error: PAM: Authentication failure for kevin from 62.220.137.36

View File

@ -425,7 +425,8 @@ Oct 7 01:03:12 [sshd] Failed password for illegal user tata from 128.178.164.52
- Last output repeated 2 times -
Oct 7 01:03:20 [sshd] Failed password for illegal user tata from 128.178.164.52 port 37187 ssh2
- Last output repeated 2 times -
Oct 11 11:47:08 [sshd] Failed password for illegal user test from 69.182.27.122 port 34015 ssh2
Oct 11 11:47:09 [sshd] Failed password for illegal user guest from 69.182.27.122 port 34068 ssh2
Oct 11 11:47:11 [sshd] Failed password for illegal user admin from 69.182.27.122 port 34127 ssh2
Oct 12 21:54:11 yellow sshd[16069]: Failed password for cyril from 212.41.79.210 port 29404 ssh2
Nov 14 11:47:08 [sshd] Failed password for illegal user test from 69.182.27.122 port 34015 ssh2
Nov 14 11:47:09 [sshd] Failed password for illegal user guest from 69.182.27.122 port 34068 ssh2
Nov 14 11:47:11 [sshd] Failed password for illegal user admin from 69.182.27.122 port 34127 ssh2
Nov 15 11:12:11 yellow sshd[16069]: Failed password for cyril from 212.41.79.210 port 29404 ssh2
Nov 15 21:54:11 yellow sshd[16069]: Illegal user for cyril from 212.41.79.210 port 29404 ssh2

View File

@ -24,9 +24,7 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import os, sys, time
from sshd import Sshd
import os, sys, time, re
class LogReader:
""" Reads a log file and reports information about IP that make password
@ -34,13 +32,15 @@ class LogReader:
attempt.
"""
def __init__(self, logPath, logSys, findTime = 3600):
def __init__(self, logSys, logPath, timeregex, timepattern, failregex, findTime = 3600):
self.logPath = logPath
self.timeregex = timeregex
self.timepattern = timepattern
self.failregex = failregex
self.findTime = findTime
self.ignoreIpList = []
self.lastModTime = 0
self.logSys = logSys
self.parserList = ["Sshd"]
def addIgnoreIP(self, ip):
""" Adds an IP to the ignore list.
@ -79,30 +79,14 @@ class LogReader:
self.lastModTime = logStats.st_mtime
return True
def matchLine(self, line):
""" Checks if the line contains a pattern. It does this for all
classes specified in *parserList*. We use a singleton to avoid
creating/destroying objects too much.
Return a dict with the IP and number of retries.
"""
for i in self.parserList:
match = eval(i).getInstance().parseLogLine(line)
if match:
return match
return None
def getFailInfo(self, findTime):
""" Gets the failed login attempt. Returns a dict() which contains
IP and the number of retries.
"""
def getFailures(self):
ipList = dict()
logFile = self.openLogFile()
for line in logFile.readlines():
match = self.matchLine(line)
if match:
ip = match[0]
unixTime = match[1]
value = self.findFailure(line)
if value:
ip = value[0]
unixTime = value[1]
if unixTime < time.time()-self.findTime:
continue
if self.inIgnoreIPList(ip):
@ -116,8 +100,34 @@ class LogReader:
logFile.close()
return ipList
def getPwdFailure(self):
""" Executes the getFailInfo method. Not very usefull...
def findFailure(self, line):
match = self.matchLine(line, self.failregex)
if match:
timeMatch = self.matchLine(match.string, self.timeregex)
if timeMatch:
date = self.getUnixTime(timeMatch.group(), self.timepattern)
ipMatch = self.matchAddress(match.string)
if ipMatch:
ip = ipMatch.group()
return [ip, date]
return None
def getUnixTime(self, value, pattern):
date = list(time.strptime(value, pattern))
if date[0] < 2000:
date[0] = time.gmtime()[0]
unixTime = time.mktime(date)
return unixTime
def matchLine(self, line, pattern):
""" Checks if the line contains a pattern. It does this for all
classes specified in *parserList*. We use a singleton to avoid
creating/destroying objects too much.
Return a dict with the IP and number of retries.
"""
failList = self.getFailInfo(self.findTime)
return failList
return re.search(pattern, line)
def matchAddress(self, line):
return re.search("(?:\d{1,3}\.){3}\d{1,3}", line)

View File

@ -1,67 +0,0 @@
# This file is part of Fail2Ban.
#
# Fail2Ban 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 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban 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 Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision$
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import time, re
class Parser:
""" This class is the main log parser class. It should be inherited
by all the service specific classes.
"""
def getLogMatch(self, pattern, line):
""" Returns a match if pattern is found in line.
"""
return re.search(pattern, line)
def getLogIPv4(self, line):
""" Returns IP if one is found in line. Match IPv4 string.
"""
matchIP = re.search("(?:\d{1,3}\.){3}\d{1,3}", line)
if matchIP:
return matchIP.group()
else:
return None
def getLogIP(self, line):
""" Returns IP if one is found in line.
"""
return self.getLogIPv4(line)
def getLogTimeStandard(self, line):
""" Returns the log time of line using a standard log format.
Format: Oct 14 11:47:08
"""
date = list(time.strptime(line[0:15], "%b %d %H:%M:%S"))
date[0] = time.gmtime()[0]
unixTime = time.mktime(date)
return unixTime
def getLogTime(self, line):
""" Returns the log time of line.
"""
return self.getLogTimeStandard(line)

View File

@ -38,5 +38,5 @@ setup(
url = "http://www.sourceforge.net/projects/fail2ban",
scripts = ['fail2ban.py'],
py_modules = ['version'],
packages = ['firewall', 'logreader']
packages = ['firewall', 'logreader', 'confreader']
)

View File

@ -24,4 +24,4 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
version = "0.1.2"
version = "0.3.0-CVS"