Compare commits

...
Author SHA1 Message Date
Yaroslav Halchenko b14257f27f BF: Thanks to insights from Rogerio -- handle both aInfo and cInfo and replicate cmds if no key provided 2011-04-28 23:06:27 -04:00
Yaroslav Halchenko 28b44d2655 NF: Mockup for handling complex additional Init parameters in actions
So we could have substitutions tags chosen according to values of other tags,
e.g. in this case ipv (IP version) tag would be added by fail2ban
internally

novo# grep  -e '^[^#]' /etc/fail2ban/action.d/iptables-multiport.conf
[Definition]
actionstart = <actioncmd> -N fail2ban-<name>
              <actioncmd> -A fail2ban-<name> -j RETURN
              <actioncmd> -I <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
actionstop = <actioncmd> -D <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
             <actioncmd> -F fail2ban-<name>
             <actioncmd> -X fail2ban-<name>
actioncheck = <actioncmd> -n -L <chain> | grep -q fail2ban-<name>
actionban = <actioncmd> -I fail2ban-<name> 1 -s <ip> -j DROP
actionunban = <actioncmd> -D fail2ban-<name> -s <ip> -j DROP

[Init]
name = default
port = ssh
protocol = tcp
chain = INPUT
actioncmd/ipv = 4="iptables", 6="ip6tables"
2011-04-27 22:54:03 -04:00
2 changed files with 51 additions and 9 deletions
+48 -9
View File
@@ -81,6 +81,14 @@ class Action:
# @param value the property value
def setCInfo(self, key, value):
if '/' in key:
logSys.debug("Evaluating the value to dict")
try:
value = eval("dict(%s)" % value)
except Exception, e:
logSys.error("Failed to evaluate value dict(%s) for %s "
"as dict due to %r" % (value, key, e))
logSys.debug("Set cinfo %s = %r" % (key, value))
self.__cInfo[key] = value
##
@@ -237,7 +245,38 @@ class Action:
"""
string = query
for tag in aInfo:
string = string.replace('<' + tag + '>', str(aInfo[tag]))
# simple replacement string or a dictionary
val = aInfo[tag]
subs = [(tag, val)] # by default just 1 substitution pair
if '/' in tag:
# dict Info and we should take after '/' as the key
# which would determine which actual tag to take from
# aInfo
tag_, key_tag = tag.split('/', 1)
if not isinstance(val, dict):
logSys.error("Tags defined as X/Y must contain dictionary "
"entries. Got %r. Tag %s was ignored"
% (val, tag))
continue
if not key_tag in aInfo:
# Need to duplicate for all known and unique
logSys.debug(
"No information for key tag %s among %s. "
"Duplicating the string for all keys"
% (key_tag, aInfo.keys()))
subs = [(tag_, v) for v in val.itervalues()]
else:
# There is a key
if not aInfo[key_tag] in val:
logSys.error("There is no value for %s in %r. Tag %s was ignored"
% (aInfo[key_tag], val, tag))
continue
subs = [(tag_, val[aInfo[key_tag]])]
strings = [string.replace('<' + t + '>', str(v)) for t,v in subs]
# only unique, so we do not run the same command multiple times,
# if that tag wasn't even in place. anyways order of them is arbitrary
# due to arbitrary order of keys in a val dict above
string = '; '.join(list(set(strings)))
# New line
string = string.replace("<br>", '\n')
return string
@@ -274,15 +313,15 @@ class Action:
if not Action.executeCmd(checkCmd):
logSys.fatal("Unable to restore environment")
return False
# Replace tags
if not aInfo == None:
realCmd = Action.replaceTag(cmd, aInfo)
else:
realCmd = cmd
# Replace static fields
realCmd = Action.replaceTag(realCmd, self.__cInfo)
# Compose ultimate untagging dictionary with aInfo overriding
# present in cInfo
allInfo = self.__cInfo.copy()
if aInfo:
allInfo.update(aInfo)
# Replace tags
realCmd = Action.replaceTag(cmd, allInfo)
return Action.executeCmd(realCmd)
+3
View File
@@ -156,6 +156,9 @@ class Actions(JailThread):
aInfo = dict()
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
# TODO: adopt IPv6 handling from Rogerio
# and assign namespace here accordingly
aInfo["ipv"] = 4 # 4 for now
aInfo["failures"] = bTicket.getAttempt()
aInfo["time"] = bTicket.getTime()
if self.__banManager.addBanTicket(bTicket):