mirror of https://github.com/fail2ban/fail2ban
				
				
				
			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-2951pull/3117/head
							parent
							
								
									63acc862b1
								
							
						
					
					
						commit
						a45b1c974c
					
				| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue