mirror of https://github.com/fail2ban/fail2ban
- Add log4py import exception handling
- Remove metalog class. Now use LogReader - Add -r option: you can specifie the maximum number of login failure before ban - Code comments git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@27 a942ae1a-1317-0410-a47c-b1dcaea8d6050.6
parent
3fa88d60a6
commit
18029d4426
52
fail2ban.py
52
fail2ban.py
|
@ -27,13 +27,19 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import posix, time, sys, getopt, os, signal
|
import posix, time, sys, getopt, os, signal
|
||||||
import log4py
|
|
||||||
|
# Checks if log4py is present.
|
||||||
|
try:
|
||||||
|
import log4py
|
||||||
|
except:
|
||||||
|
print "log4py is needed (see README)"
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
# Appends our own modules path
|
# Appends our own modules path
|
||||||
sys.path.append('/usr/lib/fail2ban')
|
sys.path.append('/usr/lib/fail2ban')
|
||||||
|
|
||||||
from firewall.iptables import Iptables
|
from firewall.iptables import Iptables
|
||||||
from logreader.metalog import Metalog
|
from logreader.logreader import LogReader
|
||||||
from version import version
|
from version import version
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
|
@ -47,6 +53,7 @@ def usage():
|
||||||
print " -f <FILE> read password failure from FILE"
|
print " -f <FILE> read password failure from FILE"
|
||||||
print " -h display this help message"
|
print " -h display this help message"
|
||||||
print " -l <FILE> log message in FILE"
|
print " -l <FILE> log message in FILE"
|
||||||
|
print " -r <VALUE> allow a max of VALUE password failure"
|
||||||
print " -t <TIME> ban IP for TIME seconds"
|
print " -t <TIME> ban IP for TIME seconds"
|
||||||
print " -v verbose"
|
print " -v verbose"
|
||||||
print
|
print
|
||||||
|
@ -140,18 +147,22 @@ def createDaemon():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
# Gets an instance of log4py.
|
||||||
logSys = log4py.Logger().get_instance()
|
logSys = log4py.Logger().get_instance()
|
||||||
logSys.set_formatstring("%T %L %M")
|
logSys.set_formatstring("%T %L %M")
|
||||||
|
|
||||||
try:
|
# Initializes some variables.
|
||||||
optList, args = getopt.getopt(sys.argv[1:], 'hvbdf:l:t:i:')
|
|
||||||
except getopt.GetoptError:
|
|
||||||
usage()
|
|
||||||
|
|
||||||
debug = False
|
debug = False
|
||||||
logFilePath = "/var/log/pwdfail/current"
|
logFilePath = "/var/log/pwdfail/current"
|
||||||
banTime = 600
|
banTime = 600
|
||||||
ignoreIPList = {}
|
ignoreIPList = {}
|
||||||
|
retryAllowed = 3
|
||||||
|
|
||||||
|
# Reads the command line options.
|
||||||
|
try:
|
||||||
|
optList, args = getopt.getopt(sys.argv[1:], 'hvbdf:l:t:i:r:')
|
||||||
|
except getopt.GetoptError:
|
||||||
|
usage()
|
||||||
|
|
||||||
for opt in optList:
|
for opt in optList:
|
||||||
if opt[0] == "-h":
|
if opt[0] == "-h":
|
||||||
|
@ -185,7 +196,15 @@ if __name__ == "__main__":
|
||||||
logSys.error("Using default value")
|
logSys.error("Using default value")
|
||||||
if opt[0] == "-i":
|
if opt[0] == "-i":
|
||||||
ignoreIPList = opt[1].split(' ')
|
ignoreIPList = opt[1].split(' ')
|
||||||
|
if opt[0] == "-r":
|
||||||
|
try:
|
||||||
|
retryAllowed = int(opt[1])
|
||||||
|
except ValueError:
|
||||||
|
logSys.error("retryAllowed must be an integer")
|
||||||
|
logSys.error("Using default value")
|
||||||
|
|
||||||
|
# Checks for root user. This is necessary because log files
|
||||||
|
# are owned by root and firewall needs root access.
|
||||||
if not checkForRoot():
|
if not checkForRoot():
|
||||||
logSys.error("You must be root")
|
logSys.error("You must be root")
|
||||||
if not debug:
|
if not debug:
|
||||||
|
@ -193,36 +212,51 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
logSys.debug("logFilePath is "+logFilePath)
|
logSys.debug("logFilePath is "+logFilePath)
|
||||||
logSys.debug("BanTime is "+`banTime`)
|
logSys.debug("BanTime is "+`banTime`)
|
||||||
|
logSys.debug("retryAllowed is "+`retryAllowed`)
|
||||||
|
|
||||||
|
# Creates one instance of Iptables and one of LogReader.
|
||||||
fireWall = Iptables(banTime, logSys)
|
fireWall = Iptables(banTime, logSys)
|
||||||
logFile = Metalog(logFilePath, logSys, banTime)
|
logFile = LogReader(logFilePath, logSys, 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")
|
logFile.addIgnoreIP("127.0.0.1")
|
||||||
while len(ignoreIPList) > 0:
|
while len(ignoreIPList) > 0:
|
||||||
ip = ignoreIPList.pop()
|
ip = ignoreIPList.pop()
|
||||||
logFile.addIgnoreIP(ip)
|
logFile.addIgnoreIP(ip)
|
||||||
|
|
||||||
logSys.info("Fail2Ban v"+version+" is running")
|
logSys.info("Fail2Ban v"+version+" is running")
|
||||||
|
# Main loop
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
# Checks if some IP have to be remove from ban
|
||||||
|
# list.
|
||||||
fireWall.checkForUnBan(debug)
|
fireWall.checkForUnBan(debug)
|
||||||
|
|
||||||
|
# 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():
|
if not logFile.isModified():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Gets the failure list from the log file.
|
||||||
failList = logFile.getPwdFailure()
|
failList = logFile.getPwdFailure()
|
||||||
|
|
||||||
|
# We iterate the failure list and ban IP that make
|
||||||
|
# *retryAllowed* login failures.
|
||||||
iterFailList = failList.iteritems()
|
iterFailList = failList.iteritems()
|
||||||
for i in range(len(failList)):
|
for i in range(len(failList)):
|
||||||
element = iterFailList.next()
|
element = iterFailList.next()
|
||||||
if element[1][0] > 2:
|
if element[1][0] >= retryAllowed:
|
||||||
fireWall.addBanIP(element[0], debug)
|
fireWall.addBanIP(element[0], debug)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
# When the user press <ctrl>+<c> we flush the ban list
|
||||||
|
# and exit nicely.
|
||||||
logSys.info("Restoring iptables...")
|
logSys.info("Restoring iptables...")
|
||||||
fireWall.flushBanList(debug)
|
fireWall.flushBanList(debug)
|
||||||
logSys.info("Exiting...")
|
logSys.info("Exiting...")
|
||||||
|
|
Loading…
Reference in New Issue