Обнаружение честных веб-сканеров

Я хотел бы обнаружить (на стороне сервера), какие запросы от ботов. На данный момент меня не волнуют злые боты, просто те, которые играют хорошо. Я видел несколько подходов, которые в основном связаны с совпадением строки пользовательского агента с такими ключевыми словами, как «бот». Но это кажется неудобным, неполным и неподвластным. Так у кого-то есть более прочные подходы? Если нет, есть ли у вас какие-либо ресурсы, которые вы используете, чтобы быть в курсе всех дружественных пользовательских агентов?

Если вам интересно: я не пытаюсь сделать что-либо против какой-либо политики в поисковых системах. У нас есть раздел сайта, где пользователь случайным образом представлен одной из нескольких немного разных версий страницы. Однако, если обнаружен веб-искатель, мы всегда предоставляем им одну и ту же версию, чтобы индекс был согласован.

Также я использую Java, но я бы предположил, что подход будет схожим для любой серверной технологии.

Вы можете найти очень подробную базу данных о известных «хороших» веб-сканерах в Robotstxt.org Robots Database . Использование этих данных было бы гораздо более эффективным, чем просто сопоставление бота в пользовательском агенте.

Вы сказали, что совпадение с пользовательским агентом на «боте» может быть неудобным, но мы обнаружили, что это довольно хороший матч. Наши исследования показали, что он охватит около 98% полученных вами обращений. Мы также не встретили никаких ложных позитивных матчей. Если вы хотите повысить этот показатель до 99,9%, вы можете включить несколько других хорошо известных совпадений, таких как «искатель», «baiduspider», «ia_archiver», «curl» и т. Д. Мы тестировали это на наших производственных системах более миллионами хитов.

Вот несколько решений для C # для вас:

1) Простейший

Является самым быстрым при обработке промаха. т.е. трафик от не-бота – обычный пользователь. Захватывает 99% скинов.

bool iscrawler = Regex.IsMatch(Request.UserAgent, @"bot|crawler|baiduspider|80legs|ia_archiver|voyager|curl|wget|yahoo! slurp|mediapartners-google", RegexOptions.IgnoreCase); 

2) Средний

