Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c5f11079c | ||
|
|
f31607ded1 | ||
|
|
05fcb1f104 | ||
|
|
270ea363d3 | ||
|
|
b912d61ccb | ||
|
|
5d526bbeb1 | ||
|
|
7b5dc9f24f | ||
|
|
fc5f729f01 | ||
|
|
4f636eb0e3 | ||
|
|
bfaf33b6ba | ||
|
|
2c158fe168 | ||
|
|
8f521b8551 | ||
|
|
0e1f8f7f39 | ||
|
|
96c20c8379 | ||
|
|
c58c4de9bc | ||
|
|
249e169d8e | ||
|
|
544cfaff2c |
@@ -1,4 +1,3 @@
|
||||
.pc/*
|
||||
*~
|
||||
build
|
||||
dist
|
||||
|
||||
@@ -48,12 +48,16 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
|
||||
* cyrus-imap -- also catch also failed logins via secured (imaps/pop3s).
|
||||
Regression was introduced while strengthening failregex in 0.8.11 (bd175f)
|
||||
Debian bug #755173
|
||||
* postfix-sasl -- added journalmatch. Thanks Luc Maisonobe
|
||||
* postfix-sasl - added journalmatch. Thanks Luc Maisonobe
|
||||
* postfix* - match with a new daemon string (postfix/submission/smtpd).
|
||||
Closes gh-804 . Thanks Paul Traina
|
||||
* apache - added filter for AH01630 client denied by server configuration.
|
||||
|
||||
- New features:
|
||||
- New filters:
|
||||
- monit Thanks Jason H Martin
|
||||
- directadmin Thanks niorg
|
||||
- apache-shellshock Thanks Eugene Hopkinson (SlowRiot)
|
||||
- New actions:
|
||||
- symbiosis-blacklist-allports for Bytemark symbiosis firewall
|
||||
- fail2ban-client can fetch the running server version
|
||||
|
||||
@@ -34,6 +34,7 @@ David Nutter
|
||||
Derek Atkins
|
||||
Eric Gerbier
|
||||
Enrico Labedzki
|
||||
Eugene Hopkinson (SlowRiot)
|
||||
ftoppi
|
||||
François Boulogne
|
||||
Frédéric
|
||||
@@ -81,6 +82,7 @@ Mika (mkl)
|
||||
Nick Munger
|
||||
onorua
|
||||
Paul Marrapese
|
||||
Paul Traina
|
||||
Noel Butler
|
||||
Patrick Börjesson
|
||||
Pressy
|
||||
|
||||
Vendored
-5
@@ -1,10 +1,5 @@
|
||||
Vagrant.configure("2") do |config|
|
||||
|
||||
config.vm.define "builder" do |builder|
|
||||
builder.vm.box = "vm144"
|
||||
builder.vm.provision "shell", path: "provision.sh"
|
||||
end
|
||||
|
||||
config.vm.define "secure" do |secure|
|
||||
secure.vm.box = "ubuntu/trusty64"
|
||||
secure.vm.hostname = "secure.dev.fail2ban.org"
|
||||
|
||||
+44
-44
@@ -59,53 +59,53 @@ class Fail2banClient:
|
||||
self.__conf["pidfile"] = None
|
||||
|
||||
def dispVersion(self):
|
||||
print("Fail2Ban v" + version)
|
||||
print()
|
||||
print("Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors")
|
||||
print("Copyright of modifications held by their respective authors.")
|
||||
print("Licensed under the GNU General Public License v2 (GPL).")
|
||||
print()
|
||||
print("Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.")
|
||||
print("Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.")
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
print "Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors"
|
||||
print "Copyright of modifications held by their respective authors."
|
||||
print "Licensed under the GNU General Public License v2 (GPL)."
|
||||
print
|
||||
print "Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
print("Usage: "+self.__argv[0]+" [OPTIONS] <COMMAND>")
|
||||
print()
|
||||
print("Fail2Ban v" + version + " reads log file that contains password failure report")
|
||||
print("and bans the corresponding IP addresses using firewall rules.")
|
||||
print()
|
||||
print("Options:")
|
||||
print(" -c <DIR> configuration directory")
|
||||
print(" -s <FILE> socket path")
|
||||
print(" -p <FILE> pidfile path")
|
||||
print(" -d dump configuration. For debugging")
|
||||
print(" -i interactive mode")
|
||||
print(" -v increase verbosity")
|
||||
print(" -q decrease verbosity")
|
||||
print(" -x force execution of the server (remove socket file)")
|
||||
print(" -b start server in background (default)")
|
||||
print(" -f start server in foreground (note that the client forks once itself)")
|
||||
print(" -h, --help display this help message")
|
||||
print(" -V, --version print the version")
|
||||
print()
|
||||
print("Command:")
|
||||
print "Usage: "+self.__argv[0]+" [OPTIONS] <COMMAND>"
|
||||
print
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print "Options:"
|
||||
print " -c <DIR> configuration directory"
|
||||
print " -s <FILE> socket path"
|
||||
print " -p <FILE> pidfile path"
|
||||
print " -d dump configuration. For debugging"
|
||||
print " -i interactive mode"
|
||||
print " -v increase verbosity"
|
||||
print " -q decrease verbosity"
|
||||
print " -x force execution of the server (remove socket file)"
|
||||
print " -b start server in background (default)"
|
||||
print " -f start server in foreground (note that the client forks once itself)"
|
||||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print
|
||||
print "Command:"
|
||||
|
||||
# Prints the protocol
|
||||
printFormatted()
|
||||
|
||||
print()
|
||||
print("Report bugs to https://github.com/fail2ban/fail2ban/issues")
|
||||
print
|
||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
||||
|
||||
def dispInteractive(self):
|
||||
print("Fail2Ban v" + version + " reads log file that contains password failure report")
|
||||
print("and bans the corresponding IP addresses using firewall rules.")
|
||||
print()
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
|
||||
def __sigTERMhandler(self, signum, frame):
|
||||
# Print a new line because we probably come from wait
|
||||
print()
|
||||
print
|
||||
logSys.warning("Caught signal %d. Exiting" % signum)
|
||||
sys.exit(-1)
|
||||
|
||||
@@ -152,19 +152,19 @@ class Fail2banClient:
|
||||
client = CSocket(self.__conf["socket"])
|
||||
ret = client.send(c)
|
||||
if ret[0] == 0:
|
||||
logSys.debug("OK : " + repr(ret[1]))
|
||||
logSys.debug("OK : " + `ret[1]`)
|
||||
if showRet:
|
||||
print(beautifier.beautify(ret[1]))
|
||||
print beautifier.beautify(ret[1])
|
||||
else:
|
||||
logSys.error("NOK: " + repr(ret[1].args))
|
||||
logSys.error("NOK: " + `ret[1].args`)
|
||||
if showRet:
|
||||
print(beautifier.beautifyError(ret[1]))
|
||||
print beautifier.beautifyError(ret[1])
|
||||
streamRet = False
|
||||
except socket.error:
|
||||
if showRet:
|
||||
logSys.error("Unable to contact server. Is it running?")
|
||||
return False
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
if showRet:
|
||||
logSys.error(e)
|
||||
return False
|
||||
@@ -383,7 +383,7 @@ class Fail2banClient:
|
||||
readline.parse_and_bind("tab: complete")
|
||||
self.dispInteractive()
|
||||
while True:
|
||||
cmd = input(self.PROMPT)
|
||||
cmd = raw_input(self.PROMPT)
|
||||
if cmd == "exit" or cmd == "quit":
|
||||
# Exit
|
||||
return True
|
||||
@@ -392,10 +392,10 @@ class Fail2banClient:
|
||||
elif not cmd == "":
|
||||
try:
|
||||
self.__processCommand(shlex.split(cmd))
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
logSys.error(e)
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
print()
|
||||
print
|
||||
return True
|
||||
# Single command mode
|
||||
else:
|
||||
@@ -413,7 +413,7 @@ class Fail2banClient:
|
||||
ret = self.__configurator.getOptions(jail)
|
||||
self.__configurator.convertToProtocol()
|
||||
self.__stream = self.__configurator.getConfigStream()
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
logSys.error("Failed during configuration: %s" % e)
|
||||
ret = False
|
||||
return ret
|
||||
@@ -421,7 +421,7 @@ class Fail2banClient:
|
||||
#@staticmethod
|
||||
def dumpConfig(cmd):
|
||||
for c in cmd:
|
||||
print(c)
|
||||
print c
|
||||
return True
|
||||
dumpConfig = staticmethod(dumpConfig)
|
||||
|
||||
|
||||
+46
-44
@@ -29,10 +29,10 @@ __author__ = "Fail2Ban Developers"
|
||||
__copyright__ = "Copyright (c) 2004-2008 Cyril Jaquier, 2012-2014 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
import getopt, sys, time, logging, os, locale, shlex, time, urllib.request, urllib.parse, urllib.error
|
||||
import getopt, sys, time, logging, os, locale, shlex, time, urllib
|
||||
from optparse import OptionParser, Option
|
||||
|
||||
from configparser import NoOptionError, NoSectionError, MissingSectionHeaderError
|
||||
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
|
||||
|
||||
try:
|
||||
from systemd import journal
|
||||
@@ -50,7 +50,7 @@ from fail2ban.helpers import FormatterWithTraceBack, getLogger
|
||||
logSys = getLogger("fail2ban")
|
||||
|
||||
def debuggexURL(sample, regex):
|
||||
q = urllib.parse.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),
|
||||
q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),
|
||||
'str': sample,
|
||||
'flavor': 'python' })
|
||||
return 'http://www.debuggex.com/?' + q
|
||||
@@ -69,7 +69,7 @@ def pprint_list(l, header=None):
|
||||
s = "|- %s\n" % header
|
||||
else:
|
||||
s = ''
|
||||
print(s + "| " + "\n| ".join(l) + '\n`-')
|
||||
print s + "| " + "\n| ".join(l) + '\n`-'
|
||||
|
||||
def file_lines_gen(hdlr):
|
||||
for line in hdlr:
|
||||
@@ -244,14 +244,14 @@ class Fail2banRegex(object):
|
||||
self._filter.setDatePattern(pattern)
|
||||
self._datepattern_set = True
|
||||
if pattern is not None:
|
||||
print("Use datepattern : %s" % (
|
||||
self._filter.getDatePattern()[1], ))
|
||||
print "Use datepattern : %s" % (
|
||||
self._filter.getDatePattern()[1], )
|
||||
|
||||
def setMaxLines(self, v):
|
||||
if not self._maxlines_set:
|
||||
self._filter.setMaxLines(int(v))
|
||||
self._maxlines_set = True
|
||||
print("Use maxlines : %d" % self._filter.getMaxLines())
|
||||
print "Use maxlines : %d" % self._filter.getMaxLines()
|
||||
|
||||
def setJournalMatch(self, v):
|
||||
if self._journalmatch is None:
|
||||
@@ -261,7 +261,7 @@ class Fail2banRegex(object):
|
||||
assert(regextype in ('fail', 'ignore'))
|
||||
regex = regextype + 'regex'
|
||||
if os.path.isfile(value):
|
||||
print("Use %11s file : %s" % (regex, value))
|
||||
print "Use %11s file : %s" % (regex, value)
|
||||
reader = FilterReader(value, 'fail2ban-regex-jail', {})
|
||||
reader.setBaseDir(None)
|
||||
|
||||
@@ -270,7 +270,9 @@ class Fail2banRegex(object):
|
||||
readercommands = reader.convert()
|
||||
regex_values = [
|
||||
RegexStat(m[3])
|
||||
for m in [x for x in readercommands if x[0] == 'set' and x[2] == "add%sregex" % regextype]]
|
||||
for m in filter(
|
||||
lambda x: x[0] == 'set' and x[2] == "add%sregex" % regextype,
|
||||
readercommands)]
|
||||
# Read out and set possible value of maxlines
|
||||
for command in readercommands:
|
||||
if command[2] == "maxlines":
|
||||
@@ -278,8 +280,8 @@ class Fail2banRegex(object):
|
||||
try:
|
||||
self.setMaxLines(maxlines)
|
||||
except ValueError:
|
||||
print("ERROR: Invalid value for maxlines (%(maxlines)r) " \
|
||||
"read from %(value)s" % locals())
|
||||
print "ERROR: Invalid value for maxlines (%(maxlines)r) " \
|
||||
"read from %(value)s" % locals()
|
||||
return False
|
||||
elif command[2] == 'addjournalmatch':
|
||||
journalmatch = command[3]
|
||||
@@ -288,10 +290,10 @@ class Fail2banRegex(object):
|
||||
datepattern = command[3]
|
||||
self.setDatePattern(datepattern)
|
||||
else:
|
||||
print("ERROR: failed to read %s" % value)
|
||||
print "ERROR: failed to read %s" % value
|
||||
return False
|
||||
else:
|
||||
print("Use %11s line : %s" % (regex, shortstr(value)))
|
||||
print "Use %11s line : %s" % (regex, shortstr(value))
|
||||
regex_values = [RegexStat(value)]
|
||||
|
||||
setattr(self, "_" + regex, regex_values)
|
||||
@@ -308,8 +310,8 @@ class Fail2banRegex(object):
|
||||
if ret is not None:
|
||||
found = True
|
||||
regex = self._ignoreregex[ret].inc()
|
||||
except RegexException as e:
|
||||
print(e)
|
||||
except RegexException, e:
|
||||
print e
|
||||
return False
|
||||
return found
|
||||
|
||||
@@ -325,11 +327,11 @@ class Fail2banRegex(object):
|
||||
regex = self._failregex[match[0]]
|
||||
regex.inc()
|
||||
regex.appendIP(match)
|
||||
except RegexException as e:
|
||||
print(e)
|
||||
except RegexException, e:
|
||||
print e
|
||||
return False
|
||||
except IndexError:
|
||||
print("Sorry, but no <HOST> found in regex")
|
||||
print "Sorry, but no <HOST> found in regex"
|
||||
return False
|
||||
for bufLine in orgLineBuffer[int(fullBuffer):]:
|
||||
if bufLine not in self._filter._Filter__lineBuffer:
|
||||
@@ -403,21 +405,21 @@ class Fail2banRegex(object):
|
||||
ans = [[]]
|
||||
for arg in [l, regexlist]:
|
||||
ans = [ x + [y] for x in ans for y in arg ]
|
||||
b = [a[0] + ' | ' + a[1].getFailRegex() + ' | ' + debuggexURL(a[0], a[1].getFailRegex()) for a in ans]
|
||||
b = map(lambda a: a[0] + ' | ' + a[1].getFailRegex() + ' | ' + debuggexURL(a[0], a[1].getFailRegex()), ans)
|
||||
pprint_list([x.rstrip() for x in b], header)
|
||||
else:
|
||||
print("%s too many to print. Use --print-all-%s " \
|
||||
"to print all %d lines" % (header, ltype, lines))
|
||||
print "%s too many to print. Use --print-all-%s " \
|
||||
"to print all %d lines" % (header, ltype, lines)
|
||||
elif lines < self._maxlines or getattr(self, '_print_all_' + ltype):
|
||||
pprint_list([x.rstrip() for x in l], header)
|
||||
else:
|
||||
print("%s too many to print. Use --print-all-%s " \
|
||||
"to print all %d lines" % (header, ltype, lines))
|
||||
print "%s too many to print. Use --print-all-%s " \
|
||||
"to print all %d lines" % (header, ltype, lines)
|
||||
|
||||
def printStats(self):
|
||||
print()
|
||||
print("Results")
|
||||
print("=======")
|
||||
print
|
||||
print "Results"
|
||||
print "======="
|
||||
|
||||
def print_failregexes(title, failregexes):
|
||||
# Print title
|
||||
@@ -438,7 +440,7 @@ class Fail2banRegex(object):
|
||||
timeString,
|
||||
ip[-1] and " (multiple regex matched)" or ""))
|
||||
|
||||
print("\n%s: %d total" % (title, total))
|
||||
print "\n%s: %d total" % (title, total)
|
||||
pprint_list(out, " #) [# of hits] regular expression")
|
||||
return total
|
||||
|
||||
@@ -448,7 +450,7 @@ class Fail2banRegex(object):
|
||||
|
||||
|
||||
if self._filter.dateDetector is not None:
|
||||
print("\nDate template hits:")
|
||||
print "\nDate template hits:"
|
||||
out = []
|
||||
for template in self._filter.dateDetector.templates:
|
||||
if self._verbose or template.hits:
|
||||
@@ -456,10 +458,10 @@ class Fail2banRegex(object):
|
||||
template.hits, template.name))
|
||||
pprint_list(out, "[# of hits] date format")
|
||||
|
||||
print("\nLines: %s" % self._line_stats, end=' ')
|
||||
print "\nLines: %s" % self._line_stats,
|
||||
if self._time_elapsed is not None:
|
||||
print("[processed in %.2f sec]" % self._time_elapsed, end=' ')
|
||||
print()
|
||||
print "[processed in %.2f sec]" % self._time_elapsed,
|
||||
print
|
||||
|
||||
if self._print_all_matched:
|
||||
self.printLines('matched')
|
||||
@@ -484,10 +486,10 @@ if __name__ == "__main__":
|
||||
parser.print_help()
|
||||
sys.exit(-1)
|
||||
|
||||
print()
|
||||
print("Running tests")
|
||||
print("=============")
|
||||
print()
|
||||
print
|
||||
print "Running tests"
|
||||
print "============="
|
||||
print
|
||||
|
||||
fail2banRegex = Fail2banRegex(opts)
|
||||
|
||||
@@ -536,15 +538,15 @@ if __name__ == "__main__":
|
||||
if os.path.isfile(cmd_log):
|
||||
try:
|
||||
hdlr = open(cmd_log, 'rb')
|
||||
print("Use log file : %s" % cmd_log)
|
||||
print("Use encoding : %s" % fail2banRegex.encoding)
|
||||
print "Use log file : %s" % cmd_log
|
||||
print "Use encoding : %s" % fail2banRegex.encoding
|
||||
test_lines = file_lines_gen(hdlr)
|
||||
except IOError as e:
|
||||
print(e)
|
||||
except IOError, e:
|
||||
print e
|
||||
sys.exit(-1)
|
||||
elif cmd_log == "systemd-journal":
|
||||
if not journal:
|
||||
print("Error: systemd library not found. Exiting...")
|
||||
print "Error: systemd library not found. Exiting..."
|
||||
sys.exit(-1)
|
||||
myjournal = journal.Reader(converters={'__CURSOR': lambda x: x})
|
||||
journalmatch = fail2banRegex._journalmatch
|
||||
@@ -557,14 +559,14 @@ if __name__ == "__main__":
|
||||
else:
|
||||
myjournal.add_match(element)
|
||||
except ValueError:
|
||||
print("Error: Invalid journalmatch: %s" % shortstr(" ".join(journalmatch)))
|
||||
print "Error: Invalid journalmatch: %s" % shortstr(" ".join(journalmatch))
|
||||
sys.exit(-1)
|
||||
print("Use journal match : %s" % " ".join(journalmatch))
|
||||
print "Use journal match : %s" % " ".join(journalmatch)
|
||||
test_lines = journal_lines_gen(myjournal)
|
||||
else:
|
||||
print("Use single line : %s" % shortstr(cmd_log))
|
||||
print "Use single line : %s" % shortstr(cmd_log)
|
||||
test_lines = [ cmd_log ]
|
||||
print()
|
||||
print
|
||||
|
||||
fail2banRegex.process(test_lines)
|
||||
|
||||
|
||||
+28
-28
@@ -51,37 +51,37 @@ class Fail2banServer:
|
||||
self.__conf["pidfile"] = "/var/run/fail2ban/fail2ban.pid"
|
||||
|
||||
def dispVersion(self):
|
||||
print("Fail2Ban v" + version)
|
||||
print()
|
||||
print("Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors")
|
||||
print("Copyright of modifications held by their respective authors.")
|
||||
print("Licensed under the GNU General Public License v2 (GPL).")
|
||||
print()
|
||||
print("Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.")
|
||||
print("Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.")
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
print "Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors"
|
||||
print "Copyright of modifications held by their respective authors."
|
||||
print "Licensed under the GNU General Public License v2 (GPL)."
|
||||
print
|
||||
print "Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
print("Usage: "+self.__argv[0]+" [OPTIONS]")
|
||||
print()
|
||||
print("Fail2Ban v" + version + " reads log file that contains password failure report")
|
||||
print("and bans the corresponding IP addresses using firewall rules.")
|
||||
print()
|
||||
print("Only use this command for debugging purpose. Start the server with")
|
||||
print("fail2ban-client instead. The default behaviour is to start the server")
|
||||
print("in background.")
|
||||
print()
|
||||
print("Options:")
|
||||
print(" -b start in background")
|
||||
print(" -f start in foreground")
|
||||
print(" -s <FILE> socket path")
|
||||
print(" -p <FILE> pidfile path")
|
||||
print(" -x force execution of the server (remove socket file)")
|
||||
print(" -h, --help display this help message")
|
||||
print(" -V, --version print the version")
|
||||
print()
|
||||
print("Report bugs to https://github.com/fail2ban/fail2ban/issues")
|
||||
print "Usage: "+self.__argv[0]+" [OPTIONS]"
|
||||
print
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print "Only use this command for debugging purpose. Start the server with"
|
||||
print "fail2ban-client instead. The default behaviour is to start the server"
|
||||
print "in background."
|
||||
print
|
||||
print "Options:"
|
||||
print " -b start in background"
|
||||
print " -f start in foreground"
|
||||
print " -s <FILE> socket path"
|
||||
print " -p <FILE> pidfile path"
|
||||
print " -x force execution of the server (remove socket file)"
|
||||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print
|
||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
||||
|
||||
def __getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
@@ -125,7 +125,7 @@ class Fail2banServer:
|
||||
self.__conf["pidfile"],
|
||||
self.__conf["force"])
|
||||
return True
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
logSys.exception(e)
|
||||
self.__server.quit()
|
||||
return False
|
||||
|
||||
@@ -114,8 +114,8 @@ logSys.addHandler(stdout)
|
||||
# Let know the version
|
||||
#
|
||||
if not opts.log_level or opts.log_level != 'critical': # pragma: no cover
|
||||
print(("Fail2ban %s test suite. Python %s. Please wait..." \
|
||||
% (version, str(sys.version).replace('\n', ''))))
|
||||
print("Fail2ban %s test suite. Python %s. Please wait..." \
|
||||
% (version, str(sys.version).replace('\n', '')))
|
||||
|
||||
tests = gatherTests(regexps, opts.no_network)
|
||||
#
|
||||
|
||||
@@ -10,7 +10,7 @@ before = apache-common.conf
|
||||
[Definition]
|
||||
|
||||
|
||||
failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$
|
||||
failregex = ^%(_apache_error_client)s (AH(01797|01630): )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$
|
||||
^%(_apache_error_client)s (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$
|
||||
^%(_apache_error_client)s (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$
|
||||
^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*(, referer: \S+)?\s*$
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Fail2Ban filter to block web requests containing custom headers attempting to exploit the shellshock bug
|
||||
#
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
# overwrite with apache-common.local if _apache_error_client is incorrect.
|
||||
before = apache-common.conf
|
||||
|
||||
[Definition]
|
||||
|
||||
failregex = ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: warning: HTTP_.*?: ignoring function definition attempt(, referer: \S+)?\s*$
|
||||
^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: error importing function definition for `HTTP_.*?'(, referer: \S+)?\s*$
|
||||
|
||||
ignoreregex =
|
||||
|
||||
|
||||
# DEV Notes:
|
||||
#
|
||||
# https://wiki.apache.org/httpd/ListOfErrors for apache error IDs
|
||||
#
|
||||
# example log lines:
|
||||
# [Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt
|
||||
# [Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST'
|
||||
#
|
||||
# Author: Eugene Hopkinson (riot@riot.so)
|
||||
@@ -7,10 +7,12 @@ before = common.conf
|
||||
|
||||
[Definition]
|
||||
|
||||
_daemon = postfix/smtpd
|
||||
_daemon = postfix/(submission/)?smtp(d|s)
|
||||
|
||||
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
||||
|
||||
ignoreregex =
|
||||
|
||||
[Init]
|
||||
|
||||
journalmatch = _SYSTEMD_UNIT=postfix.service
|
||||
|
||||
@@ -10,7 +10,7 @@ before = common.conf
|
||||
|
||||
[Definition]
|
||||
|
||||
_daemon = postfix/smtpd
|
||||
_daemon = postfix/(submission/)?smtp(d|s)
|
||||
|
||||
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$
|
||||
^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$
|
||||
|
||||
@@ -283,6 +283,11 @@ port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
[apache-shellshock]
|
||||
|
||||
port = http,https
|
||||
logpath = $(apache_error_log)s
|
||||
maxretry = 1
|
||||
|
||||
[nginx-http-auth]
|
||||
|
||||
|
||||
Vendored
-79
@@ -1,79 +0,0 @@
|
||||
fail2ban (0.9.0+git48-gabcab00-1) experimental; urgency=low
|
||||
|
||||
[ Yaroslav Halchenko ]
|
||||
* This version went through big refactoring which allowed to gain new
|
||||
features such as multiline matching (see upstream's changelog for more
|
||||
information).
|
||||
* Although .local files are still supported, customizations are advised
|
||||
to be provided under corresponding .d/ directories. E.g. see
|
||||
/etc/fail2ban/jail.d/defaults-debian.conf which is where now sshd
|
||||
jail is enabled by default to match previous behavior of Fail2Ban in
|
||||
Debian.
|
||||
|
||||
[ Daniel Schaal ]
|
||||
* All jails definitions were rewritten to become more concise and uniform.
|
||||
From this version on log paths are defined in distro specific files,
|
||||
for Debian this is in /etc/fail2ban/paths-debian.conf.
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Tue, 25 Mar 2014 08:38:31 -0400
|
||||
|
||||
fail2ban (0.8.11-1) unstable; urgency=low
|
||||
|
||||
* retroactive for 0.8.9: by default iptables-* actions do not simply
|
||||
DROP packets from offending IP but rather reject with
|
||||
icmp-port-unreachable. If DROP behaviour is preferable, provide
|
||||
config/action.d/iptables-blocktype.local with [Init] section defining
|
||||
blocktype = DROP or override action definition to provide
|
||||
blocktype=DROP option in jail.local
|
||||
* Many failregex's were tight-up in this release which could
|
||||
theoretically effect operation in comparison to previous release(s).
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Sat, 16 Nov 2013 22:27:50 -0500
|
||||
|
||||
fail2ban (0.8.4-3) unstable; urgency=low
|
||||
|
||||
* Jail named-refused-udp is unsafe and opens possibility for easy DoS,
|
||||
thus discouraged to be used, and commented out (see #583364 for more
|
||||
information).
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Mon, 28 Jun 2010 22:12:22 -0400
|
||||
|
||||
fail2ban (0.7.1-0.2) unstable; urgency=low
|
||||
|
||||
fail2ban 0.7 is a complete rewrite of the 0.6 version, and if you
|
||||
customized any of provided configuration or startup files
|
||||
(/etc/default/fail2ban, /etc/fail2ban.conf, /etc/init.d/fail2ban),
|
||||
please read further. The configuration scheme has changed upstream:
|
||||
0.7 ignores /etc/fail2ban.conf and instead uses a split configuration
|
||||
under /etc/fail2ban/. To retain your customizations, for example to
|
||||
monitor anything other than sshd, you will need to set them under that
|
||||
new directory; use *.local files for customizations. Please see
|
||||
/usr/share/doc/fail2ban/README.Debian.gz and
|
||||
http://fail2ban.sourceforge.net for further description of new
|
||||
configuration scheme. Detailed documentation is under development (see
|
||||
#400416). When you are satisfied with the new settings, please delete
|
||||
/etc/fail2ban.conf to avoid confusion.
|
||||
|
||||
Fail2ban 0.7 uses client/server architecture and fail2ban-client is to
|
||||
substitute fail2ban command to provide an interface between the user and
|
||||
fail2ban-server. That is why some command line parameters present in
|
||||
fail2ban 0.6 are invalid in fail2ban-client. Such change affects
|
||||
/etc/default/fail2ban; you should review that file if you customized it.
|
||||
Please enable sections as directed in README.Debian.gz mentioned above.
|
||||
You must use newly shipped init.d/fail2ban, or otherwise fail2ban will
|
||||
not start.
|
||||
|
||||
This note was rewritten in release 0.7.5-2 to clarify its meaning.
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Sat, 9 Dec 2006 18:24:36 -0500
|
||||
|
||||
fail2ban (0.6.0-4) unstable; urgency=low
|
||||
|
||||
In this version the new section ApacheAttacks was introduced to ban IPs
|
||||
which are found to run some known attack on the host. For now it captures
|
||||
just awstats and mambo related attacks. To make this feature work, the bug of
|
||||
wrongly specified timeregexp for Apache's access.log file was fixed.
|
||||
Besides that group of log files has changed to be adm, and now they are
|
||||
readable by the group.
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com> Fri, 10 Feb 2006 13:05:07 -0500
|
||||
Vendored
-234
@@ -1,234 +0,0 @@
|
||||
fail2ban (>=0.7.0) for Debian
|
||||
-----------------------------
|
||||
|
||||
This package is ~99% identical to the upstream version. Few features
|
||||
could have been added but not yet propagated into upstream version and
|
||||
some modifications might be Debian-specific. Debian specific jail.conf
|
||||
file is shipped. Original upstream file is available from
|
||||
/usr/share/doc/fail2ban/examples/jail.conf
|
||||
|
||||
Currently, the major difference with upstream: python libraries are
|
||||
placed under /usr/share/fail2ban instead of /usr/lib/fail2ban to
|
||||
comply with policy regarding architecture independent resources.
|
||||
|
||||
Upgrade from 0.6 versions:
|
||||
-------------------------
|
||||
|
||||
* New Config Files Format:
|
||||
|
||||
If you had introduced your own sections in /etc/fail2ban.conf, you
|
||||
would need manually to convert them into a new format. At minimum you
|
||||
need to create /etc/fail2ban/filter.d/NAME.local (leave .conf files
|
||||
for me and upstream please to avoid any conflicts -- introduce your
|
||||
changes in .local) with failregex in [Definition] section. And provide
|
||||
appropriate jail definition in /etc/fail2ban/jail.local
|
||||
|
||||
|
||||
* Enabled Sections:
|
||||
|
||||
Only handling of ssh files is enabled by default. If you want to use
|
||||
fail2ban with apache, please enable apache section manually in
|
||||
/etc/fail2ban/jail.local by including next lines:
|
||||
|
||||
[apache]
|
||||
enabled = true
|
||||
|
||||
NOTE: -e command line parameter is non existant in 0.7.x
|
||||
|
||||
|
||||
* Interpolations vs actions/filters parameters:
|
||||
|
||||
For details see #398739 or wait for a closure of #400416
|
||||
|
||||
Every pair of .conf and then .local (if exists) files is read
|
||||
separately from any other configuration file, so interpolations cannot
|
||||
penetrate from jail.* into actions.d/*. To overcome this, it is
|
||||
necessary to create a PARAMETER which can be substituted in actions
|
||||
[Definition] section, if it is also defined in the [Init] section of
|
||||
that file and is used in place of necessary allocation as <PARAMETER>
|
||||
tag. Parameters can be specified in the definitions within
|
||||
jail.{conf,local}. For instance, 1 lengthy example, where the same
|
||||
name "fwchain" is used both as interpolation (in jail.local) and as a
|
||||
parameter (in iptables-flex.local) (from #398739)
|
||||
|
||||
==> /etc/fail2ban/jail.local <==
|
||||
[DEFAULT]
|
||||
action = iptables-flex[name=%(__name__)s, port=%(port)s, fwchain=%(fwchain)s, post_start_commands=%(post_start_commands)s, pre_end_commands=%(pre_end_commands)s]
|
||||
fwchain = INPUT
|
||||
[ssh]
|
||||
fwchain = ssh-tarpit
|
||||
==> /etc/fail2ban/action.d/iptables-flex.local <==
|
||||
[Definition]
|
||||
actionstart = iptables -N fail2ban-<name>
|
||||
iptables -I <fwchain> -m state --state NEW -p <protocol> --dport <port> -j fail2ban-<name>
|
||||
iptables -I <fwchain> -j <whitelist>
|
||||
actionstop = iptables -D <fwchain> -j <whitelist>
|
||||
iptables -D <fwchain> -m state --state NEW -p <protocol> --dport <port> -j fail2ban-<name>
|
||||
iptables -F fail2ban-<name>
|
||||
iptables -X fail2ban-<name>
|
||||
actioncheck = iptables -n -L <fwchain> | grep -q fail2ban-<name>
|
||||
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
|
||||
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
|
||||
[Init]
|
||||
whitelist = ssh-whitelist
|
||||
fwchain = INPUT
|
||||
name = default
|
||||
port = ssh
|
||||
protocol = tcp
|
||||
|
||||
|
||||
* Multiport banning: Comment for #373592, #545971
|
||||
|
||||
iptables-multiport action is now default banaction (file jail.conf, to
|
||||
be customized within jail.local). Therefore assure that you have built
|
||||
multiport module if you use custom kernel.
|
||||
|
||||
If you would like to ban all ports for that host, just redefine
|
||||
fwban/fwunban commands to don't have --dport %(port)s statement at
|
||||
all, or use shorewall, where actionban bans whole IP.
|
||||
|
||||
* Blocking of NEW connections only
|
||||
Comment for the wishlist #350746.
|
||||
|
||||
It might be benefitial in some cases to ban only new connections. For
|
||||
that just use iptables-new action instead of default banaction
|
||||
|
||||
/etc/fail2ban/jail.local:
|
||||
|
||||
[DEFAULT]
|
||||
banaction=iptables-new
|
||||
|
||||
(you can override banaction within interesting for you section).
|
||||
Also you can redefine the whole action parameter if you like.
|
||||
|
||||
|
||||
* Interaction with ipmasq
|
||||
Comment to #461417
|
||||
|
||||
Although fail2ban should detect and recreate missing chains if the external
|
||||
command wipes out iptables, it is better to explicitly to force-reload
|
||||
fail2ban. For this reason there is examples/ipmasq-ZZZzzz|fail2ban.rul file is
|
||||
shipped along to be installed under name ZZZzzz|fail2ban.rul within
|
||||
/etc/ipmasq.
|
||||
|
||||
* Interaction with logrotate with custom logtarget
|
||||
Comment to #631917
|
||||
|
||||
if you use an alternative logtarget (e.g. SYSLOG) thus not using
|
||||
/var/log/fail2ban.log you should divert logrotate configuration into
|
||||
a disabled state, e.g.
|
||||
|
||||
sudo dpkg-divert --rename --divert \
|
||||
/etc/logrotate.d/fail2ban.disabled /etc/logrotate.d/fail2ban
|
||||
|
||||
|
||||
Troubleshooting:
|
||||
---------------
|
||||
|
||||
* Updated failregex:
|
||||
|
||||
To resolve the security bug #330827 [1] failregex expressions must
|
||||
provide a named group (?P<host>...) as a placeholder of the abuser's
|
||||
host. Alternative tag (since 0.7.5) can be "<HOST>". The naming of the
|
||||
group was introduced to capture possible future generalizations of
|
||||
failregex to provide even more information.
|
||||
|
||||
[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=330827
|
||||
|
||||
You might benefit from using fail2ban-regex command shipped along to
|
||||
construct and debug your failregex statements.
|
||||
|
||||
* "Interpolations" in the config file:
|
||||
|
||||
Since version 0.6.0-3 to reduce duplication, thus to improve
|
||||
readability of the config file, interpolations provided by the module
|
||||
ConfigParser are used. If you had custom sections defined before, you
|
||||
might benefit from updating config file and adding appropriate
|
||||
information for the new sections.
|
||||
|
||||
N.B. If you have some nice additional sections defined, I would really
|
||||
appreciate if you share them with me or upstream author, so they could
|
||||
be eventually included in the fail2ban package for general use by the
|
||||
rest of the community.
|
||||
|
||||
|
||||
* Mailing:
|
||||
|
||||
Since actions.d/mail*.conf commands rely on presence of "mail"
|
||||
command, mailx package (or another package providing mailx
|
||||
functionality such as mailutils) is required if those actions are
|
||||
activated in jail.{conf,local}.
|
||||
|
||||
|
||||
* Dirty exit:
|
||||
|
||||
If firewall rules gets cleaned out before fail2ban exits (like was
|
||||
happening with firestarter), errors get reported during the exit of
|
||||
fail2ban, but they are "safe" and can be ignored.
|
||||
|
||||
|
||||
** SSHD Configuration Specific Problems
|
||||
|
||||
* Ban "Not allowed" attempts:
|
||||
|
||||
Make sure that you have
|
||||
ChallengeResponseAuthentication no
|
||||
PasswordAuthentication yes
|
||||
|
||||
Details from the bug report #350980 [2]
|
||||
|
||||
[2] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350980
|
||||
|
||||
|
||||
* Not caught attempts to login as root
|
||||
|
||||
On the boxes running older versions of openssh (e.g. sarge
|
||||
distribution) in the case when PermitRootLogin is set to something
|
||||
else than "yes" and iff AllowUsers is active, failed root logins do
|
||||
not confirm to the standard logging message -- they omit the source
|
||||
IP, thus allowing attack to persist since such messages are not caught
|
||||
by fail2ban.
|
||||
|
||||
|
||||
* Bantime:
|
||||
|
||||
An IP is banned for "bantime" not since the last failed login attempt
|
||||
from the IP, but rather since the moment when failed login was
|
||||
detected by fail2ban. Thus, if fail2ban gets [re]started, any IP which
|
||||
had enough of failed logins with durations less than "findtime" between
|
||||
them prior to the [re]start moment, will be banned for
|
||||
"bantime" since [re]start moment, not since the last failed login
|
||||
time.
|
||||
|
||||
* Findtime:
|
||||
|
||||
"Findtime" option of a jail actually defines a duration to reset the
|
||||
counter of failed login attempts, if no new attempt was detected within
|
||||
that time frame (i.e. within "findtime").
|
||||
|
||||
See
|
||||
http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jail_Options
|
||||
for more information on jail options.
|
||||
|
||||
|
||||
* Syslog entries can be 'forged' by a regular user
|
||||
|
||||
From
|
||||
http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Possibility_of_DOS_attack_by_a_local_user
|
||||
|
||||
Especially on systems wich provide ssh/CGI/PHP services to unknown
|
||||
users it is possible to block other users from ssh and probably other
|
||||
access as a unprivileged user may issue:
|
||||
|
||||
logger -p auth.warning -t 'sshd[123]' 'Illegal user user1 from 1.2.3.4'
|
||||
|
||||
N.B. chmod o-x /usr/bin/logger should provide at least obfuscation
|
||||
solution
|
||||
|
||||
Or the malicious user may write via PHP's openlog()/syslog() to syslog.
|
||||
|
||||
P.S. Anyone is welcome to recommend proper security solution to this
|
||||
issue, such as an alternative to sysklogd which allows better control
|
||||
over users logging to specific facilities (such as AUTH)
|
||||
|
||||
-- Yaroslav Halchenko <debian@onerussian.com>, Thu, 28 Jul 2011 23:19:44 -0400
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
* Collect more sections for other log files
|
||||
* Find proper answer to "Syslog entries can be 'forged' by a regular
|
||||
user" mentioned in README.Debian
|
||||
|
||||
-- Yaroslav O. Halchenko <debian@onerussian.com> Wed, 6 Dec 2006 22:14:26 -0500
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
nopycentral.patch
|
||||
Vendored
-40
@@ -1,40 +0,0 @@
|
||||
diff -x '*~' -x .svn -Naur trunk/debian/control trunk.backports/debian/control
|
||||
--- trunk/debian/control 2006-10-23 00:57:02.000000000 -0400
|
||||
+++ trunk.backports/debian/control 2006-12-04 08:45:25.000000000 -0500
|
||||
@@ -4,13 +4,13 @@
|
||||
Maintainer: Yaroslav Halchenko <debian@onerussian.com>
|
||||
Uploaders: Barak Pearlmutter <bap@debian.org>
|
||||
Build-Depends: debhelper (>= 5.0.37.2), dpatch
|
||||
-Build-Depends-Indep: python, python-dev, help2man, python-central (>= 0.5.6)
|
||||
+Build-Depends-Indep: python, python2.4, python2.4-dev, help2man
|
||||
XS-Python-Version: current, >= 2.4
|
||||
Standards-Version: 3.7.2
|
||||
|
||||
Package: fail2ban
|
||||
Architecture: all
|
||||
-Depends: ${python:Depends}, iptables, lsb-base (>=2.0-7)
|
||||
+Depends: python2.4, iptables, lsb-base (>=2.0-7)
|
||||
Suggests: python-gamin
|
||||
XB-Python-Version: ${python:Versions}
|
||||
Description: bans IPs that cause multiple authentication errors
|
||||
diff -x '*~' -x .svn -Naur trunk/debian/rules trunk.backports/debian/rules
|
||||
--- trunk/debian/rules 2006-11-11 21:19:14.000000000 -0500
|
||||
+++ trunk.backports/debian/rules 2006-12-04 08:45:45.000000000 -0500
|
||||
@@ -39,7 +39,7 @@
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/fail2ban.
|
||||
- python setup.py install --root=$(DESTDIR) --no-compile
|
||||
+ python2.4 setup.py install --root=$(DESTDIR) --no-compile
|
||||
#X Evil - must be removed after Debian switches over to 2.4, now
|
||||
# distutils.setup will override the enterpreter line to /usr/bin/python
|
||||
install fail2ban-server fail2ban-client $(DESTDIR)/usr/bin
|
||||
@@ -62,7 +62,7 @@
|
||||
dh_installlogrotate
|
||||
dh_installinit -- defaults 99
|
||||
dh_installman man/*.1
|
||||
- dh_pycentral
|
||||
+ dh_python
|
||||
dh_link
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
Vendored
-1180
File diff suppressed because it is too large
Load Diff
Vendored
-1
@@ -1 +0,0 @@
|
||||
9
|
||||
Vendored
-29
@@ -1,29 +0,0 @@
|
||||
Source: fail2ban
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Yaroslav Halchenko <debian@onerussian.com>
|
||||
Build-Depends: debhelper (>= 9), python3 (>= 3.0~), python3-pyinotify, dh-systemd
|
||||
Homepage: http://www.fail2ban.org
|
||||
Vcs-Git: git://github.com/fail2ban/fail2ban.git
|
||||
Vcs-Browser: http://github.com/fail2ban/fail2ban
|
||||
Standards-Version: 3.9.4
|
||||
|
||||
|
||||
Package: fail2ban
|
||||
Architecture: all
|
||||
Depends: ${python3:Depends}, ${misc:Depends}, lsb-base (>=2.0-7)
|
||||
Recommends: iptables, whois, python3-pyinotify
|
||||
Suggests: python-gamin, mailx, system-log-daemon, python3-systemd
|
||||
Description: ban hosts that cause multiple authentication errors
|
||||
Fail2ban monitors log files (e.g. /var/log/auth.log,
|
||||
/var/log/apache/access.log) and temporarily or persistently bans
|
||||
failure-prone addresses by updating existing firewall rules. Fail2ban allows
|
||||
easy specification of different actions to be taken such as to ban an
|
||||
IP using iptables or hostsdeny rules, or simply to send a
|
||||
notification email.
|
||||
.
|
||||
By default, it comes with filter expressions for various services
|
||||
(sshd, apache, qmail, proftpd, sasl etc.) but configuration can be
|
||||
easily extended for monitoring any other text file. All filters and
|
||||
actions are given in the config files, thus fail2ban can be adopted
|
||||
to be used with a variety of files and firewalls.
|
||||
Vendored
-31
@@ -1,31 +0,0 @@
|
||||
This package was originally debianized by Yaroslav Halchenko
|
||||
<debian@onerussian.com> on Mon Jul 4 14:41:34 HST 2005
|
||||
|
||||
It was downloaded from http://www.sourceforge.net/projects/fail2ban
|
||||
|
||||
Author: Cyril Jaquier: <cyril.jaquier@fail2ban.org>
|
||||
http://fail2ban.sourceforge.net
|
||||
|
||||
Copyright: 2004-2009 Cyril Jaquier
|
||||
|
||||
This program 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License, version 2, can be found in /usr/share/common-licenses/GPL-2.
|
||||
|
||||
The Debian packaging is (C) 2006-2011, Yaroslav Halchenko <debian@onerussian.com>
|
||||
and is licensed under the GPL, see above.
|
||||
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
README.md
|
||||
TODO
|
||||
doc/run-rootless.txt
|
||||
Vendored
-39
@@ -1,39 +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$
|
||||
|
||||
# Command line options for Fail2Ban. Refer to "fail2ban-client -h" for
|
||||
# valid options.
|
||||
FAIL2BAN_OPTS=""
|
||||
|
||||
# Run fail2ban as a different user. If not set, fail2ban
|
||||
# will run as root.
|
||||
#
|
||||
# The user is not created automatically.
|
||||
# The user can be created e.g. with
|
||||
# useradd --system --no-create-home --home-dir / --groups adm fail2ban
|
||||
# Log files are readable by group adm by default. Adding the fail2ban
|
||||
# user to this group allows it to read the logfiles.
|
||||
#
|
||||
# Another manual step that needs to be taken is to allow write access
|
||||
# for fail2ban user to fail2ban log files. The /etc/init.d/fail2ban
|
||||
# script will change the ownership when starting fail2ban. Logrotate
|
||||
# needs to be configured separately, see /etc/logrotate.d/fail2ban.
|
||||
#
|
||||
# FAIL2BAN_USER="fail2ban"
|
||||
Vendored
-244
@@ -1,244 +0,0 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: fail2ban
|
||||
# Required-Start: $local_fs $remote_fs
|
||||
# Required-Stop: $local_fs $remote_fs
|
||||
# Should-Start: $time $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall iptables-persistent ferm
|
||||
# Should-Stop: $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall iptables-persistent ferm
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start/stop fail2ban
|
||||
# Description: Start/stop fail2ban, a daemon scanning the log files and
|
||||
# banning potential attackers.
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Aaron Isotton <aaron@isotton.com>
|
||||
# Modified: by Yaroslav Halchenko <debian@onerussian.com>
|
||||
# reindented + minor corrections + to work on sarge without modifications
|
||||
# Modified: by Glenn Aaldering <glenn@openvideo.nl>
|
||||
# added exit codes for status command
|
||||
#
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
DESC="authentication failure monitor"
|
||||
NAME=fail2ban
|
||||
|
||||
# fail2ban-client is not a daemon itself but starts a daemon and
|
||||
# loads its with configuration
|
||||
DAEMON=/usr/bin/$NAME-client
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Ad-hoc way to parse out socket file name
|
||||
SOCKFILE=`grep -h '^[^#]*socket *=' /etc/$NAME/$NAME.conf /etc/$NAME/$NAME.local 2>/dev/null \
|
||||
| tail -n 1 | sed -e 's/.*socket *= *//g' -e 's/ *$//g'`
|
||||
[ -z "$SOCKFILE" ] && SOCKFILE='/tmp/fail2ban.sock'
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Run as root by default.
|
||||
FAIL2BAN_USER=root
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
DAEMON_ARGS="$FAIL2BAN_OPTS"
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
[ -f /etc/default/rcS ] && . /etc/default/rcS
|
||||
|
||||
# Predefine what can be missing from lsb source later on -- necessary to run
|
||||
# on sarge. Just present it in a bit more compact way from what was shipped
|
||||
log_daemon_msg () {
|
||||
[ -z "$1" ] && return 1
|
||||
echo -n "$1:"
|
||||
[ -z "$2" ] || echo -n " $2"
|
||||
}
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
# Actually has to (>=2.0-7) present in sarge. log_daemon_msg is predefined
|
||||
# so we must be ok
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Shortcut function for abnormal init script interruption
|
||||
#
|
||||
report_bug()
|
||||
{
|
||||
echo $*
|
||||
echo "Please submit a bug report to Debian BTS (reportbug fail2ban)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Helper function to check if socket is present, which is often left after
|
||||
# abnormal exit of fail2ban and needs to be removed
|
||||
#
|
||||
check_socket()
|
||||
{
|
||||
# Return
|
||||
# 0 if socket is present and readable
|
||||
# 1 if socket file is not present
|
||||
# 2 if socket file is present but not readable
|
||||
# 3 if socket file is present but is not a socket
|
||||
[ -e "$SOCKFILE" ] || return 1
|
||||
[ -r "$SOCKFILE" ] || return 2
|
||||
[ -S "$SOCKFILE" ] || return 3
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
do_status && return 1
|
||||
|
||||
if [ -e "$SOCKFILE" ]; then
|
||||
log_failure_msg "Socket file $SOCKFILE is present"
|
||||
[ "$1" = "force-start" ] \
|
||||
&& log_success_msg "Starting anyway as requested" \
|
||||
|| return 2
|
||||
DAEMON_ARGS="$DAEMON_ARGS -x"
|
||||
fi
|
||||
|
||||
# Assure that /var/run/fail2ban exists
|
||||
[ -d /var/run/fail2ban ] || mkdir -p /var/run/fail2ban
|
||||
|
||||
if [ "$FAIL2BAN_USER" != "root" ]; then
|
||||
# Make the socket directory, IP lists and fail2ban log
|
||||
# files writable by fail2ban
|
||||
chown "$FAIL2BAN_USER" /var/run/fail2ban
|
||||
# Create the logfile if it doesn't exist
|
||||
touch /var/log/fail2ban.log
|
||||
chown "$FAIL2BAN_USER" /var/log/fail2ban.log
|
||||
find /proc/net/xt_recent -name 'fail2ban-*' -exec chown "$FAIL2BAN_USER" {} \;
|
||||
fi
|
||||
|
||||
start-stop-daemon --start --quiet --chuid "$FAIL2BAN_USER" --exec $DAEMON -- \
|
||||
$DAEMON_ARGS start > /dev/null\
|
||||
|| return 2
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Function that checks the status of fail2ban and returns
|
||||
# corresponding code
|
||||
#
|
||||
do_status()
|
||||
{
|
||||
$DAEMON ping > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
$DAEMON status > /dev/null 2>&1 || return 1
|
||||
$DAEMON stop > /dev/null || return 2
|
||||
|
||||
# now we need actually to wait a bit since it might take time
|
||||
# for server to react on client's stop request. Especially
|
||||
# important for restart command on slow boxes
|
||||
count=1
|
||||
while do_status && [ $count -lt 60 ]; do
|
||||
sleep 1
|
||||
count=$(($count+1))
|
||||
done
|
||||
[ $count -lt 60 ] || return 3 # failed to stop
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Function to reload configuration
|
||||
#
|
||||
do_reload() {
|
||||
$DAEMON reload > /dev/null && return 0 || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# yoh:
|
||||
# shortcut function to don't duplicate case statements and to don't use
|
||||
# bashisms (arrays). Fixes #368218
|
||||
#
|
||||
log_end_msg_wrapper()
|
||||
{
|
||||
if [ "$3" != "no" ]; then
|
||||
[ $1 -lt $2 ] && value=0 || value=1
|
||||
log_end_msg $value
|
||||
fi
|
||||
}
|
||||
|
||||
command="$1"
|
||||
case "$command" in
|
||||
start|force-start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start "$command"
|
||||
log_end_msg_wrapper $? 2 "$VERBOSE"
|
||||
;;
|
||||
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
log_end_msg_wrapper $? 2 "$VERBOSE"
|
||||
;;
|
||||
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
log_end_msg_wrapper $? 1 "always"
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
reload|force-reload)
|
||||
log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
do_reload
|
||||
log_end_msg $?
|
||||
;;
|
||||
|
||||
status)
|
||||
log_daemon_msg "Status of $DESC"
|
||||
do_status
|
||||
case $? in
|
||||
0) log_success_msg " $NAME is running" ;;
|
||||
255)
|
||||
check_socket
|
||||
case $? in
|
||||
1) log_failure_msg " $NAME is not running" && exit 3 ;;
|
||||
0) log_failure_msg " $NAME is not running but $SOCKFILE exists" && exit 3 ;;
|
||||
2) log_failure_msg " $SOCKFILE not readable, status of $NAME is unknown" && exit 3 ;;
|
||||
3) log_failure_msg " $SOCKFILE exists but not a socket, status of $NAME is unknown" && exit 3 ;;
|
||||
*) report_bug "Unknown return code from $NAME:check_socket." && exit 4 ;;
|
||||
esac
|
||||
;;
|
||||
*) report_bug "Unknown $NAME status code" && exit 4
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|force-start|stop|restart|force-reload|status}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
/var/log/fail2ban.log {
|
||||
|
||||
weekly
|
||||
rotate 4
|
||||
compress
|
||||
|
||||
delaycompress
|
||||
missingok
|
||||
postrotate
|
||||
fail2ban-client flushlogs 1>/dev/null
|
||||
endscript
|
||||
|
||||
# If fail2ban runs as non-root it still needs to have write access
|
||||
# to logfiles.
|
||||
# create 640 fail2ban adm
|
||||
create 640 root adm
|
||||
}
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
[DEFAULT]
|
||||
# the default branch for upstream sources:
|
||||
upstream-branch = upstream
|
||||
# the default branch for the debian patch:
|
||||
debian-branch = debian-releases/experimental
|
||||
# use pristine-tar
|
||||
# pristine-tar = True
|
||||
# the default tag formats used:
|
||||
upstream-tag = %(version)s
|
||||
debian-tag = debian/%(version)s
|
||||
|
||||
|
||||
# Options only affecting git-buildpackage
|
||||
[git-buildpackage]
|
||||
# use this for more svn-buildpackage like bahaviour:
|
||||
export-dir = ../build-area/
|
||||
tarball-dir = ../tarballs/
|
||||
|
||||
-1556
File diff suppressed because it is too large
Load Diff
-26
@@ -1,26 +0,0 @@
|
||||
From: Yaroslav Halchenko <debian@onerussian.com>
|
||||
Date: Fri, 8 Feb 2008 00:40:57 -0500
|
||||
Subject: tune ups in upstream manpages to direct users to use reportbug
|
||||
|
||||
--- a/man/fail2ban-client.1
|
||||
+++ b/man/fail2ban-client.1
|
||||
@@ -369,7 +369,7 @@
|
||||
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
-Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||
+Report bugs via Debian bug tracking system \fIhttp://www.debian.org/Bugs/\fR .
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors
|
||||
.br
|
||||
--- a/man/fail2ban-server.1
|
||||
+++ b/man/fail2ban-server.1
|
||||
@@ -38,7 +38,7 @@
|
||||
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
-Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||
+Report bugs via Debian bug tracking system \fIhttp://www.debian.org/Bugs/\fR .
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors
|
||||
.br
|
||||
Vendored
-46
@@ -1,46 +0,0 @@
|
||||
From: Yaroslav Halchenko <debian@onerussian.com>
|
||||
Date: Thu, 6 Dec 2012 12:50:12 -0500
|
||||
Subject: [PATCH] Patch for elderly Debian/Ubuntu (e.g. 10.04) releases without dh_python2
|
||||
|
||||
Use again pycentral etc
|
||||
|
||||
crafted post 0.8.8-1 release when a user complained about inability to upgrade
|
||||
|
||||
---
|
||||
debian/control | 2 ++
|
||||
debian/rules | 12 +++++-------
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/debian/control
|
||||
+++ b/debian/control
|
||||
@@ -3,6 +3,8 @@ Section: net
|
||||
Priority: optional
|
||||
Maintainer: Yaroslav Halchenko <debian@onerussian.com>
|
||||
Build-Depends: debhelper (>= 5.0.37.2), python (>= 2.5.4-1~), python-pyinotify
|
||||
+Build-Depends-Indep: python-central (>= 0.5.6)
|
||||
+XS-Python-Version: current, >= 2.4
|
||||
Homepage: http://www.fail2ban.org
|
||||
Vcs-Git: git://github.com/fail2ban/fail2ban.git
|
||||
Vcs-Browser: http://github.com/fail2ban/fail2ban
|
||||
--- a/debian/rules
|
||||
+++ b/debian/rules
|
||||
@@ -72,14 +72,12 @@ binary-indep: install
|
||||
dh_installdocs
|
||||
dh_installexamples config/jail.conf files/ipmasq-*
|
||||
dh_installlogrotate
|
||||
- dh_python2 /usr/share/fail2ban
|
||||
+ dh_pycentral
|
||||
dh_installinit -- defaults 99
|
||||
-
|
||||
- # perform swap of order of calls to init and pycentral (or even
|
||||
- # bleedingly new dh_python2) in prerm to close #422655 --
|
||||
- # python-cleanup section is cut and placed at the end of the file
|
||||
- # since .init script would trigger their compilation again
|
||||
- sed -i -e '/^#.*ed by dh_python2/,/# End auto/{H;d};$$G' \
|
||||
+ # perform swap of order of calls to init and pycentral in prerm
|
||||
+ # to close #422655 -- pycentral section is cut and placed at
|
||||
+ # the end of the file
|
||||
+ sed -i -e '/^#.*ed by dh_pycentral/,/# End auto/{H;d};$$G' \
|
||||
debian/fail2ban.prerm.debhelper
|
||||
|
||||
dh_installman man/*.[15]
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
deb_manpages_reportbug
|
||||
convert-to-python3.patch
|
||||
Vendored
-98
@@ -1,98 +0,0 @@
|
||||
#! /bin/sh
|
||||
# postinst script for fail2ban
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
#
|
||||
preversion=$2
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# To fix the bug in generated by previous version files permissions
|
||||
# also closes #352053
|
||||
|
||||
LOG=/var/log/fail2ban.log
|
||||
touch $LOG
|
||||
chown root:adm ${LOG}*
|
||||
chmod 640 ${LOG}*
|
||||
|
||||
# Note regarding changed configuration file
|
||||
# Note regarding changed configuration file
|
||||
if [ ! -z $preversion ]; then
|
||||
if dpkg --compare-versions $preversion lt 0.7.1-1; then
|
||||
cat <<EOF
|
||||
WARNING!
|
||||
|
||||
Fail2ban 0.7 is a complete rewrite of the 0.6 version, and if you
|
||||
customized any of provided configuration or startup files
|
||||
(/etc/default/fail2ban, /etc/fail2ban.conf, /etc/init.d/fail2ban), please
|
||||
read relevant entry in /usr/share/doc/fail2ban/NEWS.Debian.gz.
|
||||
|
||||
EOF
|
||||
fi
|
||||
if dpkg --compare-versions $preversion lt 0.5.4-5.14; then
|
||||
cat <<EOF
|
||||
WARNING!
|
||||
|
||||
Configuration file /etc/fail2ban.conf, failregex configuration
|
||||
parameter specificly, were changed in 0.5.4-5 to close reported
|
||||
security breach, and in 0.5.4-5.14 to close few other bugs.
|
||||
|
||||
updating from <0.5.4-5
|
||||
Unless configuration file (or corresponding failregex'es) gets updated,
|
||||
security breach is not closed and corresponding warning will be reported
|
||||
by the fail2ban (in the log files).
|
||||
|
||||
updating from <0.5.4-5.14
|
||||
Bugs #329163, #331695 dealing with changed iptables rules
|
||||
outside of fail2ban were fixed in 0.5.4-5.14, and require upgrade of the
|
||||
configuration file (fwcheck option was introduced) to take full
|
||||
advantage of the problem solution (otherwise some problems might
|
||||
persist)
|
||||
|
||||
Please review the configuration file and make appropriate changes.
|
||||
ENJOY!
|
||||
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if dpkg-maintscript-helper supports mv_conffile 2>/dev/null; then
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/action.d/firewall-cmd-direct-new.conf /etc/fail2ban/action.d/firewallcmd-new.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/lighttpd-fastcgi.conf /etc/fail2ban/filter.d/suhosin.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/sasl.conf /etc/fail2ban/filter.d/postfix-sasl.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/couriersmtp.conf /etc/fail2ban/filter.d/courier-smtp.conf 0.9.0-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/courierlogin.conf /etc/fail2ban/filter.d/courier-auth.conf 0.9.0-1~ -- "$@"
|
||||
fi
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
#! /bin/sh
|
||||
# postrm script for fail2ban
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postrm> `remove'
|
||||
# * <postrm> `purge'
|
||||
# * <old-postrm> `upgrade' <new-version>
|
||||
# * <new-postrm> `failed-upgrade' <old-version>
|
||||
# * <new-postrm> `abort-install'
|
||||
# * <new-postrm> `abort-install' <old-version>
|
||||
# * <new-postrm> `abort-upgrade' <old-version>
|
||||
# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
|
||||
# for details, see /usr/doc/packaging-manual/
|
||||
|
||||
|
||||
case "$1" in
|
||||
purge|disappear)
|
||||
|
||||
# Remove configuration
|
||||
rm -f /etc/fail2ban.conf
|
||||
|
||||
# Remove logs
|
||||
rm -f /var/log/fail2ban*
|
||||
|
||||
# Remove sqlite db
|
||||
rm -f /var/lib/fail2ban/fail2ban.sqlite3
|
||||
;;
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade)
|
||||
# nothing
|
||||
# We may not delete the user fail2ban, as there may be
|
||||
# files owned by it in /var/log/ and /etc/.
|
||||
;;
|
||||
esac
|
||||
|
||||
if dpkg-maintscript-helper supports mv_conffile 2>/dev/null; then
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/action.d/firewall-cmd-direct-new.conf /etc/fail2ban/action.d/firewallcmd-new.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/lighttpd-fastcgi.conf /etc/fail2ban/filter.d/suhosin.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/sasl.conf /etc/fail2ban/filter.d/postfix-sasl.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/couriersmtp.conf /etc/fail2ban/filter.d/courier-smtp.conf 0.9.0-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/courierlogin.conf /etc/fail2ban/filter.d/courier-auth.conf 0.9.0-1~ -- "$@"
|
||||
fi
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
|
||||
Vendored
-15
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if dpkg-maintscript-helper supports mv_conffile 2>/dev/null; then
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/action.d/firewall-cmd-direct-new.conf /etc/fail2ban/action.d/firewallcmd-new.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/lighttpd-fastcgi.conf /etc/fail2ban/filter.d/suhosin.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/sasl.conf /etc/fail2ban/filter.d/postfix-sasl.conf 0.8.13-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/couriersmtp.conf /etc/fail2ban/filter.d/courier-smtp.conf 0.9.0-1~ -- "$@"
|
||||
dpkg-maintscript-helper mv_conffile /etc/fail2ban/filter.d/courierlogin.conf /etc/fail2ban/filter.d/courier-auth.conf 0.9.0-1~ -- "$@"
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
Vendored
-53
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@ --with python3,systemd --buildsystem pybuild
|
||||
|
||||
DESTDIR=$(CURDIR)/debian/fail2ban
|
||||
|
||||
override_dh_clean:
|
||||
rm -rf fail2ban.egg-info
|
||||
dh_clean
|
||||
|
||||
override_dh_install:
|
||||
rm -f $(DESTDIR)/usr/share/doc/fail2ban/README.Solaris
|
||||
: # Remove explicitely created /var/run/fail2ban
|
||||
: # just to please lintian since init file will
|
||||
: # take care about it anyways
|
||||
rm -rf $(DESTDIR)/var/run/
|
||||
: # Install bash completion
|
||||
install -d $(DESTDIR)/etc/bash_completion.d
|
||||
install -m 644 files/bash-completion $(DESTDIR)/etc/bash_completion.d/fail2ban
|
||||
: # Install systemd files
|
||||
install -d $(DESTDIR)/lib/systemd/system
|
||||
install -d $(DESTDIR)/usr/lib/tmpfiles.d
|
||||
install -m 644 files/fail2ban.service $(DESTDIR)/lib/systemd/system
|
||||
install -m 644 files/fail2ban-tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d
|
||||
install -d $(DESTDIR)/lib/systemd/system
|
||||
: # Install default jail enabler
|
||||
install -m 644 debian/source/jail.d_defaults-debian.conf $(DESTDIR)/etc/fail2ban/jail.d/defaults-debian.conf
|
||||
dh_install
|
||||
|
||||
override_dh_auto_test:
|
||||
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
||||
cd build && PYTHONPATH=../.pybuild/pythonX.Y_3.4/build/ scripts-*/fail2ban-testcases --no-network
|
||||
|
||||
endif
|
||||
|
||||
override_dh_installexamples:
|
||||
dh_installexamples files/ipmasq-* files/nagios files/cacti
|
||||
|
||||
override_dh_installinit:
|
||||
dh_installinit -- defaults 99
|
||||
|
||||
override_dh_installman:
|
||||
dh_installman man/*.[15]
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
3.0 (quilt)
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
[sshd]
|
||||
enabled = true
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
# watch control file for uscan
|
||||
# Run the "uscan" command to check for upstream updates and more.
|
||||
# Site Directory Pattern Version Script
|
||||
version=3
|
||||
opts="filenamemangle=s/.*\/(.*).tar.gz/fail2ban_$1\.orig.tar.gz/" \
|
||||
http://githubredir.debian.net/github/fail2ban/fail2ban /([\.0-9]*).tar.gz
|
||||
@@ -45,7 +45,7 @@ class Beautifier:
|
||||
return self.__inputCmd
|
||||
|
||||
def beautify(self, response):
|
||||
logSys.debug("Beautify " + repr(response) + " with " + repr(self.__inputCmd))
|
||||
logSys.debug("Beautify " + `response` + " with " + `self.__inputCmd`)
|
||||
inC = self.__inputCmd
|
||||
msg = response
|
||||
try:
|
||||
@@ -99,7 +99,7 @@ class Beautifier:
|
||||
elif response == 4:
|
||||
msg = msg + "DEBUG"
|
||||
else:
|
||||
msg = msg + repr(response)
|
||||
msg = msg + `response`
|
||||
elif inC[1] == "dbfile":
|
||||
if response is None:
|
||||
msg = "Database currently disabled"
|
||||
@@ -180,13 +180,13 @@ class Beautifier:
|
||||
msg += ", ".join(response)
|
||||
except Exception:
|
||||
logSys.warning("Beautifier error. Please report the error")
|
||||
logSys.error("Beautify " + repr(response) + " with " + repr(self.__inputCmd) +
|
||||
logSys.error("Beautify " + `response` + " with " + `self.__inputCmd` +
|
||||
" failed")
|
||||
msg = msg + repr(response)
|
||||
msg = msg + `response`
|
||||
return msg
|
||||
|
||||
def beautifyError(self, response):
|
||||
logSys.debug("Beautify (error) " + repr(response) + " with " + repr(self.__inputCmd))
|
||||
logSys.debug("Beautify (error) " + `response` + " with " + `self.__inputCmd`)
|
||||
msg = response
|
||||
if isinstance(response, UnknownJailException):
|
||||
msg = "Sorry but the jail '" + response.args[0] + "' does not exist"
|
||||
|
||||
@@ -58,7 +58,7 @@ if sys.version_info >= (3,2): # pragma: no cover
|
||||
parser, option, accum, rest, section, map, depth)
|
||||
|
||||
else: # pragma: no cover
|
||||
from configparser import SafeConfigParser
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger(__name__)
|
||||
@@ -122,7 +122,7 @@ after = 1.conf
|
||||
parser.read(resource, encoding='utf-8')
|
||||
else:
|
||||
parser.read(resource)
|
||||
except UnicodeDecodeError as e:
|
||||
except UnicodeDecodeError, e:
|
||||
logSys.error("Error decoding config file '%s': %s" % (resource, e))
|
||||
return []
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import glob, os
|
||||
from configparser import NoOptionError, NoSectionError
|
||||
from ConfigParser import NoOptionError, NoSectionError
|
||||
|
||||
from .configparserinc import SafeConfigParserWithIncludes
|
||||
from ..helpers import getLogger
|
||||
@@ -67,7 +67,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||
config_files += sorted(glob.glob('%s/*.local' % config_dir))
|
||||
|
||||
# choose only existing ones
|
||||
config_files = list(filter(os.path.exists, config_files))
|
||||
config_files = filter(os.path.exists, config_files)
|
||||
|
||||
if len(config_files):
|
||||
# at least one config exists and accessible
|
||||
@@ -111,7 +111,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||
if not pOptions is None and option[1] in pOptions:
|
||||
continue
|
||||
values[option[1]] = v
|
||||
except NoSectionError as e:
|
||||
except NoSectionError, e:
|
||||
# No "Definition" section or wrong basedir
|
||||
logSys.error(e)
|
||||
values[option[1]] = option[2]
|
||||
@@ -127,7 +127,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||
option[1], sec)
|
||||
except ValueError:
|
||||
logSys.warning("Wrong value for '" + option[1] + "' in '" + sec +
|
||||
"'. Using default one: '" + repr(option[2]) + "'")
|
||||
"'. Using default one: '" + `option[2]` + "'")
|
||||
values[option[1]] = option[2]
|
||||
return values
|
||||
|
||||
@@ -174,7 +174,7 @@ class DefinitionInitConfigReader(ConfigReader):
|
||||
|
||||
if self.has_section("Init"):
|
||||
for opt in self.options("Init"):
|
||||
if opt not in self._initOpts:
|
||||
if not self._initOpts.has_key(opt):
|
||||
self._initOpts[opt] = self.get("Init", opt)
|
||||
|
||||
def convert(self):
|
||||
|
||||
@@ -63,7 +63,7 @@ class CSocket:
|
||||
while msg.rfind(CSocket.END_STRING) == -1:
|
||||
chunk = sock.recv(6)
|
||||
if chunk == '':
|
||||
raise RuntimeError("socket connection broken")
|
||||
raise RuntimeError, "socket connection broken"
|
||||
msg = msg + chunk
|
||||
return loads(msg)
|
||||
receive = staticmethod(receive)
|
||||
|
||||
@@ -49,7 +49,7 @@ class FilterReader(DefinitionInitConfigReader):
|
||||
opts = CommandAction.substituteRecursiveTags(combinedopts)
|
||||
if not opts:
|
||||
raise ValueError('recursive tag definitions unable to be resolved')
|
||||
for opt, value in opts.items():
|
||||
for opt, value in opts.iteritems():
|
||||
if opt == "failregex":
|
||||
for regex in value.split('\n'):
|
||||
# Do not send a command if the rule is empty.
|
||||
|
||||
@@ -148,7 +148,7 @@ class JailReader(ConfigReader):
|
||||
self.__actions.append(action)
|
||||
else:
|
||||
raise AttributeError("Unable to read action")
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
logSys.error("Error in action definition " + act)
|
||||
logSys.debug("Caught exception: %s" % (e,))
|
||||
return False
|
||||
|
||||
+13
-13
@@ -128,7 +128,7 @@ def printFormatted():
|
||||
firstHeading = False
|
||||
for m in protocol:
|
||||
if m[0] == '' and firstHeading:
|
||||
print()
|
||||
print
|
||||
firstHeading = True
|
||||
first = True
|
||||
if len(m[0]) >= MARGIN:
|
||||
@@ -139,7 +139,7 @@ def printFormatted():
|
||||
first = False
|
||||
else:
|
||||
line = ' ' * (INDENT + MARGIN) + n.strip()
|
||||
print(line)
|
||||
print line
|
||||
|
||||
##
|
||||
# Prints the protocol in a "mediawiki" format.
|
||||
@@ -149,19 +149,19 @@ def printWiki():
|
||||
for m in protocol:
|
||||
if m[0] == '':
|
||||
if firstHeading:
|
||||
print("|}")
|
||||
print "|}"
|
||||
__printWikiHeader(m[1], m[2])
|
||||
firstHeading = True
|
||||
else:
|
||||
print("|-")
|
||||
print("| <span style=\"white-space:nowrap;\"><tt>" + m[0] + "</tt></span> || || " + m[1])
|
||||
print("|}")
|
||||
print "|-"
|
||||
print "| <span style=\"white-space:nowrap;\"><tt>" + m[0] + "</tt></span> || || " + m[1]
|
||||
print "|}"
|
||||
|
||||
def __printWikiHeader(section, desc):
|
||||
print()
|
||||
print("=== " + section + " ===")
|
||||
print()
|
||||
print(desc)
|
||||
print()
|
||||
print("{|")
|
||||
print("| '''Command''' || || '''Description'''")
|
||||
print
|
||||
print "=== " + section + " ==="
|
||||
print
|
||||
print desc
|
||||
print
|
||||
print "{|"
|
||||
print "| '''Command''' || || '''Description'''"
|
||||
|
||||
@@ -27,7 +27,6 @@ from abc import ABCMeta
|
||||
from collections import MutableMapping
|
||||
|
||||
from ..helpers import getLogger
|
||||
import collections
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger(__name__)
|
||||
@@ -48,7 +47,7 @@ _RETCODE_HINTS = {
|
||||
|
||||
# Dictionary to lookup signal name from number
|
||||
signame = dict((num, name)
|
||||
for name, num in signal.__dict__.items() if name.startswith("SIG"))
|
||||
for name, num in signal.__dict__.iteritems() if name.startswith("SIG"))
|
||||
|
||||
class CallingMap(MutableMapping):
|
||||
"""A Mapping type which returns the result of callable values.
|
||||
@@ -75,7 +74,7 @@ class CallingMap(MutableMapping):
|
||||
|
||||
def __getitem__(self, key):
|
||||
value = self.data[key]
|
||||
if isinstance(value, collections.Callable):
|
||||
if callable(value):
|
||||
return value()
|
||||
else:
|
||||
return value
|
||||
@@ -95,7 +94,7 @@ class CallingMap(MutableMapping):
|
||||
def copy(self):
|
||||
return self.__class__(self.data.copy())
|
||||
|
||||
class ActionBase(object, metaclass=ABCMeta):
|
||||
class ActionBase(object):
|
||||
"""An abstract base class for actions in Fail2Ban.
|
||||
|
||||
Action Base is a base definition of what methods need to be in
|
||||
@@ -125,6 +124,7 @@ class ActionBase(object, metaclass=ABCMeta):
|
||||
Any additional arguments specified in `jail.conf` or passed
|
||||
via `fail2ban-client` will be passed as keyword arguments.
|
||||
"""
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@classmethod
|
||||
def __subclasshook__(cls, C):
|
||||
@@ -135,7 +135,7 @@ class ActionBase(object, metaclass=ABCMeta):
|
||||
"unban",
|
||||
)
|
||||
for method in required:
|
||||
if not isinstance(getattr(C, method, None), collections.Callable):
|
||||
if not callable(getattr(C, method, None)):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -242,7 +242,7 @@ class CommandAction(ActionBase):
|
||||
return dict(
|
||||
(key, getattr(self, key))
|
||||
for key in dir(self)
|
||||
if not key.startswith("_") and not isinstance(getattr(self, key), collections.Callable))
|
||||
if not key.startswith("_") and not callable(getattr(self, key)))
|
||||
|
||||
@property
|
||||
def actionstart(self):
|
||||
@@ -379,7 +379,7 @@ class CommandAction(ActionBase):
|
||||
within the values recursively replaced.
|
||||
"""
|
||||
t = re.compile(r'<([^ >]+)>')
|
||||
for tag in tags.keys():
|
||||
for tag in tags.iterkeys():
|
||||
if tag in cls._escapedTags:
|
||||
# Escaped so won't match
|
||||
continue
|
||||
@@ -398,7 +398,7 @@ class CommandAction(ActionBase):
|
||||
# Escaped so won't match
|
||||
continue
|
||||
else:
|
||||
if found_tag in tags:
|
||||
if tags.has_key(found_tag):
|
||||
value = value.replace('<%s>' % found_tag , tags[found_tag])
|
||||
#logSys.log(5, 'value now: %s' % value)
|
||||
done.append(found_tag)
|
||||
@@ -563,7 +563,7 @@ class CommandAction(ActionBase):
|
||||
os.kill(popen.pid, signal.SIGKILL) # Kill the process
|
||||
time.sleep(0.1)
|
||||
retcode = popen.poll()
|
||||
except OSError as e:
|
||||
except OSError, e:
|
||||
logSys.error("%s -- failed with %s" % (realCmd, e))
|
||||
finally:
|
||||
_cmd_lock.release()
|
||||
|
||||
@@ -213,7 +213,7 @@ class Actions(JailThread, Mapping):
|
||||
bool
|
||||
True when the thread exits nicely.
|
||||
"""
|
||||
for name, action in self._actions.items():
|
||||
for name, action in self._actions.iteritems():
|
||||
try:
|
||||
action.start()
|
||||
except Exception as e:
|
||||
@@ -231,7 +231,7 @@ class Actions(JailThread, Mapping):
|
||||
time.sleep(self.sleeptime)
|
||||
self.__flushBan()
|
||||
|
||||
actions = list(self._actions.items())
|
||||
actions = self._actions.items()
|
||||
actions.reverse()
|
||||
for name, action in actions:
|
||||
try:
|
||||
@@ -274,7 +274,7 @@ class Actions(JailThread, Mapping):
|
||||
jail.database.getBansMerged(ip=ip, jail=jail).getAttempt()
|
||||
if self.__banManager.addBanTicket(bTicket):
|
||||
logSys.notice("[%s] Ban %s" % (self._jail.name, aInfo["ip"]))
|
||||
for name, action in self._actions.items():
|
||||
for name, action in self._actions.iteritems():
|
||||
try:
|
||||
action.ban(aInfo.copy())
|
||||
except Exception as e:
|
||||
@@ -323,7 +323,7 @@ class Actions(JailThread, Mapping):
|
||||
aInfo["time"] = ticket.getTime()
|
||||
aInfo["matches"] = "".join(ticket.getMatches())
|
||||
logSys.notice("[%s] Unban %s" % (self._jail.name, aInfo["ip"]))
|
||||
for name, action in self._actions.items():
|
||||
for name, action in self._actions.iteritems():
|
||||
try:
|
||||
action.unban(aInfo.copy())
|
||||
except Exception as e:
|
||||
|
||||
@@ -134,7 +134,7 @@ class Fail2BanDb(object):
|
||||
|
||||
logSys.info(
|
||||
"Connected to fail2ban persistent database '%s'", filename)
|
||||
except sqlite3.OperationalError as e:
|
||||
except sqlite3.OperationalError, e:
|
||||
logSys.error(
|
||||
"Error connecting to fail2ban persistent database '%s': %s",
|
||||
filename, e.args[0])
|
||||
|
||||
@@ -168,7 +168,7 @@ class DatePatternRegex(DateTemplate):
|
||||
regex
|
||||
pattern
|
||||
"""
|
||||
_patternRE = r"%%(%%|[%s])" % "".join(list(timeRE.keys()))
|
||||
_patternRE = r"%%(%%|[%s])" % "".join(timeRE.keys())
|
||||
_patternName = {
|
||||
'a': "DAY", 'A': "DAYNAME", 'b': "MON", 'B': "MONTH", 'd': "Day",
|
||||
'H': "24hour", 'I': "12hour", 'j': "Yearday", 'm': "Month",
|
||||
@@ -232,7 +232,7 @@ class DatePatternRegex(DateTemplate):
|
||||
if dateMatch:
|
||||
groupdict = dict(
|
||||
(key, value)
|
||||
for key, value in dateMatch.groupdict().items()
|
||||
for key, value in dateMatch.groupdict().iteritems()
|
||||
if value is not None)
|
||||
return reGroupDictStrptime(groupdict), dateMatch
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ class FailManager:
|
||||
ip = ticket.getIP()
|
||||
unixTime = ticket.getTime()
|
||||
matches = ticket.getMatches()
|
||||
if ip in self.__failList:
|
||||
if self.__failList.has_key(ip):
|
||||
fData = self.__failList[ip]
|
||||
if fData.getLastReset() < unixTime - self.__maxTime:
|
||||
fData.setLastReset(unixTime)
|
||||
@@ -112,7 +112,7 @@ class FailManager:
|
||||
# in case of having many active failures, it should be ran only
|
||||
# if debug level is "low" enough
|
||||
failures_summary = ', '.join(['%s:%d' % (k, v.getRetry())
|
||||
for k,v in self.__failList.items()])
|
||||
for k,v in self.__failList.iteritems()])
|
||||
logSys.debug("Total # of detected failures: %d. Current failures from %d IPs (IP:count): %s"
|
||||
% (self.__failTotal, len(self.__failList), failures_summary))
|
||||
finally:
|
||||
@@ -136,7 +136,7 @@ class FailManager:
|
||||
self.__lock.release()
|
||||
|
||||
def __delFailure(self, ip):
|
||||
if ip in self.__failList:
|
||||
if self.__failList.has_key(ip):
|
||||
del self.__failList[ip]
|
||||
|
||||
def toBan(self):
|
||||
|
||||
+11
-11
@@ -100,7 +100,7 @@ class Filter(JailThread):
|
||||
logSys.warning(
|
||||
"Mutliline regex set for jail '%s' "
|
||||
"but maxlines not greater than 1")
|
||||
except RegexException as e:
|
||||
except RegexException, e:
|
||||
logSys.error(e)
|
||||
raise e
|
||||
|
||||
@@ -134,7 +134,7 @@ class Filter(JailThread):
|
||||
try:
|
||||
regex = Regex(value)
|
||||
self.__ignoreRegex.append(regex)
|
||||
except RegexException as e:
|
||||
except RegexException, e:
|
||||
logSys.error(e)
|
||||
raise e
|
||||
|
||||
@@ -310,7 +310,7 @@ class Filter(JailThread):
|
||||
logSys.warning('Requested to manually ban an ignored IP %s. User knows best. Proceeding to ban it.' % ip)
|
||||
|
||||
unixTime = MyTime.time()
|
||||
for i in range(self.failManager.getMaxRetry()):
|
||||
for i in xrange(self.failManager.getMaxRetry()):
|
||||
self.failManager.addFailure(FailTicket(ip, unixTime))
|
||||
|
||||
# Perform the banning of the IP now.
|
||||
@@ -361,7 +361,7 @@ class Filter(JailThread):
|
||||
elif "." in s[1]: # 255.255.255.0 style mask
|
||||
s[1] = len(re.search(
|
||||
"(?<=b)1+", bin(DNSUtils.addr2bin(s[1]))).group())
|
||||
s[1] = int(s[1])
|
||||
s[1] = long(s[1])
|
||||
try:
|
||||
a = DNSUtils.cidr(s[0], s[1])
|
||||
b = DNSUtils.cidr(ip, s[1])
|
||||
@@ -525,7 +525,7 @@ class Filter(JailThread):
|
||||
failRegex.getMatchedLines()])
|
||||
if not checkAllRegex:
|
||||
break
|
||||
except RegexException as e: # pragma: no cover - unsure if reachable
|
||||
except RegexException, e: # pragma: no cover - unsure if reachable
|
||||
logSys.error(e)
|
||||
return failList
|
||||
|
||||
@@ -656,15 +656,15 @@ class FileFilter(Filter):
|
||||
try:
|
||||
has_content = container.open()
|
||||
# see http://python.org/dev/peps/pep-3151/
|
||||
except IOError as e:
|
||||
except IOError, e:
|
||||
logSys.error("Unable to open %s" % filename)
|
||||
logSys.exception(e)
|
||||
return False
|
||||
except OSError as e: # pragma: no cover - requires race condition to tigger this
|
||||
except OSError, e: # pragma: no cover - requires race condition to tigger this
|
||||
logSys.error("Error opening %s" % filename)
|
||||
logSys.exception(e)
|
||||
return False
|
||||
except OSError as e: # pragma: no cover - Requires implemention error in FileContainer to generate
|
||||
except OSError, e: # pragma: no cover - Requires implemention error in FileContainer to generate
|
||||
logSys.error("Internal errror in FileContainer open method - please report as a bug to https://github.com/fail2ban/fail2ban/issues")
|
||||
logSys.exception(e)
|
||||
return False
|
||||
@@ -845,11 +845,11 @@ class DNSUtils:
|
||||
"""
|
||||
try:
|
||||
return set(socket.gethostbyname_ex(dns)[2])
|
||||
except socket.error as e:
|
||||
except socket.error, e:
|
||||
logSys.warning("Unable to find a corresponding IP address for %s: %s"
|
||||
% (dns, e))
|
||||
return list()
|
||||
except socket.error as e:
|
||||
except socket.error, e:
|
||||
logSys.warning("Socket error raised trying to resolve hostname %s: %s"
|
||||
% (dns, e))
|
||||
return list()
|
||||
@@ -909,7 +909,7 @@ class DNSUtils:
|
||||
integer.
|
||||
"""
|
||||
# 32-bit IPv4 address mask
|
||||
MASK = 0xFFFFFFFF
|
||||
MASK = 0xFFFFFFFFL
|
||||
return ~(MASK >> n) & MASK & DNSUtils.addr2bin(i)
|
||||
cidr = staticmethod(cidr)
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class FilterGamin(FileFilter):
|
||||
|
||||
|
||||
def callback(self, path, event):
|
||||
logSys.debug("Got event: " + repr(event) + " for " + path)
|
||||
logSys.debug("Got event: " + `event` + " for " + path)
|
||||
if event in (gamin.GAMCreated, gamin.GAMChanged, gamin.GAMExists):
|
||||
logSys.debug("File changed: " + path)
|
||||
self.__modified = True
|
||||
|
||||
@@ -136,7 +136,7 @@ class FilterPoll(FileFilter):
|
||||
logSys.debug("%s has been modified", filename)
|
||||
self.__prevStats[filename] = stats
|
||||
return True
|
||||
except OSError as e:
|
||||
except OSError, e:
|
||||
logSys.error("Unable to get stat on %s because of: %s"
|
||||
% (filename, e))
|
||||
self.__file404Cnt[filename] += 1
|
||||
|
||||
@@ -44,7 +44,7 @@ if not hasattr(pyinotify, '__version__') \
|
||||
try:
|
||||
manager = pyinotify.WatchManager()
|
||||
del manager
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
raise ImportError("Pyinotify is probably not functional on this system: %s"
|
||||
% str(e))
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
|
||||
logelements.append(logentry.get('MESSAGE', ''))
|
||||
|
||||
try:
|
||||
logline = " ".join(logelements)
|
||||
logline = u" ".join(logelements)
|
||||
except UnicodeDecodeError:
|
||||
# Python 2, so treat as string
|
||||
logline = " ".join([str(logline) for logline in logelements])
|
||||
|
||||
@@ -23,7 +23,7 @@ __author__ = "Cyril Jaquier, Lee Clemens, Yaroslav Halchenko"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
import queue, logging
|
||||
import Queue, logging
|
||||
|
||||
from .actions import Actions
|
||||
from ..helpers import getLogger
|
||||
@@ -71,7 +71,7 @@ class Jail:
|
||||
"might not function correctly. Please shorten"
|
||||
% name)
|
||||
self.__name = name
|
||||
self.__queue = queue.Queue()
|
||||
self.__queue = Queue.Queue()
|
||||
self.__filter = None
|
||||
logSys.info("Creating new jail '%s'" % self.name)
|
||||
self._setBackend(backend)
|
||||
@@ -104,7 +104,7 @@ class Jail:
|
||||
logSys.info("Initiated %r backend" % b)
|
||||
self.__actions = Actions(self)
|
||||
return # we are done
|
||||
except ImportError as e:
|
||||
except ImportError, e:
|
||||
# Log debug if auto, but error if specific
|
||||
logSys.log(
|
||||
logging.DEBUG if backend == "auto" else logging.ERROR,
|
||||
@@ -117,25 +117,25 @@ class Jail:
|
||||
|
||||
|
||||
def _initPolling(self):
|
||||
from .filterpoll import FilterPoll
|
||||
from filterpoll import FilterPoll
|
||||
logSys.info("Jail '%s' uses poller" % self.name)
|
||||
self.__filter = FilterPoll(self)
|
||||
|
||||
def _initGamin(self):
|
||||
# Try to import gamin
|
||||
from .filtergamin import FilterGamin
|
||||
from filtergamin import FilterGamin
|
||||
logSys.info("Jail '%s' uses Gamin" % self.name)
|
||||
self.__filter = FilterGamin(self)
|
||||
|
||||
def _initPyinotify(self):
|
||||
# Try to import pyinotify
|
||||
from .filterpyinotify import FilterPyinotify
|
||||
from filterpyinotify import FilterPyinotify
|
||||
logSys.info("Jail '%s' uses pyinotify" % self.name)
|
||||
self.__filter = FilterPyinotify(self)
|
||||
|
||||
def _initSystemd(self): # pragma: systemd no cover
|
||||
# Try to import systemd
|
||||
from .filtersystemd import FilterSystemd
|
||||
from filtersystemd import FilterSystemd
|
||||
logSys.info("Jail '%s' uses systemd" % self.name)
|
||||
self.__filter = FilterSystemd(self)
|
||||
|
||||
@@ -199,7 +199,7 @@ class Jail:
|
||||
"""
|
||||
try:
|
||||
return self.__queue.get(False)
|
||||
except queue.Empty:
|
||||
except Queue.Empty:
|
||||
return False
|
||||
|
||||
def start(self):
|
||||
|
||||
@@ -74,7 +74,7 @@ class Server:
|
||||
sys.excepthook = excepthook
|
||||
|
||||
# First set the mask to only allow access to owner
|
||||
os.umask(0o077)
|
||||
os.umask(0077)
|
||||
if self.__daemon: # pragma: no cover
|
||||
logSys.info("Starting in daemon mode")
|
||||
ret = self.__createDaemon()
|
||||
@@ -90,20 +90,20 @@ class Server:
|
||||
pidFile = open(pidfile, 'w')
|
||||
pidFile.write("%s\n" % os.getpid())
|
||||
pidFile.close()
|
||||
except IOError as e:
|
||||
except IOError, e:
|
||||
logSys.error("Unable to create PID file: %s" % e)
|
||||
|
||||
# Start the communication
|
||||
logSys.debug("Starting communication")
|
||||
try:
|
||||
self.__asyncServer.start(sock, force)
|
||||
except AsyncServerException as e:
|
||||
except AsyncServerException, e:
|
||||
logSys.error("Could not start server: %s", e)
|
||||
# Removes the PID file.
|
||||
try:
|
||||
logSys.debug("Remove PID file %s" % pidfile)
|
||||
os.remove(pidfile)
|
||||
except OSError as e:
|
||||
except OSError, e:
|
||||
logSys.error("Unable to remove PID file: %s" % e)
|
||||
logSys.info("Exiting Fail2ban")
|
||||
|
||||
@@ -159,7 +159,7 @@ class Server:
|
||||
logSys.info("Stopping all jails")
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
for jail in list(self.__jails.keys()):
|
||||
for jail in self.__jails.keys():
|
||||
self.stopJail(jail)
|
||||
finally:
|
||||
self.__lock.release()
|
||||
@@ -486,7 +486,7 @@ class Server:
|
||||
# the child gets a new PID, making it impossible for its PID to equal its
|
||||
# PGID.
|
||||
pid = os.fork()
|
||||
except OSError as e:
|
||||
except OSError, e:
|
||||
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
||||
|
||||
if pid == 0: # The first child.
|
||||
@@ -507,7 +507,7 @@ class Server:
|
||||
# fork guarantees that the child is no longer a session leader, thus
|
||||
# preventing the daemon from ever acquiring a controlling terminal.
|
||||
pid = os.fork() # Fork a second child.
|
||||
except OSError as e:
|
||||
except OSError, e:
|
||||
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
||||
|
||||
if (pid == 0): # The second child.
|
||||
|
||||
@@ -57,7 +57,7 @@ def reGroupDictStrptime(found_dict):
|
||||
# weekday and julian defaulted to -1 so as to signal need to calculate
|
||||
# values
|
||||
weekday = julian = -1
|
||||
for group_key in list(found_dict.keys()):
|
||||
for group_key in found_dict.keys():
|
||||
# Directives not explicitly handled below:
|
||||
# c, x, X
|
||||
# handled by making out of other directives
|
||||
|
||||
@@ -62,7 +62,7 @@ class Ticket:
|
||||
return False
|
||||
|
||||
def setIP(self, value):
|
||||
if isinstance(value, str):
|
||||
if isinstance(value, basestring):
|
||||
# guarantee using regular str instead of unicode for the IP
|
||||
value = str(value)
|
||||
self.__ip = value
|
||||
|
||||
@@ -29,7 +29,6 @@ import json
|
||||
|
||||
from ..helpers import getLogger
|
||||
from .. import version
|
||||
import collections
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger(__name__)
|
||||
@@ -52,11 +51,11 @@ class Transmitter:
|
||||
|
||||
def proceed(self, command):
|
||||
# Deserialize object
|
||||
logSys.debug("Command: " + repr(command))
|
||||
logSys.debug("Command: " + `command`)
|
||||
try:
|
||||
ret = self.__commandHandler(command)
|
||||
ack = 0, ret
|
||||
except Exception as e:
|
||||
except Exception, e:
|
||||
logSys.warning("Command %r has failed. Received %r"
|
||||
% (command, e))
|
||||
ack = 1, e
|
||||
@@ -249,7 +248,7 @@ class Transmitter:
|
||||
actionname = command[2]
|
||||
actionkey = command[3]
|
||||
action = self.__server.getAction(name, actionname)
|
||||
if isinstance(getattr(action, actionkey, None), collections.Callable):
|
||||
if callable(getattr(action, actionkey, None)):
|
||||
actionvalue = json.loads(command[4]) if len(command)>4 else {}
|
||||
return getattr(action, actionkey)(**actionvalue)
|
||||
else:
|
||||
@@ -307,7 +306,7 @@ class Transmitter:
|
||||
elif command[1] == "bantime":
|
||||
return self.__server.getBanTime(name)
|
||||
elif command[1] == "actions":
|
||||
return list(self.__server.getActions(name).keys())
|
||||
return self.__server.getActions(name).keys()
|
||||
elif command[1] == "action":
|
||||
actionname = command[2]
|
||||
actionvalue = command[3]
|
||||
@@ -319,13 +318,13 @@ class Transmitter:
|
||||
return [
|
||||
key for key in dir(action)
|
||||
if not key.startswith("_") and
|
||||
not isinstance(getattr(action, key), collections.Callable)]
|
||||
not callable(getattr(action, key))]
|
||||
elif command[1] == "actionmethods":
|
||||
actionname = command[2]
|
||||
action = self.__server.getAction(name, actionname)
|
||||
return [
|
||||
key for key in dir(action)
|
||||
if not key.startswith("_") and isinstance(getattr(action, key), collections.Callable)]
|
||||
if not key.startswith("_") and callable(getattr(action, key))]
|
||||
raise Exception("Invalid command (no get action or not yet implemented)")
|
||||
|
||||
def status(self, command):
|
||||
|
||||
@@ -22,11 +22,7 @@ import unittest
|
||||
import sys
|
||||
|
||||
from ..dummyjail import DummyJail
|
||||
|
||||
if os.path.exists('config/fail2ban.conf'):
|
||||
CONFIG_DIR = "config"
|
||||
else:
|
||||
CONFIG_DIR='/etc/fail2ban'
|
||||
from ..utils import CONFIG_DIR
|
||||
|
||||
if sys.version_info >= (2,7):
|
||||
class BadIPsActionTest(unittest.TestCase):
|
||||
|
||||
@@ -30,10 +30,7 @@ else:
|
||||
|
||||
from ..dummyjail import DummyJail
|
||||
|
||||
if os.path.exists('config/fail2ban.conf'):
|
||||
CONFIG_DIR = "config"
|
||||
else:
|
||||
CONFIG_DIR='/etc/fail2ban'
|
||||
from ..utils import CONFIG_DIR
|
||||
|
||||
class TestSMTPServer(smtpd.SMTPServer):
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
import os, glob, shutil, tempfile, unittest
|
||||
import os, glob, shutil, tempfile, unittest, re
|
||||
|
||||
from ..client.configreader import ConfigReader
|
||||
from ..client.jailreader import JailReader
|
||||
@@ -32,8 +32,10 @@ from ..client.configurator import Configurator
|
||||
from .utils import LogCaptureTestCase
|
||||
|
||||
TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files")
|
||||
|
||||
from .utils import CONFIG_DIR
|
||||
|
||||
STOCK = os.path.exists(os.path.join('config','fail2ban.conf'))
|
||||
CONFIG_DIR='config' if STOCK else '/etc/fail2ban'
|
||||
|
||||
IMPERFECT_CONFIG = os.path.join(os.path.dirname(__file__), 'config')
|
||||
|
||||
@@ -333,6 +335,36 @@ class FilterReaderTest(unittest.TestCase):
|
||||
self.assertRaises(ValueError, FilterReader.convert, filterReader)
|
||||
|
||||
|
||||
class JailsReaderTestCache(LogCaptureTestCase):
|
||||
|
||||
def testTestJailConfCache(self):
|
||||
basedir = tempfile.mkdtemp("fail2ban_conf")
|
||||
try:
|
||||
shutil.rmtree(basedir)
|
||||
shutil.copytree(CONFIG_DIR, basedir)
|
||||
shutil.copy(CONFIG_DIR + '/jail.conf', basedir + '/jail.local')
|
||||
shutil.copy(CONFIG_DIR + '/fail2ban.conf', basedir + '/fail2ban.local')
|
||||
|
||||
# read whole configuration like a file2ban-client ...
|
||||
configurator = Configurator()
|
||||
configurator.setBaseDir(basedir)
|
||||
configurator.readEarly()
|
||||
configurator.getEarlyOptions()
|
||||
configurator.readAll()
|
||||
# from here we test a cache :
|
||||
self.assertTrue(configurator.getOptions(None))
|
||||
cnt = 0
|
||||
for s in self.getLog().rsplit('\n'):
|
||||
if re.match(r"^Reading files: .*jail.local", s):
|
||||
cnt += 1
|
||||
# if cnt > 2:
|
||||
# self.printLog()
|
||||
self.assertFalse(cnt > 2, "Too many times reading of config files, cnt = %s" % cnt)
|
||||
self.assertFalse(cnt <= 0)
|
||||
finally:
|
||||
shutil.rmtree(basedir)
|
||||
|
||||
|
||||
class JailsReaderTest(LogCaptureTestCase):
|
||||
|
||||
def testProvidingBadBasedir(self):
|
||||
|
||||
@@ -92,7 +92,7 @@ class DatabaseTest(unittest.TestCase):
|
||||
self.db = Fail2BanDb(self.dbFilename)
|
||||
self.assertEqual(self.db.getJailNames(), set(['DummyJail #29162448 with 0 tickets']))
|
||||
self.assertEqual(self.db.getLogPaths(), set(['/tmp/Fail2BanDb_pUlZJh.log']))
|
||||
ticket = FailTicket("127.0.0.1", 1388009242.26, ["abc\n"])
|
||||
ticket = FailTicket("127.0.0.1", 1388009242.26, [u"abc\n"])
|
||||
self.assertEqual(self.db.getBans()[0], ticket)
|
||||
|
||||
self.assertEqual(self.db.updateDb(Fail2BanDb.__version__), Fail2BanDb.__version__)
|
||||
|
||||
@@ -139,7 +139,7 @@ class DateDetectorTest(unittest.TestCase):
|
||||
self.assertEqual(logMatch.group(), '2012/10/11 02:37:17')
|
||||
self.__datedetector.sortTemplate()
|
||||
# confuse it with year being at the end
|
||||
for i in range(10):
|
||||
for i in xrange(10):
|
||||
( logTime, logMatch ) = self.__datedetector.getTime('11/10/2012 02:37:17 [error] 18434#0')
|
||||
self.assertEqual(logTime, mu)
|
||||
self.assertEqual(logMatch.group(), '11/10/2012 02:37:17')
|
||||
|
||||
@@ -33,11 +33,11 @@ class AddFailure(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Call before every test case."""
|
||||
self.__items = [['193.168.0.128', 1167605999.0],
|
||||
['193.168.0.128', 1167605999.0],
|
||||
['193.168.0.128', 1167605999.0],
|
||||
['193.168.0.128', 1167605999.0],
|
||||
['193.168.0.128', 1167605999.0],
|
||||
self.__items = [[u'193.168.0.128', 1167605999.0],
|
||||
[u'193.168.0.128', 1167605999.0],
|
||||
[u'193.168.0.128', 1167605999.0],
|
||||
[u'193.168.0.128', 1167605999.0],
|
||||
[u'193.168.0.128', 1167605999.0],
|
||||
['87.142.124.10', 1167605999.0],
|
||||
['87.142.124.10', 1167605999.0],
|
||||
['87.142.124.10', 1167605999.0],
|
||||
|
||||
@@ -33,13 +33,13 @@ def auth(v):
|
||||
response="%s"
|
||||
""" % ( username, algorithm, realm, url, nonce, qop, response )
|
||||
# opaque="%s",
|
||||
print(p.method, p.url, p.headers)
|
||||
print p.method, p.url, p.headers
|
||||
s = requests.Session()
|
||||
return s.send(p)
|
||||
|
||||
def preauth():
|
||||
r = requests.get(host + url)
|
||||
print(r)
|
||||
print r
|
||||
r.headers['www-authenticate'].split(', ')
|
||||
return dict([ a.split('=',1) for a in r.headers['www-authenticate'].split(', ') ])
|
||||
|
||||
@@ -51,7 +51,7 @@ v = preauth()
|
||||
|
||||
username="username"
|
||||
password = "password"
|
||||
print(v)
|
||||
print v
|
||||
|
||||
realm = 'so far away'
|
||||
r = auth(v)
|
||||
@@ -67,18 +67,18 @@ r = auth(v)
|
||||
|
||||
# [Sun Jul 28 21:41:20 2013] [error] [client 127.0.0.1] Digest: unknown algorithm `super funky chicken' received: /digest/
|
||||
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
v['algorithm'] = algorithm
|
||||
|
||||
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
nonce = v['nonce']
|
||||
v['nonce']=v['nonce'][5:-5]
|
||||
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
# [Sun Jul 28 21:05:31.178340 2013] [auth_digest:error] [pid 24224:tid 139895539455744] [client 127.0.0.1:56906] AH01793: invalid qop `auth' received: /digest/qop_none/
|
||||
|
||||
@@ -86,7 +86,7 @@ print(r.status_code,r.headers, r.text)
|
||||
v['nonce']=nonce[0:11] + 'ZZZ' + nonce[14:]
|
||||
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
#[Sun Jul 28 21:18:11.769228 2013] [auth_digest:error] [pid 24752:tid 139895505884928] [client 127.0.0.1:56964] AH01776: invalid nonce b9YAiJDiBAZZZ1b1abe02d20063ea3b16b544ea1b0d981c1bafe received - hash is not d42d824dee7aaf50c3ba0a7c6290bd453e3dd35b
|
||||
|
||||
@@ -98,7 +98,7 @@ import time
|
||||
time.sleep(1)
|
||||
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
# Obtained by putting the following code in modules/aaa/mod_auth_digest.c
|
||||
# in the function initialize_secret
|
||||
@@ -128,7 +128,7 @@ s = sha.sha(apachesecret)
|
||||
|
||||
v=preauth()
|
||||
|
||||
print(v['nonce'])
|
||||
print v['nonce']
|
||||
realm = v['Digest realm'][1:-1]
|
||||
|
||||
(t,) = struct.unpack('l',base64.b64decode(v['nonce'][1:13]))
|
||||
@@ -143,17 +143,17 @@ s.update(timepac)
|
||||
|
||||
v['nonce'] = v['nonce'][0] + timepac + s.hexdigest() + v['nonce'][-1]
|
||||
|
||||
print(v)
|
||||
print v
|
||||
|
||||
r = auth(v)
|
||||
#[Mon Jul 29 02:12:55.539813 2013] [auth_digest:error] [pid 9647:tid 139895522670336] [client 127.0.0.1:58474] AH01777: invalid nonce 59QJppTiBAA=b08983fd166ade9840407df1b0f75b9e6e07d88d received - user attempted time travel
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
url='/digest_onetime/'
|
||||
v=preauth()
|
||||
|
||||
# Need opaque header handling in auth
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
r = auth(v)
|
||||
print(r.status_code,r.headers, r.text)
|
||||
print r.status_code,r.headers, r.text
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
# failJSON: { "time": "2013-07-20T21:34:49", "match": true , "host": "127.0.0.1" }
|
||||
[Sat Jul 20 21:34:49.453232 2013] [access_compat:error] [pid 17512:tid 140123104306944] [client 127.0.0.1:51380] AH01797: client denied by server configuration: /var/www/html/noentry/cant_get_me.html
|
||||
|
||||
# failJSON: { "time": "2014-09-14T21:44:43", "match": true , "host": "192.3.9.178" }
|
||||
[Sun Sep 14 21:44:43.008606 2014] [authz_core:error] [pid 10691] [client 192.3.9.178:44271] AH01630: client denied by server configuration: /var/www/html/noentry/cant_get_me.html
|
||||
|
||||
# wget --http-user='' --http-password='' http://localhost/basic/file/cant_get_me.html -O /dev/null
|
||||
# failJSON: { "time": "2013-07-17T23:14:37", "match": true , "host": "127.0.0.1" }
|
||||
[Wed Jul 17 23:14:37 2013] [error] [client 127.0.0.1] user not found: /basic/anon/cant_get_me.html
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# failJSON: { "time": "2014-09-25T09:27:18", "match": true , "host": "89.207.132.76" }
|
||||
[Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt
|
||||
# failJSON: { "time": "2014-09-25T09:29:56", "match": true , "host": "162.247.73.206" }
|
||||
[Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST'
|
||||
@@ -5,3 +5,6 @@ Dec 2 22:24:22 hel postfix/smtpd[7676]: warning: 114-44-142-233.dynamic.hinet.n
|
||||
# failJSON: { "time": "2005-03-10T13:33:30", "match": true , "host": "1.1.1.1" }
|
||||
Mar 10 13:33:30 gandalf postfix/smtpd[3937]: warning: HOSTNAME[1.1.1.1]: SASL LOGIN authentication failed: authentication failure
|
||||
|
||||
#3 Example from postfix post-debian changes to rename to add "submission" to syslog name
|
||||
# failJSON: { "time": "2004-09-06T00:44:56", "match": true , "host": "82.221.106.233" }
|
||||
Sep 6 00:44:56 trianon postfix/submission/smtpd[11538]: warning: unknown[82.221.106.233]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
from builtins import open as fopen
|
||||
from __builtin__ import open as fopen
|
||||
import unittest
|
||||
import getpass
|
||||
import os
|
||||
@@ -133,7 +133,7 @@ def _copy_lines_between_files(in_, fout, n=None, skip=0, mode='a', terminal_line
|
||||
else:
|
||||
fin = in_
|
||||
# Skip
|
||||
for i in range(skip):
|
||||
for i in xrange(skip):
|
||||
fin.readline()
|
||||
# Read
|
||||
i = 0
|
||||
@@ -170,7 +170,7 @@ def _copy_lines_to_journal(in_, fields={},n=None, skip=0, terminal_line=""): # p
|
||||
"PRIORITY": "7",
|
||||
})
|
||||
# Skip
|
||||
for i in range(skip):
|
||||
for i in xrange(skip):
|
||||
fin.readline()
|
||||
# Read/Write
|
||||
i = 0
|
||||
@@ -806,7 +806,7 @@ class GetFailures(unittest.TestCase):
|
||||
|
||||
# so that they could be reused by other tests
|
||||
FAILURES_01 = ('193.168.0.128', 3, 1124013599.0,
|
||||
['Aug 14 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 193.168.0.128']*3)
|
||||
[u'Aug 14 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 193.168.0.128']*3)
|
||||
|
||||
def setUp(self):
|
||||
"""Call before every test case."""
|
||||
@@ -856,8 +856,8 @@ class GetFailures(unittest.TestCase):
|
||||
|
||||
def testGetFailures02(self):
|
||||
output = ('141.3.81.106', 4, 1124013539.0,
|
||||
['Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
|
||||
% m for m in (53, 54, 57, 58)])
|
||||
[u'Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
|
||||
% m for m in 53, 54, 57, 58])
|
||||
|
||||
self.filter.addLogPath(GetFailures.FILENAME_02)
|
||||
self.filter.addFailRegex("Failed .* from <HOST>")
|
||||
@@ -889,11 +889,11 @@ class GetFailures(unittest.TestCase):
|
||||
def testGetFailuresUseDNS(self):
|
||||
# We should still catch failures with usedns = no ;-)
|
||||
output_yes = ('93.184.216.119', 2, 1124013539.0,
|
||||
['Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2',
|
||||
'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.119 port 51332 ssh2'])
|
||||
[u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2',
|
||||
u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.119 port 51332 ssh2'])
|
||||
|
||||
output_no = ('93.184.216.119', 1, 1124013539.0,
|
||||
['Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.119 port 51332 ssh2'])
|
||||
[u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.119 port 51332 ssh2'])
|
||||
|
||||
# Actually no exception would be raised -- it will be just set to 'no'
|
||||
#self.assertRaises(ValueError,
|
||||
|
||||
@@ -30,7 +30,7 @@ import shutil
|
||||
import fnmatch
|
||||
import datetime
|
||||
from glob import glob
|
||||
from io import StringIO
|
||||
from StringIO import StringIO
|
||||
|
||||
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger
|
||||
from ..server.datetemplate import DatePatternRegex
|
||||
@@ -138,7 +138,7 @@ class TestsUtilsTest(unittest.TestCase):
|
||||
else: func_raise()
|
||||
|
||||
try:
|
||||
print(deep_function(3))
|
||||
print deep_function(3)
|
||||
except ValueError:
|
||||
s = tb()
|
||||
|
||||
|
||||
@@ -28,17 +28,13 @@ if sys.version_info >= (2, 6):
|
||||
import json
|
||||
else:
|
||||
import simplejson as json
|
||||
next = lambda x: x.__next__()
|
||||
next = lambda x: x.next()
|
||||
|
||||
from ..server.filter import Filter
|
||||
from ..client.filterreader import FilterReader
|
||||
from .utils import setUpMyTime, tearDownMyTime
|
||||
from .utils import setUpMyTime, tearDownMyTime, CONFIG_DIR
|
||||
|
||||
TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files")
|
||||
if os.path.exists('config/fail2ban.conf'):
|
||||
CONFIG_DIR = "config"
|
||||
else:
|
||||
CONFIG_DIR='/etc/fail2ban'
|
||||
|
||||
class FilterSamplesRegex(unittest.TestCase):
|
||||
|
||||
@@ -94,7 +90,7 @@ def testSampleRegexsFactory(name):
|
||||
if jsonREMatch:
|
||||
try:
|
||||
faildata = json.loads(jsonREMatch.group(1))
|
||||
except ValueError as e:
|
||||
except ValueError, e:
|
||||
raise ValueError("%s: %s:%i" %
|
||||
(e, logFile.filename(), logFile.filelineno()))
|
||||
line = next(logFile)
|
||||
@@ -116,7 +112,7 @@ def testSampleRegexsFactory(name):
|
||||
"Line matched when shouldn't have: %s:%i %r" %
|
||||
(logFile.filename(), logFile.filelineno(), line))
|
||||
self.assertEqual(len(ret), 1, "Multiple regexs matched %r - %s:%i" %
|
||||
([x[0] for x in ret],logFile.filename(), logFile.filelineno()))
|
||||
(map(lambda x: x[0], ret),logFile.filename(), logFile.filelineno()))
|
||||
|
||||
# Verify timestamp and host as expected
|
||||
failregex, host, fail2banTime, lines = ret[0]
|
||||
@@ -149,7 +145,7 @@ def testSampleRegexsFactory(name):
|
||||
|
||||
return testFilter
|
||||
|
||||
for filter_ in [x for x in os.listdir(os.path.join(CONFIG_DIR, "filter.d")) if not x.endswith('common.conf')]:
|
||||
for filter_ in filter(lambda x: not x.endswith('common.conf'), os.listdir(os.path.join(CONFIG_DIR, "filter.d"))):
|
||||
filterName = filter_.rpartition(".")[0]
|
||||
if not filterName.startswith('.'):
|
||||
setattr(
|
||||
|
||||
@@ -685,7 +685,7 @@ class TransmitterLogging(TransmitterBase):
|
||||
|
||||
def testLogTarget(self):
|
||||
logTargets = []
|
||||
for _ in range(3):
|
||||
for _ in xrange(3):
|
||||
tmpFile = tempfile.mkstemp("fail2ban", "transmitter")
|
||||
logTargets.append(tmpFile[1])
|
||||
os.close(tmpFile[0])
|
||||
@@ -738,26 +738,26 @@ class TransmitterLogging(TransmitterBase):
|
||||
self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "rolled over"))
|
||||
l.warning("After flushlogs")
|
||||
with open(fn2,'r') as f:
|
||||
line1 = next(f)
|
||||
line1 = f.next()
|
||||
if line1.find('Changed logging target to') >= 0:
|
||||
line1 = next(f)
|
||||
line1 = f.next()
|
||||
self.assertTrue(line1.endswith("Before file moved\n"))
|
||||
line2 = next(f)
|
||||
line2 = f.next()
|
||||
self.assertTrue(line2.endswith("After file moved\n"))
|
||||
try:
|
||||
n = next(f)
|
||||
n = f.next()
|
||||
if n.find("Command: ['flushlogs']") >=0:
|
||||
self.assertRaises(StopIteration, f.__next__)
|
||||
self.assertRaises(StopIteration, f.next)
|
||||
else:
|
||||
self.fail("Exception StopIteration or Command: ['flushlogs'] expected. Got: %s" % n)
|
||||
except StopIteration:
|
||||
pass # on higher debugging levels this is expected
|
||||
with open(fn,'r') as f:
|
||||
line1 = next(f)
|
||||
line1 = f.next()
|
||||
if line1.find('rollover performed on') >= 0:
|
||||
line1 = next(f)
|
||||
line1 = f.next()
|
||||
self.assertTrue(line1.endswith("After flushlogs\n"))
|
||||
self.assertRaises(StopIteration, f.__next__)
|
||||
self.assertRaises(StopIteration, f.next)
|
||||
f.close()
|
||||
finally:
|
||||
os.remove(fn2)
|
||||
|
||||
+21
-5
@@ -25,15 +25,25 @@ __license__ = "GPL"
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
from io import StringIO
|
||||
from StringIO import StringIO
|
||||
|
||||
from ..server.mytime import MyTime
|
||||
from ..helpers import getLogger
|
||||
|
||||
logSys = getLogger(__name__)
|
||||
|
||||
CONFIG_DIR = os.environ.get('FAIL2BAN_CONFIG_DIR', None)
|
||||
|
||||
if not CONFIG_DIR:
|
||||
# Use heuristic to figure out where configuration files are
|
||||
if os.path.exists(os.path.join('config','fail2ban.conf')):
|
||||
CONFIG_DIR = 'config'
|
||||
else:
|
||||
CONFIG_DIR = '/etc/fail2ban'
|
||||
|
||||
def mtimesleep():
|
||||
# no sleep now should be necessary since polling tracks now not only
|
||||
# mtime but also ino and size
|
||||
@@ -102,6 +112,7 @@ def gatherTests(regexps=None, no_network=False):
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.FilterReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailsReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailsReaderTestCache))
|
||||
# CSocket and AsyncServer
|
||||
tests.addTest(unittest.makeSuite(sockettestcase.Socket))
|
||||
# Misc helpers
|
||||
@@ -156,13 +167,13 @@ def gatherTests(regexps=None, no_network=False):
|
||||
try:
|
||||
from ..server.filtergamin import FilterGamin
|
||||
filters.append(FilterGamin)
|
||||
except Exception as e: # pragma: no cover
|
||||
except Exception, e: # pragma: no cover
|
||||
logSys.warning("Skipping gamin backend testing. Got exception '%s'" % e)
|
||||
|
||||
try:
|
||||
from ..server.filterpyinotify import FilterPyinotify
|
||||
filters.append(FilterPyinotify)
|
||||
except Exception as e: # pragma: no cover
|
||||
except Exception, e: # pragma: no cover
|
||||
logSys.warning("I: Skipping pyinotify backend testing. Got exception '%s'" % e)
|
||||
|
||||
for Filter_ in filters:
|
||||
@@ -171,7 +182,7 @@ def gatherTests(regexps=None, no_network=False):
|
||||
try: # pragma: systemd no cover
|
||||
from ..server.filtersystemd import FilterSystemd
|
||||
tests.addTest(unittest.makeSuite(filtertestcase.get_monitor_failures_journal_testcase(FilterSystemd)))
|
||||
except Exception as e: # pragma: no cover
|
||||
except Exception, e: # pragma: no cover
|
||||
logSys.warning("I: Skipping systemd backend testing. Got exception '%s'" % e)
|
||||
|
||||
|
||||
@@ -195,6 +206,8 @@ class LogCaptureTestCase(unittest.TestCase):
|
||||
# Let's log everything into a string
|
||||
self._log = StringIO()
|
||||
logSys.handlers = [logging.StreamHandler(self._log)]
|
||||
if self._old_level < logging.DEBUG: # so if HEAVYDEBUG etc -- show them!
|
||||
logSys.handlers += self._old_handlers
|
||||
logSys.setLevel(getattr(logging, 'DEBUG'))
|
||||
|
||||
def tearDown(self):
|
||||
@@ -207,5 +220,8 @@ class LogCaptureTestCase(unittest.TestCase):
|
||||
def _is_logged(self, s):
|
||||
return s in self._log.getvalue()
|
||||
|
||||
def getLog(self):
|
||||
return self._log.getvalue()
|
||||
|
||||
def printLog(self):
|
||||
print((self._log.getvalue()))
|
||||
print(self._log.getvalue())
|
||||
|
||||
@@ -378,7 +378,7 @@ the action <ACT> for <JAIL>
|
||||
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs via Debian bug tracking system \fIhttp://www.debian.org/Bugs/\fR .
|
||||
Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors
|
||||
.br
|
||||
|
||||
@@ -38,7 +38,7 @@ print the version
|
||||
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs via Debian bug tracking system \fIhttp://www.debian.org/Bugs/\fR .
|
||||
Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors
|
||||
.br
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install curl python-systemd dh-systemd python-pip python-inotifyx git build-essential autotools-dev libssl-dev devscripts debhelper git libpcre3-dev libssl-dev
|
||||
Reference in New Issue
Block a user