filter.d/ignorecommands/apache-fakegooglebot: added timeout parameter (default 55 seconds) - avoid fail with timeout (default 1 minute) by reverse lookup on some slow DNS services (googlebots must be resolved fast);

closes gh-2951
pull/3117/head
sebres 2021-03-02 19:24:03 +01:00
parent 63acc862b1
commit a45b1c974c
2 changed files with 25 additions and 13 deletions

View File

@ -6,24 +6,35 @@
#
import sys
from fail2ban.server.ipdns import DNSUtils, IPAddr
from threading import Thread
def process_args(argv):
if len(argv) != 2:
raise ValueError("Please provide a single IP as an argument. Got: %s\n"
% (argv[1:]))
if len(argv) - 1 not in (1, 2):
raise ValueError("Usage %s ip ?timeout?. Got: %s\n"
% (argv[0], argv[1:]))
ip = argv[1]
if not IPAddr(ip).isValid:
raise ValueError("Argument must be a single valid IP. Got: %s\n"
% ip)
return ip
return argv[1:]
google_ips = None
def is_googlebot(ip):
def is_googlebot(ip, timeout=55):
import re
host = DNSUtils.ipToName(ip)
timeout = float(timeout or 0)
if timeout:
def ipToNameTO(host, ip, timeout):
host[0] = DNSUtils.ipToName(ip)
host = [None]
th = Thread(target=ipToNameTO, args=(host, ip, timeout)); th.daemon=True; th.start()
th.join(timeout)
host = host[0]
else:
host = DNSUtils.ipToName(ip)
if not host or not re.match(r'.*\.google(bot)?\.com$', host):
return False
host_ips = DNSUtils.dnsToIp(host)
@ -31,7 +42,7 @@ def is_googlebot(ip):
if __name__ == '__main__': # pragma: no cover
try:
ret = is_googlebot(process_args(sys.argv))
ret = is_googlebot(*process_args(sys.argv))
except ValueError as e:
sys.stderr.write(str(e))
sys.exit(2)

View File

@ -606,13 +606,14 @@ class IgnoreIPDNS(LogCaptureTestCase):
cmd = os.path.join(STOCK_CONF_DIR, "filter.d/ignorecommands/apache-fakegooglebot")
## below test direct as python module:
mod = Utils.load_python_module(cmd)
self.assertFalse(mod.is_googlebot(mod.process_args([cmd, "128.178.222.69"])))
self.assertFalse(mod.is_googlebot(mod.process_args([cmd, "192.0.2.1"])))
self.assertFalse(mod.is_googlebot(*mod.process_args([cmd, "128.178.222.69"])))
self.assertFalse(mod.is_googlebot(*mod.process_args([cmd, "192.0.2.1"])))
self.assertFalse(mod.is_googlebot(*mod.process_args([cmd, "192.0.2.1", 0.1])))
bot_ips = ['66.249.66.1']
for ip in bot_ips:
self.assertTrue(mod.is_googlebot(mod.process_args([cmd, str(ip)])), "test of googlebot ip %s failed" % ip)
self.assertRaises(ValueError, lambda: mod.is_googlebot(mod.process_args([cmd])))
self.assertRaises(ValueError, lambda: mod.is_googlebot(mod.process_args([cmd, "192.0"])))
self.assertTrue(mod.is_googlebot(*mod.process_args([cmd, str(ip)])), "test of googlebot ip %s failed" % ip)
self.assertRaises(ValueError, lambda: mod.is_googlebot(*mod.process_args([cmd])))
self.assertRaises(ValueError, lambda: mod.is_googlebot(*mod.process_args([cmd, "192.0"])))
## via command:
self.filter.ignoreCommand = cmd + " <ip>"
for ip in bot_ips:
@ -624,7 +625,7 @@ class IgnoreIPDNS(LogCaptureTestCase):
self.pruneLog()
self.filter.ignoreCommand = cmd + " bad arguments <ip>"
self.assertFalse(self.filter.inIgnoreIPList("192.0"))
self.assertLogged('Please provide a single IP as an argument.')
self.assertLogged('Usage')