Является самым быстрым при обработке хита. т.е. трафик от бота. Очень быстро для промахов тоже. Захватывает около 100% сканеров. Матчи «бот», «гусеничный», «паук». Вы можете добавить к нему другие известные сканеры.

 List Crawlers3 = new List() { "bot","crawler","spider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google", "lwp-trivial","nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne", "atn_worldwide","atomz","bjaaland","ukonline","calif","combine","cosmos","cusco", "cyberspyder","digger","grabber","downloadexpress","ecollector","ebiness","esculapio", "esther","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm", "gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","havindex","hotwired", "htdig","ingrid","informant","inspectorwww","iron33","teoma","ask jeeves","jeeves", "image.kapsi.net","kdd-explorer","label-grabber","larbin","linkidator","linkwalker", "lockon","marvin","mattie","mediafox","merzscope","nec-meshexplorer","udmsearch","moget", "motor","muncher","muninn","muscatferret","mwdsearch","sharp-info-agent","webmechanic", "netscoop","newscan-online","objectssearch","orbsearch","packrat","pageboy","parasite", "patric","pegasus","phpdig","piltdownman","pimptrain","plumtreewebaccessor","getterrobo-plus", "raven","roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au", "searchprocess","senrigan","shagseeker","site valet","skymob","slurp","snooper","speedy", "curl_image_client","suke","www.sygol.com","tach_bw","templeton","titin","topiclink","udmsearch", "urlck","valkyrie libwww-perl","verticrawl","victoria","webscout","voyager","crawlpaper", "webcatcher","thunderstone","webmoose","pagesinventory","webquest","webreaper", "webwalker","winona","occam","robi","fdse","jobo","rhcs","gazz","dwcp","yeti","fido","wlm", "wolp","wwwc","xget","legs","curl","webs","wget","sift","cmc" }; string ua = Request.UserAgent.ToLower(); bool iscrawler = Crawlers3.Exists(x => ua.Contains(x)); в List Crawlers3 = new List() { "bot","crawler","spider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google", "lwp-trivial","nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne", "atn_worldwide","atomz","bjaaland","ukonline","calif","combine","cosmos","cusco", "cyberspyder","digger","grabber","downloadexpress","ecollector","ebiness","esculapio", "esther","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm", "gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","havindex","hotwired", "htdig","ingrid","informant","inspectorwww","iron33","teoma","ask jeeves","jeeves", "image.kapsi.net","kdd-explorer","label-grabber","larbin","linkidator","linkwalker", "lockon","marvin","mattie","mediafox","merzscope","nec-meshexplorer","udmsearch","moget", "motor","muncher","muninn","muscatferret","mwdsearch","sharp-info-agent","webmechanic", "netscoop","newscan-online","objectssearch","orbsearch","packrat","pageboy","parasite", "patric","pegasus","phpdig","piltdownman","pimptrain","plumtreewebaccessor","getterrobo-plus", "raven","roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au", "searchprocess","senrigan","shagseeker","site valet","skymob","slurp","snooper","speedy", "curl_image_client","suke","www.sygol.com","tach_bw","templeton","titin","topiclink","udmsearch", "urlck","valkyrie libwww-perl","verticrawl","victoria","webscout","voyager","crawlpaper", "webcatcher","thunderstone","webmoose","pagesinventory","webquest","webreaper", "webwalker","winona","occam","robi","fdse","jobo","rhcs","gazz","dwcp","yeti","fido","wlm", "wolp","wwwc","xget","legs","curl","webs","wget","sift","cmc" }; string ua = Request.UserAgent.ToLower(); bool iscrawler = Crawlers3.Exists(x => ua.Contains(x)); 

3) Параноидальный

