mirror of https://github.com/fail2ban/fail2ban
merged with upstream. Need to propagate 'Debian' patches into upstream as soon as possible because they lead to conflicts on upgrades
parent
e32a92e7c9
commit
66c8660494
18
CHANGELOG
18
CHANGELOG
|
@ -4,9 +4,25 @@
|
|||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.5.2) 2005/08/06
|
||||
Fail2Ban (version 0.5.3) 2005/09/08
|
||||
=============================================================
|
||||
|
||||
ver. 0.5.3 (2005/09/08) - beta
|
||||
----------
|
||||
- Fixed a bug when overriding "maxfailures" or "bantime".
|
||||
Thanks to Yaroslav Halchenko
|
||||
- Added more debug output if an error occurs when sending
|
||||
mail. Thanks to Stephen Gildea
|
||||
- Renamed "maxretry" to "maxfailures" and changed default
|
||||
value to 5. Thanks to Stephen Gildea
|
||||
- Hopefully fixed bug #1256075
|
||||
- Fixed bug #1262345
|
||||
- Fixed exception handling in PIDLock
|
||||
- Removed warning when using "-V" or "-h" with no config
|
||||
file. Thanks to Yaroslav Halchenko
|
||||
- Removed "-i eth0" from config file. Thanks to Yaroslav
|
||||
Halchenko
|
||||
|
||||
ver. 0.5.2 (2005/08/06) - beta
|
||||
----------
|
||||
- Better PID lock file handling. Should close #1239562
|
||||
|
|
4
PKG-INFO
4
PKG-INFO
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: fail2ban
|
||||
Version: 0.5.2
|
||||
Version: 0.5.3
|
||||
Summary: Ban IPs that make too many password failure
|
||||
Home-page: http://fail2ban.sourceforge.net
|
||||
Author: Cyril Jaquier
|
||||
|
@ -11,5 +11,5 @@ Description:
|
|||
/var/log/apache/error_log and bans IP that makes
|
||||
too many password failures. It updates firewall rules
|
||||
to reject the IP address or executes user defined
|
||||
commands. It needs log4py.
|
||||
commands.
|
||||
Platform: Posix
|
||||
|
|
14
README
14
README
|
@ -4,7 +4,7 @@
|
|||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.5.2) 2005/08/06
|
||||
Fail2Ban (version 0.5.3) 2005/09/08
|
||||
=============================================================
|
||||
|
||||
Fail2Ban scans log files like /var/log/pwdfail and bans IP
|
||||
|
@ -58,15 +58,16 @@ Require: python-2.3 (http://www.python.org)
|
|||
|
||||
To install, just do:
|
||||
|
||||
> tar xvfj fail2ban-0.5.2.tar.bz2
|
||||
> cd fail2ban-0.5.2
|
||||
> tar xvfj fail2ban-0.5.3.tar.bz2
|
||||
> cd fail2ban-0.5.3
|
||||
> python setup.py install
|
||||
|
||||
This will install Fail2Ban into /usr/lib/fail2ban. The fail2ban
|
||||
executable is placed into /usr/bin.
|
||||
|
||||
Gentoo: an ebuild is available on the website.
|
||||
Debian: a package is available on the website.
|
||||
Gentoo: ebuilds are available on the website.
|
||||
Debian: Fail2Ban is in Debian unstable.
|
||||
RedHat: packages are available on the website.
|
||||
|
||||
Fail2Ban should now be correctly installed. Just type:
|
||||
|
||||
|
@ -121,7 +122,8 @@ Thanks:
|
|||
-------
|
||||
|
||||
Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
|
||||
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko
|
||||
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
|
||||
Jonathan Kamens, Stephen Gildea
|
||||
|
||||
License:
|
||||
--------
|
||||
|
|
2
TODO
2
TODO
|
@ -10,3 +10,5 @@ ToDo
|
|||
See Feature Request Tracking System at SourceForge.net
|
||||
|
||||
- improve installation process (better prefix support)
|
||||
- install Fail2ban into /usr/share
|
||||
- better configuration files
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fail2Ban configuration file
|
||||
#
|
||||
# $Revision: 1.8.2.9 $
|
||||
# $Revision: 1.8.2.11 $
|
||||
#
|
||||
# 2005.06.21 modified for readability Iain Lea iain@bricbrac.de
|
||||
|
||||
|
@ -39,11 +39,11 @@ syslog-facility = 1
|
|||
#
|
||||
pidlock = /var/run/fail2ban.pid
|
||||
|
||||
# Option: maxretry
|
||||
# Notes.: number of retrys before IP gets banned.
|
||||
# Values: NUM Default: 3
|
||||
# Option: maxfailures
|
||||
# Notes.: number of failures before IP gets banned.
|
||||
# Values: NUM Default: 5
|
||||
#
|
||||
maxretry = 5
|
||||
maxfailures = 5
|
||||
|
||||
# Option: bantime
|
||||
# Notes.: number of seconds an IP will be banned.
|
||||
|
@ -61,9 +61,7 @@ findtime = 600
|
|||
# Notes.: space separated list of IP's to be ignored by fail2ban.
|
||||
# You can use CIDR mask in order to specify a range.
|
||||
# Example: ignoreip = 192.168.0.1/24 123.45.235.65
|
||||
# Values: IP Default: empty
|
||||
# Examples
|
||||
# ignoreip = 192.168.0.0/24
|
||||
# Values: IP Default: 192.168.0.0/16
|
||||
#
|
||||
ignoreip = 192.168.0.0/16
|
||||
|
||||
|
@ -133,7 +131,7 @@ subject = [Fail2Ban] Banned <ip>
|
|||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <br> new line
|
||||
# Values: TEXT Default:
|
||||
# Values: TEXT Default:
|
||||
#
|
||||
message = Hi,<br>
|
||||
The IP <ip> has just been banned by Fail2Ban after
|
||||
|
@ -200,7 +198,7 @@ fwunban = iptables -D fail2ban-http -s <ip> -j DROP
|
|||
|
||||
# Option: timeregex
|
||||
# Notes.: regex to match timestamp in Apache logfile.
|
||||
# Values: [Wed Jan 05 15:08:01 2005]
|
||||
# Values: [Wed Jan 05 15:08:01 2005]
|
||||
# Default: \S{3} \S{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}
|
||||
#
|
||||
timeregex = \S{3} \S{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}
|
||||
|
@ -272,7 +270,7 @@ fwunban = iptables -D fail2ban-ssh -s <ip> -j DROP
|
|||
|
||||
# Option: timeregex
|
||||
# Notes.: regex to match timestamp in SSH logfile.
|
||||
# Values: [Mar 7 17:53:28]
|
||||
# Values: [Mar 7 17:53:28]
|
||||
# Default: \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}
|
||||
#
|
||||
timeregex = \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
fail2ban (0.5.3-1) UNRELEASED; urgency=low
|
||||
|
||||
* (NOT RELEASED YET) New upstream release
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Fri, 9 Sep 2005 16:55:00 -0400
|
||||
|
||||
fail2ban (0.5.2-5) unstable; urgency=low
|
||||
|
||||
* Included a patch from Stephen Gildea to provide "status" report by
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
# Site Directory Pattern Version Script
|
||||
version=3
|
||||
|
||||
http://prdownloads.sf.net/fail2ban/fail2ban-(.*)\.tar\.bz2 debian svn-upgrade
|
||||
http://heanet.dl.sourceforge.net/sourceforge/fail2ban/ \
|
||||
fail2ban-(.*)\.tar\.bz2 debian svn-upgrade
|
||||
|
|
40
fail2ban.py
40
fail2ban.py
|
@ -17,11 +17,11 @@
|
|||
# Author: Cyril Jaquier
|
||||
# Modified by: Yaroslav Halchenko (SYSLOG, findtime)
|
||||
#
|
||||
# $Revision: 1.20.2.13 $
|
||||
# $Revision: 1.20.2.16 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.20.2.13 $"
|
||||
__date__ = "$Date: 2005/08/06 18:44:06 $"
|
||||
__version__ = "$Revision: 1.20.2.16 $"
|
||||
__date__ = "$Date: 2005/09/05 21:12:08 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -130,7 +130,7 @@ def getCmdLineOptions(optList):
|
|||
if opt[0] == "-i":
|
||||
conf["ignoreip"] = opt[1]
|
||||
if opt[0] == "-r":
|
||||
conf["maxretry"] = int(opt[1])
|
||||
conf["maxfailures"] = int(opt[1])
|
||||
if opt[0] == "-p":
|
||||
conf["pidlock"] = opt[1]
|
||||
if opt[0] == "-k":
|
||||
|
@ -162,12 +162,12 @@ def main():
|
|||
|
||||
# Pre-parsing of command line options for the -c option
|
||||
for opt in optList:
|
||||
if opt[0] == "-c":
|
||||
conf["conffile"] = opt[1]
|
||||
if opt[0] in ["-h", "--help"]:
|
||||
dispUsage()
|
||||
if opt[0] in ["-V", "--version"]:
|
||||
dispVersion()
|
||||
if opt[0] == "-c":
|
||||
conf["conffile"] = opt[1]
|
||||
|
||||
# Reads the config file and create a LogReader instance for
|
||||
# each log file to check.
|
||||
|
@ -181,7 +181,7 @@ def main():
|
|||
["int", "syslog-facility", 1],
|
||||
["bool", "debug", False],
|
||||
["str", "pidlock", "/var/run/fail2ban.pid"],
|
||||
["int", "maxretry", 3],
|
||||
["int", "maxfailures", 5],
|
||||
["int", "bantime", 600],
|
||||
["int", "findtime", 600],
|
||||
["str", "ignoreip", ""],
|
||||
|
@ -293,16 +293,7 @@ def main():
|
|||
|
||||
# Ignores IP list
|
||||
ignoreIPList = conf["ignoreip"].split(' ')
|
||||
|
||||
# maxretry option
|
||||
maxRetry = conf["maxretry"]
|
||||
|
||||
# bantime option
|
||||
banTime = conf["bantime"]
|
||||
|
||||
# findtime option
|
||||
findTime = conf["findtime"]
|
||||
|
||||
# Checks for root user. This is necessary because log files
|
||||
# are owned by root and firewall needs root access.
|
||||
if not checkForRoot():
|
||||
|
@ -316,12 +307,15 @@ def main():
|
|||
logSys.error("Fail2Ban already running with PID "+pid)
|
||||
sys.exit(-1)
|
||||
else:
|
||||
pidLock.create()
|
||||
ret = pidLock.create()
|
||||
if not ret:
|
||||
# Unable to create PID lock. Exit
|
||||
sys.exit(-1)
|
||||
|
||||
logSys.debug("ConfFile is " + conf["conffile"])
|
||||
logSys.debug("BanTime is " + `conf["bantime"]`)
|
||||
logSys.debug("FindTime is " + `conf["findtime"]`)
|
||||
logSys.debug("retryAllowed is " + `conf["maxretry"]`)
|
||||
logSys.debug("MaxFailure is " + `conf["maxfailures"]`)
|
||||
|
||||
# Options
|
||||
optionValues = (["bool", "enabled", False],
|
||||
|
@ -346,9 +340,9 @@ def main():
|
|||
# Options
|
||||
optionValues = (["bool", "enabled", False],
|
||||
["str", "logfile", "/dev/null"],
|
||||
["int", "maxretry", maxRetry],
|
||||
["int", "bantime", banTime],
|
||||
["int", "findtime", findTime],
|
||||
["int", "maxfailures", conf["maxfailures"]],
|
||||
["int", "bantime", conf["bantime"]],
|
||||
["int", "findtime", conf["findtime"]],
|
||||
["str", "timeregex", ""],
|
||||
["str", "timepattern", ""],
|
||||
["str", "failregex", ""],
|
||||
|
@ -364,7 +358,7 @@ def main():
|
|||
|
||||
# Creates a logreader object
|
||||
lObj = LogReader(l["logfile"], l["timeregex"], l["timepattern"],
|
||||
l["failregex"], l["maxretry"], l["findtime"])
|
||||
l["failregex"], l["maxfailures"], l["findtime"])
|
||||
# Creates a firewall object
|
||||
fObj = Firewall(l["fwban"], l["fwunban"], l["bantime"])
|
||||
# Links them into a list. I'm not really happy
|
||||
|
@ -381,6 +375,8 @@ def main():
|
|||
if isValidIP(ip):
|
||||
for element in logFwList:
|
||||
element[1].addIgnoreIP(ip)
|
||||
else:
|
||||
logSys.warn(ip + " is not a valid IP address")
|
||||
|
||||
logSys.info("Fail2Ban v" + version + " is running")
|
||||
# Execute global start command
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.13.2.7 $
|
||||
# $Revision: 1.13.2.8 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.13.2.7 $"
|
||||
__date__ = "$Date: 2005/08/06 18:43:11 $"
|
||||
__version__ = "$Revision: 1.13.2.8 $"
|
||||
__date__ = "$Date: 2005/09/05 21:06:15 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -134,11 +134,13 @@ class LogReader:
|
|||
logSys.debug(self.logPath)
|
||||
logFile = self.openLogFile()
|
||||
self.setFilePos(logFile)
|
||||
lastLine = ''
|
||||
lastLine = None
|
||||
for line in logFile:
|
||||
if not self.hasTime(line):
|
||||
# There is no valid time in this line
|
||||
continue
|
||||
lastLine = line
|
||||
failList = self.findFailure(line)
|
||||
for element in failList:
|
||||
for element in self.findFailure(line):
|
||||
ip = element[0]
|
||||
unixTime = element[1]
|
||||
if unixTime < time.time()-self.findTime:
|
||||
|
@ -152,7 +154,8 @@ class LogReader:
|
|||
else:
|
||||
ipList[ip] = (1, unixTime)
|
||||
self.lastPos = logFile.tell()
|
||||
self.lastDate = self.getTime(lastLine)
|
||||
if lastLine:
|
||||
self.lastDate = self.getTime(lastLine)
|
||||
logFile.close()
|
||||
return ipList
|
||||
|
||||
|
@ -175,6 +178,15 @@ class LogReader:
|
|||
failList.append([ip, date])
|
||||
return failList
|
||||
|
||||
def hasTime(self, line):
|
||||
""" Return true if the line contains a date
|
||||
"""
|
||||
timeMatch = re.search(self.timeregex, line)
|
||||
if timeMatch:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getTime(self, line):
|
||||
""" Gets the time of a log message.
|
||||
"""
|
||||
|
|
6
setup.py
6
setup.py
|
@ -18,11 +18,11 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.4.2.3 $
|
||||
# $Revision: 1.4.2.4 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.4.2.3 $"
|
||||
__date__ = "$Date: 2005/07/28 20:30:34 $"
|
||||
__version__ = "$Revision: 1.4.2.4 $"
|
||||
__date__ = "$Date: 2005/08/07 13:10:39 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.7.2.2 $
|
||||
# $Revision: 1.7.2.3 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.7.2.2 $"
|
||||
__date__ = "$Date: 2005/07/22 21:11:42 $"
|
||||
__version__ = "$Revision: 1.7.2.3 $"
|
||||
__date__ = "$Date: 2005/08/17 19:26:49 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -58,8 +58,9 @@ def searchIP(text):
|
|||
def isValidIP(str):
|
||||
""" Return true if str is a valid IP
|
||||
"""
|
||||
s = str.split('/', 1)
|
||||
try:
|
||||
socket.inet_aton(str)
|
||||
socket.inet_aton(s[0])
|
||||
return True
|
||||
except socket.error:
|
||||
return False
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.1.2.2 $
|
||||
# $Revision: 1.1.2.3 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.1.2.2 $"
|
||||
__date__ = "$Date: 2005/08/01 16:35:18 $"
|
||||
__version__ = "$Revision: 1.1.2.3 $"
|
||||
__date__ = "$Date: 2005/09/08 18:05:59 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -64,8 +64,8 @@ class Mail:
|
|||
server.sendmail(self.fromAddr, self.toAddr, mail)
|
||||
logSys.debug("Email sent to " + `self.toAddr`)
|
||||
server.quit()
|
||||
except Exception:
|
||||
except Exception, e:
|
||||
logSys.error("Unable to send mail to " + self.host + ":" +
|
||||
`self.port` + " from " + self.fromAddr + " to " +
|
||||
`self.toAddr`)
|
||||
`self.toAddr` + ": " + `e` + ": " + `e.args`)
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.1.2.1 $
|
||||
# $Revision: 1.1.2.2 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.1.2.1 $"
|
||||
__date__ = "$Date: 2005/08/04 20:48:30 $"
|
||||
__version__ = "$Revision: 1.1.2.2 $"
|
||||
__date__ = "$Date: 2005/08/07 13:08:18 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -51,17 +51,25 @@ class PIDLock:
|
|||
def create(self):
|
||||
""" Create PID lock.
|
||||
"""
|
||||
fileHandler = open(self.path, mode='w')
|
||||
pid = os.getpid()
|
||||
fileHandler.write(`pid` + '\n')
|
||||
fileHandler.close()
|
||||
logSys.debug("Created PID lock (" + `pid` + ") in " + self.path)
|
||||
try:
|
||||
fileHandler = open(self.path, mode='w')
|
||||
pid = os.getpid()
|
||||
fileHandler.write(`pid` + '\n')
|
||||
fileHandler.close()
|
||||
logSys.debug("Created PID lock (" + `pid` + ") in " + self.path)
|
||||
return True
|
||||
except:
|
||||
logSys.error("Unable to create PID lock " + self.path)
|
||||
return False
|
||||
|
||||
def remove(self):
|
||||
""" Remove PID lock.
|
||||
"""
|
||||
os.remove(self.path)
|
||||
logSys.debug("Removed PID lock " + self.path)
|
||||
try:
|
||||
os.remove(self.path)
|
||||
logSys.debug("Removed PID lock " + self.path)
|
||||
except OSError:
|
||||
logSys.error("Unable to remove PID lock " + self.path)
|
||||
|
||||
def exists(self):
|
||||
""" Returns the current PID if Fail2Ban is running or False
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.12.2.6 $
|
||||
# $Revision: 1.12.2.8 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 1.12.2.6 $"
|
||||
__date__ = "$Date: 2005/08/06 15:07:11 $"
|
||||
__version__ = "$Revision: 1.12.2.8 $"
|
||||
__date__ = "$Date: 2005/09/08 18:20:51 $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
version = "0.5.2"
|
||||
version = "0.5.3"
|
||||
|
|
Loading…
Reference in New Issue