mirror of https://github.com/fail2ban/fail2ban
- 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-b1dcaea8d6050.6
parent
2c778a9b76
commit
2e5bfe5bb6
|
@ -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
|
ver. 0.1.2 (11/21/2004) - beta
|
||||||
----------
|
----------
|
||||||
- Add ipfw and ipfwadm support. The rules are taken from
|
- Add ipfw and ipfwadm support. The rules are taken from
|
||||||
|
|
3
MANIFEST
3
MANIFEST
|
@ -12,5 +12,6 @@ firewall/ipfwadm.py
|
||||||
logreader/__init__.py
|
logreader/__init__.py
|
||||||
logreader/logreader.py
|
logreader/logreader.py
|
||||||
logreader/parser.py
|
logreader/parser.py
|
||||||
logreader/sshd.py
|
confreader/__init__.py
|
||||||
|
confreader/configreader.py
|
||||||
config/fail2ban.conf.default
|
config/fail2ban.conf.default
|
||||||
|
|
2
README
2
README
|
@ -79,7 +79,7 @@ options:
|
||||||
-b start fail2ban in background
|
-b start fail2ban in background
|
||||||
-d start fail2ban in debug mode
|
-d start fail2ban in debug mode
|
||||||
-e <INTF> ban IP on the INTF interface
|
-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
|
-h display this help message
|
||||||
-i <IP(s)> IP(s) to ignore
|
-i <IP(s)> IP(s) to ignore
|
||||||
-l <FILE> log message in FILE
|
-l <FILE> log message in FILE
|
||||||
|
|
|
@ -16,10 +16,6 @@ background = false
|
||||||
# and bypass root user test.
|
# and bypass root user test.
|
||||||
debug = false
|
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
|
# logfile: the path of the file for logging messages of
|
||||||
# fail2ban.
|
# fail2ban.
|
||||||
logfile = /var/log/fail2ban.log
|
logfile = /var/log/fail2ban.log
|
||||||
|
@ -44,3 +40,40 @@ interface = eth0
|
||||||
# log file). 1 is a good value.
|
# log file). 1 is a good value.
|
||||||
polltime = 1
|
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
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
@ -24,32 +24,34 @@ __date__ = "$Date$"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from parser import Parser
|
import os, sys, time
|
||||||
|
|
||||||
class Sshd(Parser):
|
from ConfigParser import *
|
||||||
""" OpenSSH daemon log parser. Contains specific code for sshd.
|
|
||||||
|
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
|
optionValues = ("logfile", "timeregex", "timepattern", "failregex")
|
||||||
# This is the pattern to look for.
|
|
||||||
pattern = "Failed password|Illegal user"
|
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
|
|
77
fail2ban.py
77
fail2ban.py
|
@ -44,6 +44,7 @@ from firewall.ipfw import Ipfw
|
||||||
from firewall.ipfwadm import Ipfwadm
|
from firewall.ipfwadm import Ipfwadm
|
||||||
from logreader.logreader import LogReader
|
from logreader.logreader import LogReader
|
||||||
from version import version
|
from version import version
|
||||||
|
from confreader.configreader import ConfigReader
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print "Usage: fail2ban.py [OPTIONS]"
|
print "Usage: fail2ban.py [OPTIONS]"
|
||||||
|
@ -54,7 +55,7 @@ def usage():
|
||||||
print " -b start fail2ban in background"
|
print " -b start fail2ban in background"
|
||||||
print " -d start fail2ban in debug mode"
|
print " -d start fail2ban in debug mode"
|
||||||
print " -e <INTF> ban IP on the INTF interface"
|
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 " -h display this help message"
|
||||||
print " -i <IP(s)> IP(s) to ignore"
|
print " -i <IP(s)> IP(s) to ignore"
|
||||||
print " -l <FILE> log message in FILE"
|
print " -l <FILE> log message in FILE"
|
||||||
|
@ -167,15 +168,12 @@ if __name__ == "__main__":
|
||||||
logSys = log4py.Logger().get_instance()
|
logSys = log4py.Logger().get_instance()
|
||||||
logSys.set_formatstring("%T %L %M")
|
logSys.set_formatstring("%T %L %M")
|
||||||
|
|
||||||
# Config file
|
|
||||||
configParser = SafeConfigParser()
|
|
||||||
configParser.read("/etc/fail2ban.conf")
|
|
||||||
|
|
||||||
conf = dict()
|
conf = dict()
|
||||||
conf["verbose"] = False
|
conf["verbose"] = False
|
||||||
conf["background"] = False
|
conf["background"] = False
|
||||||
conf["debug"] = False
|
conf["debug"] = False
|
||||||
conf["pwdfailfile"] = "/var/log/pwdfail/current"
|
conf["conffile"] = "/etc/fail2ban.conf"
|
||||||
|
conf["apachefile"] = "log-test/current"
|
||||||
conf["logging"] = False
|
conf["logging"] = False
|
||||||
conf["logfile"] = "/var/log/fail2ban.log"
|
conf["logfile"] = "/var/log/fail2ban.log"
|
||||||
conf["maxretry"] = 3
|
conf["maxretry"] = 3
|
||||||
|
@ -185,6 +183,21 @@ if __name__ == "__main__":
|
||||||
conf["firewall"] = "iptables"
|
conf["firewall"] = "iptables"
|
||||||
conf["polltime"] = 1
|
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
|
# background
|
||||||
try:
|
try:
|
||||||
conf["background"] = configParser.getboolean("DEFAULT", "background")
|
conf["background"] = configParser.getboolean("DEFAULT", "background")
|
||||||
|
@ -204,16 +217,6 @@ if __name__ == "__main__":
|
||||||
except NoOptionError:
|
except NoOptionError:
|
||||||
logSys.warn("debug option not in config file")
|
logSys.warn("debug option not in config file")
|
||||||
logSys.warn("Using default value")
|
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
|
# logfile
|
||||||
try:
|
try:
|
||||||
|
@ -265,7 +268,7 @@ if __name__ == "__main__":
|
||||||
logSys.warn("interface option not in config file")
|
logSys.warn("interface option not in config file")
|
||||||
logSys.warn("Using default value")
|
logSys.warn("Using default value")
|
||||||
|
|
||||||
# interface
|
# firewall
|
||||||
try:
|
try:
|
||||||
conf["firewall"] = configParser.get("DEFAULT", "firewall")
|
conf["firewall"] = configParser.get("DEFAULT", "firewall")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -285,12 +288,6 @@ if __name__ == "__main__":
|
||||||
logSys.warn("polltime option not in config file")
|
logSys.warn("polltime option not in config file")
|
||||||
logSys.warn("Using default value")
|
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:
|
for opt in optList:
|
||||||
if opt[0] == "-h":
|
if opt[0] == "-h":
|
||||||
usage()
|
usage()
|
||||||
|
@ -302,8 +299,6 @@ if __name__ == "__main__":
|
||||||
conf["debug"] = True
|
conf["debug"] = True
|
||||||
if opt[0] == "-e":
|
if opt[0] == "-e":
|
||||||
conf["interface"] = opt[1]
|
conf["interface"] = opt[1]
|
||||||
if opt[0] == "-f":
|
|
||||||
conf["pwdfailfile"] = opt[1]
|
|
||||||
if opt[0] == "-l":
|
if opt[0] == "-l":
|
||||||
conf["logging"] = True
|
conf["logging"] = True
|
||||||
conf["logfile"] = opt[1]
|
conf["logfile"] = opt[1]
|
||||||
|
@ -359,22 +354,35 @@ if __name__ == "__main__":
|
||||||
if not conf["debug"]:
|
if not conf["debug"]:
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
logSys.debug("logFilePath is "+conf["pwdfailfile"])
|
logSys.debug("ConfFile is "+conf["conffile"])
|
||||||
logSys.debug("BanTime is "+`conf["bantime"]`)
|
logSys.debug("BanTime is "+`conf["bantime"]`)
|
||||||
logSys.debug("retryAllowed is "+`conf["maxretry"]`)
|
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
|
# Creates one instance of Iptables (thanks to Pyhton dynamic
|
||||||
# features) and one of LogReader.
|
# features) and one of LogReader.
|
||||||
fireWallObj = eval(fireWallName)
|
fireWallObj = eval(fireWallName)
|
||||||
fireWall = fireWallObj(conf["bantime"], logSys, conf["interface"])
|
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
|
# We add 127.0.0.1 to the ignore list has we do not want
|
||||||
# to be ban ourself.
|
# to be ban ourself.
|
||||||
logFile.addIgnoreIP("127.0.0.1")
|
for element in logList:
|
||||||
|
element.addIgnoreIP("127.0.0.1")
|
||||||
while len(ignoreIPList) > 0:
|
while len(ignoreIPList) > 0:
|
||||||
ip = ignoreIPList.pop()
|
ip = ignoreIPList.pop()
|
||||||
logFile.addIgnoreIP(ip)
|
for element in logList:
|
||||||
|
element.addIgnoreIP(ip)
|
||||||
|
|
||||||
logSys.info("Fail2Ban v"+version+" is running")
|
logSys.info("Fail2Ban v"+version+" is running")
|
||||||
# Main loop
|
# Main loop
|
||||||
|
@ -390,12 +398,19 @@ if __name__ == "__main__":
|
||||||
# If the log file has not been modified since the
|
# If the log file has not been modified since the
|
||||||
# last time, we sleep for 1 second. This is active
|
# last time, we sleep for 1 second. This is active
|
||||||
# polling so not very effective.
|
# 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"])
|
time.sleep(conf["polltime"])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Gets the failure list from the log file.
|
# 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
|
# We iterate the failure list and ban IP that make
|
||||||
# *retryAllowed* login failures.
|
# *retryAllowed* login failures.
|
||||||
|
|
|
@ -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
|
|
@ -1,4 +1,5 @@
|
||||||
- Last output repeated 2 times -
|
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
|
||||||
Oct 7 11:47:08 [sshd] Failed password for illegal user test from 69.182.27.122 port 34015 ssh2
|
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
|
||||||
Oct 7 11:47:09 [sshd] Failed password for illegal user guest from 69.182.27.122 port 34068 ssh2
|
Mar 7 17:53:28 [sshd] error: PAM: Authentication failure for kevin from 62.220.137.36
|
||||||
Oct 7 11:47:11 [sshd] Failed password for illegal user admin from 69.182.27.122 port 34127 ssh2
|
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
|
||||||
|
|
|
@ -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 -
|
- 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
|
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 -
|
- 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
|
Nov 14 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
|
Nov 14 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
|
Nov 14 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 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
|
||||||
|
|
|
@ -24,9 +24,7 @@ __date__ = "$Date$"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import os, sys, time
|
import os, sys, time, re
|
||||||
|
|
||||||
from sshd import Sshd
|
|
||||||
|
|
||||||
class LogReader:
|
class LogReader:
|
||||||
""" Reads a log file and reports information about IP that make password
|
""" Reads a log file and reports information about IP that make password
|
||||||
|
@ -34,13 +32,15 @@ class LogReader:
|
||||||
attempt.
|
attempt.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, logPath, logSys, findTime = 3600):
|
def __init__(self, logSys, logPath, timeregex, timepattern, failregex, findTime = 3600):
|
||||||
self.logPath = logPath
|
self.logPath = logPath
|
||||||
|
self.timeregex = timeregex
|
||||||
|
self.timepattern = timepattern
|
||||||
|
self.failregex = failregex
|
||||||
self.findTime = findTime
|
self.findTime = findTime
|
||||||
self.ignoreIpList = []
|
self.ignoreIpList = []
|
||||||
self.lastModTime = 0
|
self.lastModTime = 0
|
||||||
self.logSys = logSys
|
self.logSys = logSys
|
||||||
self.parserList = ["Sshd"]
|
|
||||||
|
|
||||||
def addIgnoreIP(self, ip):
|
def addIgnoreIP(self, ip):
|
||||||
""" Adds an IP to the ignore list.
|
""" Adds an IP to the ignore list.
|
||||||
|
@ -79,30 +79,14 @@ class LogReader:
|
||||||
self.lastModTime = logStats.st_mtime
|
self.lastModTime = logStats.st_mtime
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def matchLine(self, line):
|
def getFailures(self):
|
||||||
""" 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.
|
|
||||||
"""
|
|
||||||
ipList = dict()
|
ipList = dict()
|
||||||
logFile = self.openLogFile()
|
logFile = self.openLogFile()
|
||||||
for line in logFile.readlines():
|
for line in logFile.readlines():
|
||||||
match = self.matchLine(line)
|
value = self.findFailure(line)
|
||||||
if match:
|
if value:
|
||||||
ip = match[0]
|
ip = value[0]
|
||||||
unixTime = match[1]
|
unixTime = value[1]
|
||||||
if unixTime < time.time()-self.findTime:
|
if unixTime < time.time()-self.findTime:
|
||||||
continue
|
continue
|
||||||
if self.inIgnoreIPList(ip):
|
if self.inIgnoreIPList(ip):
|
||||||
|
@ -115,9 +99,35 @@ class LogReader:
|
||||||
ipList[ip] = (1, unixTime)
|
ipList[ip] = (1, unixTime)
|
||||||
logFile.close()
|
logFile.close()
|
||||||
return ipList
|
return ipList
|
||||||
|
|
||||||
|
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 getPwdFailure(self):
|
def matchLine(self, line, pattern):
|
||||||
""" Executes the getFailInfo method. Not very usefull...
|
""" 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 re.search(pattern, line)
|
||||||
return failList
|
|
||||||
|
def matchAddress(self, line):
|
||||||
|
return re.search("(?:\d{1,3}\.){3}\d{1,3}", line)
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -38,5 +38,5 @@ setup(
|
||||||
url = "http://www.sourceforge.net/projects/fail2ban",
|
url = "http://www.sourceforge.net/projects/fail2ban",
|
||||||
scripts = ['fail2ban.py'],
|
scripts = ['fail2ban.py'],
|
||||||
py_modules = ['version'],
|
py_modules = ['version'],
|
||||||
packages = ['firewall', 'logreader']
|
packages = ['firewall', 'logreader', 'confreader']
|
||||||
)
|
)
|
|
@ -24,4 +24,4 @@ __date__ = "$Date$"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
version = "0.1.2"
|
version = "0.3.0-CVS"
|
||||||
|
|
Loading…
Reference in New Issue