Это довольно быстро, но немного медленнее, чем варианты 1 и 2. Это наиболее точно, и позволяет вам поддерживать списки, если хотите. Вы можете сохранить отдельный список имен с «ботом» в них, если вы боитесь ложных срабатываний в будущем. Если мы получим короткое совпадение, мы запишем его и проверим на наличие ложных срабатываний.

 // crawlers that have 'bot' in their useragent List Crawlers1 = new List() { "googlebot","bingbot","yandexbot","ahrefsbot","msnbot","linkedinbot","exabot","compspybot", "yesupbot","paperlibot","tweetmemebot","semrushbot","gigabot","voilabot","adsbot-google", "botlink","alkalinebot","araybot","undrip bot","borg-bot","boxseabot","yodaobot","admedia bot", "ezooms.bot","confuzzledbot","coolbot","internet cruiser robot","yolinkbot","diibot","musobot", "dragonbot","elfinbot","wikiobot","twitterbot","contextad bot","hambot","iajabot","news bot", "irobot","socialradarbot","ko_yappo_robot","skimbot","psbot","rixbot","seznambot","careerbot", "simbot","solbot","mail.ru_bot","spiderbot","blekkobot","bitlybot","techbot","void-bot", "vwbot_k","diffbot","friendfeedbot","archive.org_bot","woriobot","crystalsemanticsbot","wepbot", "spbot","tweetedtimes bot","mj12bot","who.is bot","psbot","robot","jbot","bbot","bot" }; // crawlers that don't have 'bot' in their useragent List Crawlers2 = new List() { "baiduspider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google","lwp-trivial", "nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne","atn_worldwide","atomz", "bjaaland","ukonline","bspider","calif","christcrawler","combine","cosmos","cusco","cyberspyder", "cydralspider","digger","grabber","downloadexpress","ecollector","ebiness","esculapio","esther", "fastcrawler","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm", "gammaspider","gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","portalbspider", "havindex","hotwired","htdig","ingrid","informant","infospiders","inspectorwww","iron33", "jcrawler","teoma","ask jeeves","jeeves","image.kapsi.net","kdd-explorer","label-grabber", "larbin","linkidator","linkwalker","lockon","logo_gif_crawler","marvin","mattie","mediafox", "merzscope","nec-meshexplorer","mindcrawler","udmsearch","moget","motor","muncher","muninn", "muscatferret","mwdsearch","sharp-info-agent","webmechanic","netscoop","newscan-online", "objectssearch","orbsearch","packrat","pageboy","parasite","patric","pegasus","perlcrawler", "phpdig","piltdownman","pimptrain","pjspider","plumtreewebaccessor","getterrobo-plus","raven", "roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au","searchprocess", "senrigan","shagseeker","site valet","skymob","slcrawler","slurp","snooper","speedy", "spider_monkey","spiderline","curl_image_client","suke","www.sygol.com","tach_bw","templeton", "titin","topiclink","udmsearch","urlck","valkyrie libwww-perl","verticrawl","victoria", "webscout","voyager","crawlpaper","wapspider","webcatcher","thunderstone", "webmoose","pagesinventory","webquest","webreaper","webspider","webwalker","winona","occam", "robi","fdse","jobo","rhcs","gazz","dwcp","yeti","crawler","fido","wlm","wolp","wwwc","xget", "legs","curl","webs","wget","sift","cmc" }; string ua = Request.UserAgent.ToLower(); string match = null; if (ua.Contains("bot")) match = Crawlers1.FirstOrDefault(x => ua.Contains(x)); else match = Crawlers2.FirstOrDefault(x => ua.Contains(x)); if (match != null && match.Length < 5) Log("Possible new crawler found: ", ua); bool iscrawler = match != null; в // crawlers that have 'bot' in their useragent List Crawlers1 = new List() { "googlebot","bingbot","yandexbot","ahrefsbot","msnbot","linkedinbot","exabot","compspybot", "yesupbot","paperlibot","tweetmemebot","semrushbot","gigabot","voilabot","adsbot-google", "botlink","alkalinebot","araybot","undrip bot","borg-bot","boxseabot","yodaobot","admedia bot", "ezooms.bot","confuzzledbot","coolbot","internet cruiser robot","yolinkbot","diibot","musobot", "dragonbot","elfinbot","wikiobot","twitterbot","contextad bot","hambot","iajabot","news bot", "irobot","socialradarbot","ko_yappo_robot","skimbot","psbot","rixbot","seznambot","careerbot", "simbot","solbot","mail.ru_bot","spiderbot","blekkobot","bitlybot","techbot","void-bot", "vwbot_k","diffbot","friendfeedbot","archive.org_bot","woriobot","crystalsemanticsbot","wepbot", "spbot","tweetedtimes bot","mj12bot","who.is bot","psbot","robot","jbot","bbot","bot" }; // crawlers that don't have 'bot' in their useragent List Crawlers2 = new List() { "baiduspider","80legs","baidu","yahoo! slurp","ia_archiver","mediapartners-google","lwp-trivial", "nederland.zoek","ahoy","anthill","appie","arale","araneo","ariadne","atn_worldwide","atomz", "bjaaland","ukonline","bspider","calif","christcrawler","combine","cosmos","cusco","cyberspyder", "cydralspider","digger","grabber","downloadexpress","ecollector","ebiness","esculapio","esther", "fastcrawler","felix ide","hamahakki","kit-fireball","fouineur","freecrawl","desertrealm", "gammaspider","gcreep","golem","griffon","gromit","gulliver","gulper","whowhere","portalbspider", "havindex","hotwired","htdig","ingrid","informant","infospiders","inspectorwww","iron33", "jcrawler","teoma","ask jeeves","jeeves","image.kapsi.net","kdd-explorer","label-grabber", "larbin","linkidator","linkwalker","lockon","logo_gif_crawler","marvin","mattie","mediafox", "merzscope","nec-meshexplorer","mindcrawler","udmsearch","moget","motor","muncher","muninn", "muscatferret","mwdsearch","sharp-info-agent","webmechanic","netscoop","newscan-online", "objectssearch","orbsearch","packrat","pageboy","parasite","patric","pegasus","perlcrawler", "phpdig","piltdownman","pimptrain","pjspider","plumtreewebaccessor","getterrobo-plus","raven", "roadrunner","robbie","robocrawl","robofox","webbandit","scooter","search-au","searchprocess", "senrigan","shagseeker","site valet","skymob","slcrawler","slurp","snooper","speedy", "spider_monkey","spiderline","curl_image_client","suke","www.sygol.com","tach_bw","templeton", "titin","topiclink","udmsearch","urlck","valkyrie libwww-perl","verticrawl","victoria", "webscout","voyager","crawlpaper","wapspider","webcatcher","thunderstone", "webmoose","pagesinventory","webquest","webreaper","webspider","webwalker","winona","occam", "robi","fdse","jobo","rhcs","gazz","dwcp","yeti","crawler","fido","wlm","wolp","wwwc","xget", "legs","curl","webs","wget","sift","cmc" }; string ua = Request.UserAgent.ToLower(); string match = null; if (ua.Contains("bot")) match = Crawlers1.FirstOrDefault(x => ua.Contains(x)); else match = Crawlers2.FirstOrDefault(x => ua.Contains(x)); if (match != null && match.Length < 5) Log("Possible new crawler found: ", ua); bool iscrawler = match != null; 

