fail2ban/client/jailreader.py

228 lines
7.1 KiB
Python
Raw Normal View History

# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Author: Cyril Jaquier
#
__author__ = "Cyril Jaquier"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import logging, re, glob, os.path
from configreader import ConfigReader
from filterreader import FilterReader
from actionreader import ActionReader
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.client.config")
class JailReader(ConfigReader):
actionCRE = re.compile("^([\w_.-]+)(?:\[(.*)\])?$")
def __init__(self, name, force_enable=False, **kwargs):
ConfigReader.__init__(self, **kwargs)
self.__name = name
self.__filter = None
self.__force_enable = force_enable
self.__actions = list()
def setName(self, value):
self.__name = value
def getName(self):
return self.__name
def read(self):
return ConfigReader.read(self, "jail")
def isEnabled(self):
return self.__force_enable or ( self.__opts and self.__opts["enabled"] )
@staticmethod
def _glob(path):
"""Given a path for glob return list of files to be passed to server.
Dangling symlinks are warned about and not returned
"""
pathList = []
for p in glob.glob(path):
if os.path.exists(p):
pathList.append(p)
else:
logSys.warning("File %s is a dangling link, thus cannot be monitored" % p)
return pathList
def getOptions(self):
opts = [["bool", "enabled", "false"],
["string", "logpath", "/var/log/messages"],
["string", "backend", "auto"],
["int", "maxretry", 3],
["int", "findtime", 600],
["int", "bantime", 600],
ENH: Add usedns parameter for the jails following commits were squashed from feature branch use_dns commit 068c105eb58b85aaf5ad9df02e7f4122a4efea81 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 22:19:04 2012 -0500 Prevent warning when IP is read from log commit 635ed36a8c7280658d501318d882f6e9dd426343 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 22:17:08 2012 -0500 Removed logDebug commit 24656d2812c18e0f9312ce36d42ef51ecb68b354 Merge: 7957fbe c429f5c Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 21:13:11 2012 -0500 Merge branch 'enh/use_dns' of github:leeclemens/fail2ban into enh/use_dns Conflicts: testcases/filtertestcase.py commit 7957fbe821b0cebf162f64b4627a345db551c2d0 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 21:09:58 2012 -0500 filtertestcase fixes from yarikoptic commit 6ce9d04640789c1eb587454d2ec95d61f7b67ce8 Author: Yaroslav Halchenko <debian@onerussian.com> Date: Tue Jan 10 19:26:05 2012 -0500 RF: for consistency use_dns -> usedns I guess it was might fault of inconsistency suggesting that name. Other options/commands do not have _ in the names, so let it be consistent with the rest for now commit cfb2c75b49942b127fff6da4e4e349c667606b5d Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:18:41 2012 -0500 Updated DNSUtilsTests to test use_dns and added positive test to testTextToIp commit f6186eff14ff1ff9da42f30c7f6268fd792104e6 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:02:04 2012 -0500 Changed wording of 'DNS Reverse lookup used' message commit 82c62d29dc49582594ff86fb24dc710654ea6269 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 18:53:17 2012 -0500 Removed extraneous "n" commit dc0ae2193227cbf8e837bdd173403edbd68afd9a Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 23:07:59 2012 -0500 ENH: use_dns - removed debugging statements commit 594e25818cd6b5dd366194d7e74af99294c5a394 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:53:39 2012 -0500 Added use_dns protocol to set and get per jail during runtime commit 48ff80ffac25d8c3d538e5c05678514f6c9628f6 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:41:18 2012 -0500 Completed use_dns for initial startup - with debugging statements commit 0bdab4c2d7f0d0c29d4999e70db5f748b51fe1b5 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:05:35 2012 -0500 ENH: Added use_dns option commit 6d6b734ea51a2f2792ed34d9a4227bb7a3361adb Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:01:34 2012 -0500 ENH: Added use_dns option commit 11ad2b61254ee03fa761e0c3a7e4905dd89bc54a Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 19:17:30 2012 -0500 Added useDns flag to testcase commit b48fa9b6af242fc04c1d1fe1ddf8f7bc1c8fdeed Author: Lee Clemens <java@leeclemens.net> Date: Sun Jan 8 15:13:27 2012 -0500 Added use_dns option in jail.conf commit c429f5c91ae935b359e28376b2120eb3d6ea0ad7 Merge: 4b18afb 0021906 Author: leeclemens <java@leeclemens.net> Date: Tue Jan 10 16:32:22 2012 -0800 Merge pull request #3 from yarikoptic/enh/use_dns let's be consistent ;-) commit 0021906358e50c9f53d2fa98ba853a16f6388078 Author: Yaroslav Halchenko <debian@onerussian.com> Date: Tue Jan 10 19:26:05 2012 -0500 RF: for consistency use_dns -> usedns I guess it was might fault of inconsistency suggesting that name. Other options/commands do not have _ in the names, so let it be consistent with the rest for now commit 4b18afb28a5be525913ad552459bfb3287ccfda5 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:18:41 2012 -0500 Updated DNSUtilsTests to test use_dns and added positive test to testTextToIp commit 4fae37e46fef62058738040325a3c9cd2be11d45 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:02:04 2012 -0500 Changed wording of 'DNS Reverse lookup used' message commit e94806ce4804ff3bdc124a0f5265602987245525 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 18:53:17 2012 -0500 Removed extraneous "n" commit 4d30c5290725b7d92b0a8f49c1eb5a6a2d12b32e Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 23:07:59 2012 -0500 ENH: use_dns - removed debugging statements commit 76696d452ae59e0fa161e1f85e31c6411352f966 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:53:39 2012 -0500 Added use_dns protocol to set and get per jail during runtime commit 06316180870a0349630e27f7ef078624c6f006cd Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:41:18 2012 -0500 Completed use_dns for initial startup - with debugging statements commit d23d495547fe382ea6669c30eeac5033284b4c5f Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:05:35 2012 -0500 ENH: Added use_dns option commit 9538553bc5a71faf23b5b810b83d7acb133c8d56 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:01:34 2012 -0500 ENH: Added use_dns option commit ae1e857e53e0c014da5b717976536be172a37dc1 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 19:17:30 2012 -0500 Added useDns flag to testcase commit ace43eb94128f32538182472fd35e97c220bbf34 Author: Lee Clemens <java@leeclemens.net> Date: Sun Jan 8 15:13:27 2012 -0500 Added use_dns option in jail.conf
2012-01-13 04:23:41 +00:00
["string", "usedns", "warn"],
["string", "failregex", None],
["string", "ignoreregex", None],
["string", "ignoreip", None],
["string", "filter", ""],
["string", "action", ""]]
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
if not self.__opts:
return False
if self.isEnabled():
# Read filter
if self.__opts["filter"]:
self.__filter = FilterReader(self.__opts["filter"], self.__name,
basedir=self.getBaseDir())
ret = self.__filter.read()
if ret:
self.__filter.getOptions(self.__opts)
else:
logSys.error("Unable to read the filter")
return False
else:
2013-12-13 11:36:00 +00:00
self.__filter = None
logSys.warn("No filter set for jail %s" % self.__name)
# Read action
for act in self.__opts["action"].split('\n'):
try:
if not act: # skip empty actions
continue
splitAct = JailReader.splitAction(act)
action = ActionReader(splitAct, self.__name, basedir=self.getBaseDir())
ret = action.read()
if ret:
action.getOptions(self.__opts)
self.__actions.append(action)
else:
raise AttributeError("Unable to read action")
except Exception, e:
logSys.error("Error in action definition " + act)
logSys.debug("Caught exception: %s" % (e,))
return False
if not len(self.__actions):
logSys.warn("No actions were defined for %s" % self.__name)
return True
def convert(self, allow_no_files=False):
"""Convert read before __opts to the commands stream
Parameters
----------
allow_missing : bool
Either to allow log files to be missing entirely. Primarily is
used for testing
"""
stream = []
for opt in self.__opts:
if opt == "logpath":
found_files = 0
for path in self.__opts[opt].split("\n"):
pathList = JailReader._glob(path)
if len(pathList) == 0:
logSys.error("No file(s) found for glob %s" % path)
for p in pathList:
found_files += 1
stream.append(["set", self.__name, "addlogpath", p])
if not (found_files or allow_no_files):
raise ValueError(
"Have not found any log file for %s jail" % self.__name)
elif opt == "backend":
backend = self.__opts[opt]
elif opt == "maxretry":
stream.append(["set", self.__name, "maxretry", self.__opts[opt]])
elif opt == "ignoreip":
for ip in self.__opts[opt].split():
# Do not send a command if the rule is empty.
if ip != '':
stream.append(["set", self.__name, "addignoreip", ip])
elif opt == "findtime":
stream.append(["set", self.__name, "findtime", self.__opts[opt]])
elif opt == "bantime":
stream.append(["set", self.__name, "bantime", self.__opts[opt]])
ENH: Add usedns parameter for the jails following commits were squashed from feature branch use_dns commit 068c105eb58b85aaf5ad9df02e7f4122a4efea81 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 22:19:04 2012 -0500 Prevent warning when IP is read from log commit 635ed36a8c7280658d501318d882f6e9dd426343 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 22:17:08 2012 -0500 Removed logDebug commit 24656d2812c18e0f9312ce36d42ef51ecb68b354 Merge: 7957fbe c429f5c Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 21:13:11 2012 -0500 Merge branch 'enh/use_dns' of github:leeclemens/fail2ban into enh/use_dns Conflicts: testcases/filtertestcase.py commit 7957fbe821b0cebf162f64b4627a345db551c2d0 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 21:09:58 2012 -0500 filtertestcase fixes from yarikoptic commit 6ce9d04640789c1eb587454d2ec95d61f7b67ce8 Author: Yaroslav Halchenko <debian@onerussian.com> Date: Tue Jan 10 19:26:05 2012 -0500 RF: for consistency use_dns -> usedns I guess it was might fault of inconsistency suggesting that name. Other options/commands do not have _ in the names, so let it be consistent with the rest for now commit cfb2c75b49942b127fff6da4e4e349c667606b5d Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:18:41 2012 -0500 Updated DNSUtilsTests to test use_dns and added positive test to testTextToIp commit f6186eff14ff1ff9da42f30c7f6268fd792104e6 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:02:04 2012 -0500 Changed wording of 'DNS Reverse lookup used' message commit 82c62d29dc49582594ff86fb24dc710654ea6269 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 18:53:17 2012 -0500 Removed extraneous "n" commit dc0ae2193227cbf8e837bdd173403edbd68afd9a Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 23:07:59 2012 -0500 ENH: use_dns - removed debugging statements commit 594e25818cd6b5dd366194d7e74af99294c5a394 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:53:39 2012 -0500 Added use_dns protocol to set and get per jail during runtime commit 48ff80ffac25d8c3d538e5c05678514f6c9628f6 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:41:18 2012 -0500 Completed use_dns for initial startup - with debugging statements commit 0bdab4c2d7f0d0c29d4999e70db5f748b51fe1b5 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:05:35 2012 -0500 ENH: Added use_dns option commit 6d6b734ea51a2f2792ed34d9a4227bb7a3361adb Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:01:34 2012 -0500 ENH: Added use_dns option commit 11ad2b61254ee03fa761e0c3a7e4905dd89bc54a Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 19:17:30 2012 -0500 Added useDns flag to testcase commit b48fa9b6af242fc04c1d1fe1ddf8f7bc1c8fdeed Author: Lee Clemens <java@leeclemens.net> Date: Sun Jan 8 15:13:27 2012 -0500 Added use_dns option in jail.conf commit c429f5c91ae935b359e28376b2120eb3d6ea0ad7 Merge: 4b18afb 0021906 Author: leeclemens <java@leeclemens.net> Date: Tue Jan 10 16:32:22 2012 -0800 Merge pull request #3 from yarikoptic/enh/use_dns let's be consistent ;-) commit 0021906358e50c9f53d2fa98ba853a16f6388078 Author: Yaroslav Halchenko <debian@onerussian.com> Date: Tue Jan 10 19:26:05 2012 -0500 RF: for consistency use_dns -> usedns I guess it was might fault of inconsistency suggesting that name. Other options/commands do not have _ in the names, so let it be consistent with the rest for now commit 4b18afb28a5be525913ad552459bfb3287ccfda5 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:18:41 2012 -0500 Updated DNSUtilsTests to test use_dns and added positive test to testTextToIp commit 4fae37e46fef62058738040325a3c9cd2be11d45 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 19:02:04 2012 -0500 Changed wording of 'DNS Reverse lookup used' message commit e94806ce4804ff3bdc124a0f5265602987245525 Author: Lee Clemens <java@leeclemens.net> Date: Tue Jan 10 18:53:17 2012 -0500 Removed extraneous "n" commit 4d30c5290725b7d92b0a8f49c1eb5a6a2d12b32e Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 23:07:59 2012 -0500 ENH: use_dns - removed debugging statements commit 76696d452ae59e0fa161e1f85e31c6411352f966 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:53:39 2012 -0500 Added use_dns protocol to set and get per jail during runtime commit 06316180870a0349630e27f7ef078624c6f006cd Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 22:41:18 2012 -0500 Completed use_dns for initial startup - with debugging statements commit d23d495547fe382ea6669c30eeac5033284b4c5f Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:05:35 2012 -0500 ENH: Added use_dns option commit 9538553bc5a71faf23b5b810b83d7acb133c8d56 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 20:01:34 2012 -0500 ENH: Added use_dns option commit ae1e857e53e0c014da5b717976536be172a37dc1 Author: Lee Clemens <java@leeclemens.net> Date: Mon Jan 9 19:17:30 2012 -0500 Added useDns flag to testcase commit ace43eb94128f32538182472fd35e97c220bbf34 Author: Lee Clemens <java@leeclemens.net> Date: Sun Jan 8 15:13:27 2012 -0500 Added use_dns option in jail.conf
2012-01-13 04:23:41 +00:00
elif opt == "usedns":
stream.append(["set", self.__name, "usedns", self.__opts[opt]])
elif opt == "failregex":
stream.append(["set", self.__name, "addfailregex", self.__opts[opt]])
elif opt == "ignoreregex":
for regex in self.__opts[opt].split('\n'):
# Do not send a command if the rule is empty.
if regex != '':
stream.append(["set", self.__name, "addignoreregex", regex])
2013-12-13 11:36:00 +00:00
if self.__filter:
stream.extend(self.__filter.convert())
for action in self.__actions:
stream.extend(action.convert())
stream.insert(0, ["add", self.__name, backend])
return stream
#@staticmethod
def splitAction(action):
m = JailReader.actionCRE.match(action)
d = dict()
try:
mgroups = m.groups()
except AttributeError:
raise ValueError("While reading action %s we should have got 1 or "
"2 groups. Got: 0" % action)
if len(mgroups) == 2:
action_name, action_opts = mgroups
2013-12-12 20:35:30 +00:00
elif len(mgroups) == 1: # pragma: nocover - unreachable - .* on second group always matches
action_name, action_opts = mgroups[0], None
else: # pragma: nocover - unreachable - regex only can capture 2 groups
raise ValueError("While reading action %s we should have got up to "
"2 groups. Got: %r" % (action, mgroups))
if not action_opts is None:
# Huge bad hack :( This method really sucks. TODO Reimplement it.
actions = ""
escapeChar = None
allowComma = False
for c in action_opts:
if c in ('"', "'") and not allowComma:
# Start
escapeChar = c
allowComma = True
elif c == escapeChar:
# End
escapeChar = None
allowComma = False
else:
if c == ',' and allowComma:
actions += "<COMMA>"
else:
actions += c
# Split using ,
actionsSplit = actions.split(',')
# Replace the tag <COMMA> with ,
actionsSplit = [n.replace("<COMMA>", ',') for n in actionsSplit]
for param in actionsSplit:
p = param.split('=')
try:
d[p[0].strip()] = p[1].strip()
except IndexError:
logSys.error("Invalid argument %s in '%s'" % (p, action_opts))
return [action_name, d]
splitAction = staticmethod(splitAction)