From ace43eb94128f32538182472fd35e97c220bbf34 Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Sun, 8 Jan 2012 15:13:27 -0500 Subject: [PATCH 01/11] Added use_dns option in jail.conf --- config/jail.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/jail.conf b/config/jail.conf index cdef1cb3..3b779c9c 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -38,6 +38,16 @@ maxretry = 3 # pyinotify, gamin, polling. backend = auto +# "use_dns" specifies if jails should trust hostnames in logs, +# warn when reverse DNS lookups are performed, or ignore all hostnames in logs +# +# yes: if a hostname is encountered, a reverse DNS lookup will be performed. +# warn: if a hostname is encountered, a reverse DNS lookup will be performed, +# but it will be logged as a warning. +# no: if a hostname is encountered, will not be used for banning, +# but it will be logged as info. +use_dns = warn + # This jail corresponds to the standard configuration in Fail2ban 0.6. # The mail-whois action send a notification e-mail with a whois request From ae1e857e53e0c014da5b717976536be172a37dc1 Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Mon, 9 Jan 2012 19:17:30 -0500 Subject: [PATCH 02/11] Added useDns flag to testcase --- testcases/filtertestcase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 6c29bdd6..4e03b342 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -222,12 +222,12 @@ class GetFailures(unittest.TestCase): class DNSUtilsTests(unittest.TestCase): - def testTextToIp(self): + def testTextToIp(self, useDns): # Bogus addresses which should have no DNS matches bogus = [ 'doh1.2.3.4.buga.xxxxx.yyy.invalid', '1.2.3.4.buga.xxxxx.yyy.invalid', ] for s in bogus: - res = DNSUtils.textToIp(s) + res = DNSUtils.textToIp(s, useDns) self.assertEqual(res, []) From 9538553bc5a71faf23b5b810b83d7acb133c8d56 Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Mon, 9 Jan 2012 20:01:34 -0500 Subject: [PATCH 03/11] ENH: Added use_dns option --- server/filter.py | 58 ++++++++++++++++++++++++++++++++----------- server/server.py | 6 +++++ server/transmitter.py | 6 +++++ 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/server/filter.py b/server/filter.py index e18f5b7d..e4c5e86b 100644 --- a/server/filter.py +++ b/server/filter.py @@ -64,6 +64,8 @@ class Filter(JailThread): self.__failRegex = list() ## The regular expression list with expressions to ignore. self.__ignoreRegex = list() + ## Use DNS setting + self.__useDns = "warn" ## The amount of time to look back. self.__findTime = 6000 ## The ignore IP list. @@ -139,6 +141,21 @@ class Filter(JailThread): ignoreRegex.append(regex.getRegex()) return ignoreRegex + ## + # Set the Use DNS mode + # @param value the use_dns mode + + def setUseDns(self, value): + self.__useDns = value + logSys.info("Set use_dns = %s" % value) + + ## + # Get the use_dns mode + # @return the use_dns mode + + def getUseDns(self): + return self.__useDns + ## # Set the time needed to find a failure. # @@ -325,7 +342,7 @@ class Filter(JailThread): else: try: host = failRegex.getHost() - ipMatch = DNSUtils.textToIp(host) + ipMatch = DNSUtils.textToIp(host, self.__useDns) if ipMatch: for ip in ipMatch: failList.append([ip, date]) @@ -564,22 +581,33 @@ class DNSUtils: isValidIP = staticmethod(isValidIP) #@staticmethod - def textToIp(text): + def textToIp(text, useDns): """ Return the IP of DNS found in a given text. """ - ipList = list() - # Search for plain IP - plainIP = DNSUtils.searchIP(text) - if not plainIP == None: - plainIPStr = plainIP.group(0) - if DNSUtils.isValidIP(plainIPStr): - ipList.append(plainIPStr) - if not ipList: - # Try to get IP from possible DNS - ip = DNSUtils.dnsToIp(text) - for e in ip: - ipList.append(e) - return ipList + logSys.debug("Checking rDNS: %s" % text) + logSys.debug("DNS use_dns == %s" % useDns) + if useDns == "no": + logSys.debug("use_dns == no") + return None + else: + logSys.debug("use_dns != no") + ipList = list() + # Search for plain IP + plainIP = DNSUtils.searchIP(text) + if not plainIP is None: + plainIPStr = plainIP.group(0) + if DNSUtils.isValidIP(plainIPStr): + ipList.append(plainIPStr) + if not ipList: + # Try to get IP from possible DNS + ip = DNSUtils.dnsToIp(text) + for e in ip: + ipList.append(e) + logSys.debug("At bottom of textToIp, ipList == %s" % ipList) + if useDns == "warn": + logSys.warning("IP Banned after DNS Reverse Lookup: %s = %s", + text, ipList) + return ipList textToIp = staticmethod(textToIp) #@staticmethod diff --git a/server/server.py b/server/server.py index 950cf82b..b734f82a 100644 --- a/server/server.py +++ b/server/server.py @@ -204,6 +204,12 @@ class Server: def getIgnoreRegex(self, name): return self.__jails.getFilter(name).getIgnoreRegex() + def setUseDns(self, name, value): + self.__jails.getFilter(name).setUseDns(value) + + def getUseDns(self, name): + return self.__jails.getFilter(name).getUseDns() + def setMaxRetry(self, name, value): self.__jails.getFilter(name).setMaxRetry(value) diff --git a/server/transmitter.py b/server/transmitter.py index bebba12b..305fde15 100644 --- a/server/transmitter.py +++ b/server/transmitter.py @@ -154,6 +154,10 @@ class Transmitter: value = int(command[2]) self.__server.delIgnoreRegex(name, value) return self.__server.getIgnoreRegex(name) + elif command[1] == "use_dns": + value = command[2] + self.__server.setUseDns(name, value) + return self.__server.getUseDns(name) elif command[1] == "findtime": value = command[2] self.__server.setFindTime(name, int(value)) @@ -231,6 +235,8 @@ class Transmitter: return self.__server.getFailRegex(name) elif command[1] == "ignoreregex": return self.__server.getIgnoreRegex(name) + elif command[1] == "use_dns": + return self.__server.getUseDns(name) elif command[1] == "findtime": return self.__server.getFindTime(name) elif command[1] == "maxretry": From d23d495547fe382ea6669c30eeac5033284b4c5f Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Mon, 9 Jan 2012 20:05:35 -0500 Subject: [PATCH 04/11] ENH: Added use_dns option --- client/jailreader.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/jailreader.py b/client/jailreader.py index 81a077c9..cf1e0109 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -61,6 +61,7 @@ class JailReader(ConfigReader): def getOptions(self): opts = [["bool", "enabled", "false"], ["string", "logpath", "/var/log/messages"], + ["string", "use_dns", "warn"], ["string", "backend", "auto"], ["int", "maxretry", 3], ["int", "findtime", 600], From 06316180870a0349630e27f7ef078624c6f006cd Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Mon, 9 Jan 2012 22:41:18 -0500 Subject: [PATCH 05/11] Completed use_dns for initial startup - with debugging statements --- client/jailreader.py | 5 ++++- server/filter.py | 11 ++++++----- server/server.py | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/client/jailreader.py b/client/jailreader.py index cf1e0109..618320c2 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -61,11 +61,11 @@ class JailReader(ConfigReader): def getOptions(self): opts = [["bool", "enabled", "false"], ["string", "logpath", "/var/log/messages"], - ["string", "use_dns", "warn"], ["string", "backend", "auto"], ["int", "maxretry", 3], ["int", "findtime", 600], ["int", "bantime", 600], + ["string", "use_dns", "warn"], ["string", "failregex", None], ["string", "ignoreregex", None], ["string", "ignoreip", None], @@ -123,6 +123,9 @@ class JailReader(ConfigReader): stream.append(["set", self.__name, "findtime", self.__opts[opt]]) elif opt == "bantime": stream.append(["set", self.__name, "bantime", self.__opts[opt]]) + elif opt == "use_dns": + logSys.debug("USE_DNS: In jailreader.convert") + stream.append(["set", self.__name, "use_dns", self.__opts[opt]]) elif opt == "failregex": stream.append(["set", self.__name, "addfailregex", self.__opts[opt]]) elif opt == "ignoreregex": diff --git a/server/filter.py b/server/filter.py index e4c5e86b..a08ba640 100644 --- a/server/filter.py +++ b/server/filter.py @@ -147,13 +147,14 @@ class Filter(JailThread): def setUseDns(self, value): self.__useDns = value - logSys.info("Set use_dns = %s" % value) + logSys.info("USE_DNS: Set use_dns = %s" % value) ## # Get the use_dns mode # @return the use_dns mode def getUseDns(self): + logSys.debug("USE_DNS: Get use_dns = %s" % self.__useDns) return self.__useDns ## @@ -584,13 +585,13 @@ class DNSUtils: def textToIp(text, useDns): """ Return the IP of DNS found in a given text. """ - logSys.debug("Checking rDNS: %s" % text) - logSys.debug("DNS use_dns == %s" % useDns) + logSys.debug("USE_DNS: Checking rDNS: %s" % text) + logSys.debug("USE_DNS: DNS use_dns == %s" % useDns) if useDns == "no": - logSys.debug("use_dns == no") + logSys.debug("USE_DNS: use_dns == no") return None else: - logSys.debug("use_dns != no") + logSys.debug("USE_DNS: use_dns != no") ipList = list() # Search for plain IP plainIP = DNSUtils.searchIP(text) diff --git a/server/server.py b/server/server.py index b734f82a..c7537743 100644 --- a/server/server.py +++ b/server/server.py @@ -205,9 +205,11 @@ class Server: return self.__jails.getFilter(name).getIgnoreRegex() def setUseDns(self, name, value): + logSys.debug("USE_DNS: in server.setUseDns: %s" % value) self.__jails.getFilter(name).setUseDns(value) def getUseDns(self, name): + logSys.debug("USE_DNS: in server.getUseDns: %s" % name) return self.__jails.getFilter(name).getUseDns() def setMaxRetry(self, name, value): From 76696d452ae59e0fa161e1f85e31c6411352f966 Mon Sep 17 00:00:00 2001 From: Lee Clemens Date: Mon, 9 Jan 2012 22:53:39 -0500 Subject: [PATCH 06/11] Added use_dns protocol to set and get per jail during runtime --- common/protocol.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/protocol.py b/common/protocol.py index 092c32ae..8361ee08 100644 --- a/common/protocol.py +++ b/common/protocol.py @@ -62,6 +62,7 @@ protocol = [ ["set delignoreregex ", "removes the regular expression at for ignoreregex"], ["set findtime