Заметки:

  • Заманчиво просто добавлять имена в параметр регулярного выражения 1. Но если вы сделаете это, он станет медленнее. Если вам нужен более полный список, то linq с лямбдой быстрее.
  • Убедитесь, что .ToLower () находится вне вашего метода linq - помните, что метод представляет собой цикл, и вы будете изменять строку во время каждой итерации.
  • Всегда ставьте самых тяжелых ботов в начале списка, чтобы они соответствовали раньше.
  • Поместите списки в статический class, чтобы они не перестраивались на каждом просмотре страниц.

Honeypots

Единственная реальная альтернатива этому - создать на вашем сайте ссылку «honeypot», которую достигнет только бот. Затем вы регистрируете строки агента пользователя, которые попадают на страницу honeypot в базу данных. Затем вы можете использовать эти зарегистрированные строки для classификации сканеров.

Postives: он будет соответствовать неизвестным сканерам, которые не декларируют себя.

Negatives: Не все сканеры достаточно глубоко пробиваются, чтобы поразить каждую ссылку на вашем сайте, и поэтому они могут не дойти до вашей honeypot.

Одно из предложений заключается в создании пустого привязки на вашей странице, за которым последует только бот. Обычные пользователи не видят ссылку, оставляя пауков и ботов. Например, пустой тег привязки, указывающий на подпапку, записывает запрос на получение в ваших журналах …

  

Многие люди используют этот метод при запуске HoneyPot, чтобы поймать вредоносных ботов, которые не следуют за файлом robots.txt. Я использую пустой метод привязки в решении ASP.NET для honeypot, которое я написал, чтобы поймать ловушку и заблокировать этих жутких сканеров …

Любой посетитель, чья страница входа /robots.txt, вероятно, является ботом.

Что-то быстрое и грязное, как это может быть хорошим началом:

 return if request.user_agent =~ /googlebot|msnbot|baidu|curl|wget|Mediapartners-Google|slurp|ia_archiver|Gigabot|libwww-perl|lwp-trivial/i 

Примечание: код рельсов, но регулярное выражение обычно применимо.

Я почти уверен, что большая часть ботов не использует robots.txt, но это была моя первая мысль.

Мне кажется, что лучший способ обнаружить бота – это время между запросами, если время между запросами последовательно быстро, а затем его бот.

Давайте будем гением компьютера.