Pull to refresh

Черный список IP своими руками

Reading time 14 min
Views 19K
Совсем недавно мною была выложена статья, касающаяся безопасности сайта и, в частности, проблемы капчи и большого вопроса — можно ли от нее избавиться и как это сделать.

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

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

Анализ допущенных ошибок


А ошибка одна, но довольно существенная. Внезапно оказалось, что есть не только теоретическая, но и практическая возможность сделать такого робота, которого либо нельзя либо трудно отличить от человека. Такой робот может закачивать клиентский код JS и нажимать на любые кнопки на сайте. Поскольку я в своей практике ни разу не встречался с такими зверями, я не то, чтобы был уверен, что их вообще не существует, но, скажем мягче, хотел испытать их действие на себе (своем сайте). После опубликования анализируемой статьи, анонимные, но несомненно добрые люди предоставили мне такую возможность. Только в полной мере испытать, не удалось.

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

На мой сайт пошли атаки. Я поменял имя js функции, которая выполнялась по нажатию на кнопку отправки объявления, и нападения прекратились, как отрезало. Могло это случиться по той причине, что робот был запрограммирован на исполнение скрипта по имени? Могло. А мог бы он быть потом перепрограммирован на что-то иное? Например, на поиск кнопки и парсинг ее? Да, мог бы. Тогда, для борьбы с этим роботом, мне придется закрывать все больше и больше вещей, прятать кнопку, делать еще какие-то трудоемкие ухищрения, и все равно они могут быть преодолены. Это, с одной стороны, грустно, а с другой стороны куда легче с моей стороны поставить крутую непробиваемую капчу и закрыть вопрос надежно, хоть и за счет пользователя.

Но, прошу обратить внимание, робот не был перепрограммирован! Это значит, что спамить мой «сборщик спама» невыгодно. Это совершенно четко подтвердило тезис о том, что сайт, подвергающийся нападению, должен иметь для этого адекватную ценность.

Вывод 1. Нет смысла ставить очень сложную защиту на набирающие популярность сайты. Лучше попробовать использовать метод "аяксовой кнопки", которую я описывал в статье или любой другой похожий метод из тех, что были предложены в комментариях. Такой подход как минимум не отпугнет тех пользователей, что есть, и не будет тормозом для конверсии. И только по мере начала сложных нападений следует анализировать мотивацию спамера и уже в связи с этим искать методы борьбы, самым последним из которых я вижу сложную и недобрую для подслеповатого человека (как я) капчу.

Вывод 2. Мой метод "разрешите войти" по большому счету оказался бесполезным. Можно реализовать ту же самую функциональность куда меньшими и дешевыми средствами без потери функциональности.

Вывод 3. Я понял, зачем Яндекс поставил капчу на каждый запрос получения данных в инструменте «подбора поисковых слов»! Мне приходится снять с него свою обиду за эту капчу и виртуально извиниться (поскольку обижался я тоже виртуально).

Что еще хотелось бы сказать про описываемую виртуально-браузерную атаку на мой сборщик спама? Есть кое-что, и это уже будет из разряда "хороших новостей". Дело в том, что все запросы шли с разных ip-адресов, и все они были плохими! Что значит "плохими"? Это были либо адреса, которые уже на моем сайте встречались и были помечены, как подозрительные или опасные, а другие я выборочно проверял по своему любимому сайту www.projecthoneypot.org, и многие (большинство) там были помечены, как опасные.

Вывод 4. Пометка IP-адресов в качестве опасных или подозрительных может помочь в деле борьбы со спамом. Есть сервисы, которые предоставляют эти данные бесплатно или за деньги. Бесплатные сведения скорее всего никого не спасут, ибо они ограничены по размерам, а вот платные могли бы принести существенную пользу. Тем же, кто по разным причинам не хочет тратить деньги на сервисы такого рода, можно было бы предложить осуществить этот сервис своими силами. Именно об этом я и хотел бы дальше поразмышлять.

Для каких сайтов может пригодиться такой сервис?


  • Вообще, для всех. Такой сервис заставляет хозяина сайта быть в курсе того, что на нем творится. Это всегда полезно просто в целях поддержания порядка. Делаю такой вывод исключительно исходя из своего опыта. Мне учет ури и IP неоднократно помогал в настройке своего сайта.
  • Для сайтов, у которых существуют крайне полезные онлайн-сервисы, и хозяева которых озабочены с одной стороны скоростью доступа пользователей к этому сервису, а с другой стороны снижением нагрузки на сервер.
  • Для сайтов, которых спамят и это начинает превращаться в проблему.
  • Для тех программистов и хозяев сайтов, которые крайне мотивированы собирать подобную статистику, но иногда сами затрудняются объяснить свою мотивацию. К таким программистам я могу и себя отнести.


Что делать с помеченными IP адресами?


Уличенные во вредной деятельности IP адреса можно поразить в правах. Например, им можно давать капчу при заполнении форм. С большой степенью вероятности — это не человек. Посты с таких IP можно отправлять на модерацию, а саму модерацию откладывать «на последнюю очередь». При модерации давать ссылку на пометку адреса клиента в качестве рассыльщика спама. Возможно прямо в письме-уведомлении администратору сайта о поступившем комментарии присылать одноразовую ссылку на пометку клиента.

Заходы с плохих IP адресов можно не обрабатывать, не приводить в нормальный вид и не редиректить на правильные адреса, что может значительно увеличить быстродействие сайта.

Поясню последнее утверждение на примере. Некоему сайту уже много лет. Это сайт статей. Давным давно хозяином сайта некоторые статьи были размещены на определенных ресурсах специально. Еще целый ряд материалов был утащен и на них была дана ссылка на первичное местоположение. Эти статьи с тех пор так и висят на этих ресурсах, договориться с хозяевами этих ресурсов не представляется возможным, а ссылки на эти статьи изменились. И при этом есть постоянные заходы на сайт по этим адресам и их приходится анализировать и редиректить. Но однажды, анализируя тех, кого приходится редиректить, возникли весьма обоснованные подозрения, что сайт работает не совсем для людей. Очень многие посетители являются роботами. Причем это могут быть такие роботы, которых по большому счету пускать к себе не всегда хочется. Вот тут тоже может здорово помочь пометка IP адресов. Ведь мы можем помечать адреса не только как «плохие» и «подозрительные», но и как «желательный бот», «нежелательный бот» и так далее.


Базой IP адресов можно делиться бесплатно, и даже можно сделать из этой деятельности некий бизнес.

На каком основании помечать IP адреса?


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

Запрос критических файлов определенных движков, которые на сайте не используются


Например, я не использую на своем сайте движок WordPress, но приходит запрос на чтение файла конфигурации этого движка или страницы входа для администратора.

Запросы к системным папкам сервера типа "/../../../.." или к файлам типа "passwd"


Ниже приведен реальный список значений, по которым я ловлю плохие IP. Это совсем небольшой список, но он работает довольно хорошо.

        $patterns = array(
            '#/wp-#',
            '#/browser#',
            '#/includ#',
            '#/engin#',
            '#admin#i',
            '#system#',
            '#/bitrix#',
            '#/cat_newuser#',  // страница регистрации, удаленная более 5 лет назад (8)
            '#/forum#',
            '#/common#',
            '#/plugins#',
            '#\.mdb/?#',
            '#\.aspx?/?#',
            '#^/BingSiteAuth#',
            '#passwd#',
            );

Запросы к CGI скриптам, если они не используются


К сожалению, такие запросы посредством .htaccess не ловятся (я пока не знаю, как их поймать), а доступа к редактированию виртуальных хостов может и не быть. Но эти запросы попадают в лог ошибок и IP адреса, которые обращались к этим файлам можно взять оттуда.

Запросы к страницам, вышедшим из употребления в процессе реорганизации сайта или еще по каким-нибудь причинам


Вот интересный прием, который я сначала использовал случайно, а потом, пронаблюдав результаты, подумал, что он может быть интересным и для намеренного использования. Предположим, есть страница регистрации. Называется она неважно как. Пусть ури ее будет, например, "/reg-new-user/". И вот эту страницу стали использовать роботы. Либо пытаться зарегистрироваться, если не стояло никаких защит, типа «аяксовой кнопки», либо просто к странице стало происходить слишком много обращений по сравнению с реальными регистрациями. Тогда мы меняем ури этой страницы и никаких редиректов со старой на новую не делаем. А запросы к старой продолжают идти и идти. И идут годами. Если вот так оглянуться назад, то уже лет 8 идут. Логично все IP, которые до этого адреса ломятся, сразу помечать опасными. Получилась ловушка вредных роботов. Кстати, робот поисковой системы Bing тоже ломится по такого рода адресам. Притом это не поддельный робот, а настоящий. Вот удивительно, что он такого сканирует, чтобы эти адреса получать? Может быть он сканирует и индексирует секретные форумы хакеров? Хороший вопрос, на который я, к сожалению, не знаю ответа.

Ловушка IP по результату анализа данных субмита форм


Для организации этой ловушки, нужно иметь в форме поле, которое заполняется клиентским скриптом. То есть, реальный пользователь, работая на реальном браузере подкачивает скрипт, который по нажатию на кнопку в форме заполняет некоторое поле совершенно определенным значением. Имя поля должно быть непонятным для робота, а значение должно быть закодировано и лучше одноразово. Такое значение можно генерировать из метки времени, обработанной по определенному алгоритму. Тогда робот либо не заполнит поле, либо заполнит его не тем значением, которое ожидается. Наличие неожиданного значения в этом поле сразу влечет пометку IP опасным. У меня в качестве такой ловушки работает описанный в предыдущей статье метод под кодовым названием "разрешите войти".

Следует уточнить особо. Этот метод не сработает для виртуальных js браузеров, которые тоже могут использоваться для автоматического доступа к страницам и рассылке спама.


Специальные ловушки


Имеются ввиду ловушки, созданные специально для роботов. Например, я на некотором этапе сделал доску объявлений. Этот инструмент себя не оправдал и был отключен. Но он некоторое время поучаствовал в каталогах досок и набрал широкую и верную «клиентуру», которая работает уже много лет. Чтобы «не обижать» клиентов, я опять включил этот инструмент, превратив его в своеобразный причал для роботов. Все, кто туда заходят, скорее всего не люди и их можно смело помечать в качестве роботов, рассылающих спам.

Неестественные запросы


Мы постепенно подошли к способам пометки больше теоретическим, чем практическим. Да. Очевидно, есть короткие серии запросов с одних и тех же IP к различным страницам с высокой скоростью (до нескольких штук в секунду). Такие серии сильно загружают сервер. Производить их могут как вредные роботы и боты, так и спайдеры, полезность которых мною до сих пор не выяснена. Такие странные боты метят себя в агентах и не очень-то церемонятся на вашем сайте. Совсем недавно я был свидетелем реальной ситуации, когда робот, метящий себя именем "ahrefs", пронюхал урл поиска продукта по фильтрам и на сутки остановил деятельность довольно крупного интернет-магазина, поскольку этот запрос оказался неоптимизирован с точки зрения MySQL. И если бы робот не был бы отключен через .htaccess, то он, наверное, никогда бы не остановился.

Но как с наименьшими затратами вылавливать такие неестественные запросы? Я много думал и пока не придумал ничего кроме ручной пометки и блокировки по результатам просмотра логов доступа. Поскольку логи хорошего сайта могут достигать десятков мегабайт, то этот вопрос тоже переходит в область фантастики. Хуже всего то, что урлы могут запрашиваться реальные и отрабатывают честно, и ни в какие логи плохих ури не попадают. Остается только выход пометки IP по агентам пользователя. Вынесу этот метод в отдельный пункт.

Пометка IP по содержимому заголовка агента клиента


HTTP_USER_AGENT — заголовок, на который трудно ориентироваться при отлове плохих клиентов. Куда проще помечать с помощью этого заголовка клиентов хороших, например, ботов желательных поисковиков. Но есть и случаи подделок. В любом случае IP-адреса роботов поисковых систем лучше пометить все сразу и в ручном режиме. Для вставки пулов таких IP в базу можно воспользоваться информацией whois. В этом случае все IP адреса клиентов с агентами googlebot, но не принадлежащие компании Google можно смело помечать опасными.

Случаи, реальных, но нежелательных или непонятных ботов. То-есть, мы, в результате анализа какой-то аварии, либо анализа логов доступа, либо еще как-то обнаруживаем бота с именем в агенте. В зависимости от поведения такого бота на вашем сайте мы помечаем все его IP в автоматическом или в ручном режиме и имеем его ввиду. Например, можно запретить ему доступ на некоторые страницы вообще. На странице поиска товара из каталога магазина по сложному фильтру вообще ни одному роботу, какой бы он ни был, на мой взгляд, делать нечего.

Есть еще идея помечать IP всех клиентов, у которых вообще нет заголовка HTTP_USER_AGENT. Довольно мала вероятность того, что простой и честный пользователь будет удалять этот заголовок или как-то еще манипулировать им. Остается, правда вариант неграмотной настройки или технического сбоя на стороне клиента. Так что я сам не помечаю и не планирую помечать IP с отсутствующим юзер-агентом. Но раздумываю над тем, чтобы как-то обращать на них внимание, все-таки.

А были ли в моей практике случаи попыток подсадки шелла через агент? Да! был один раз агент с кодом для подсадки шелла. Но опять же, велика вероятность того, что делалось это в качестве опыта каким-то определенным физическим лицом с обычного IP адреса. И были агенты со странным содержимым. Вот таким, например: "() { :; }; echo Content-type:text/plain;echo;echo;echo M`expr 1330 + 7`H;/bin/uname -a;echo @". Затрудняюсь, правда, сказать, что это, и как этим можно воспользоваться.


Определение робота по содержимому других заголовков


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

Виртуальные js-браузеры имеют обычно нормальные заголовки, к которым не придерешься. Их по заголовкам от людей, наверное и не отличить.


Вызов скрипта с расширением php


Представляется полезным полный, 100%-ый уход от расширений. Тогда запрос страницы с расширением php будет сигнализировать нам о приходе робота, причем скорее всего нежелательного.

Исковерканные или неполные запросы, в том числе запросы без финального слэша, если он требуется


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

Но есть реально исковерканные запросы, в которых встречается двойной слэш. С ним я долго думал, что делать. И в конце концов решил их не исправлять и не редиректить. Мне кажется, что вряд ли это будет человек. Как вариант можно на такие запросы выдавать специальную страницу 404 с предложением проверить наличие двойного слэша в адресной строке и исправить.

Встречаются запросы, недоделанные, например, состоящие из половины, например, "/some-category/arti" вместо "/some-category/article/12345/". К сожалению, этим грешат и «хорошие» боты, так что если и помечать таких клиентов в качестве «подозрительных», то только в ручном режиме.

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

Запросы, в которых имя скрипта url-декодировано


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

Несовпадение метода доступа


На сайте обычно могут быть случаи, когда метод доступа к скрипту должен быть строго определенным. Например, не может быть человеческой ошибкой вызов скрипта, обрабатывающего форму методом GET, когда ожидаются параметры, передаваемые методом POST. Либо вызов ajax-бэкенда методом GET.

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

Прямой вызов ajax бэкенда


Суть в том, что на сайте могут быть скрипты, которые вызывают другие скрипты и никогда не вызывает человек путем ввода адреса этого скрипта в адресную строку браузера. Для ловли на этот метод, скрипты ajax-бэкендов должны быть отдельными. Это не должен быть файл index.php с кучей параметров. К сожалению, отдельные скрипты ajax-бэкендов реализованы далеко не всегда и не везде. У меня реализован такой подход, и я отлавливаю описываемые случаи, но еще ни одного события я не поймал.

Запросы, похожие на инъекции и вскрытие файлов через параметры


С переходом на ЧПУ (SEO-ссылки), или просто урл-рерайтинг с целью спрятать параметры страницы, сделали эти атаки экзотическими. Довольно маловероятно в урле "some-site.com/12345/" ввести инъекцию вместо "12345" и получить что-то вменяемое. Наверное, поэтому такие опыты стали все реже происходить. Кроме того, такими вещами в моей практике занимались отдельные, но реальные физические лица со своих реальных IP адресов, например, с 3g модема. Так что большой вопрос, стоит ли их помечать. Кстати говоря, еще не так давно, всего года три назад, IP адреса мобильных сетей были очень сильно скомпрометированы (сейчас не знаю). Просто было сложно работать. Сам мучился с сетью Yota и МТС.

Анализ POST параметров страницы на подозрительные слова и символы я пробовал реализовывать и, в конце концов, отказался от него. Такой анализ стал слишком сложным и, следовательно, затратным по ресурсам. В итоге я уменьшил список подозрительных слов в параметрах до одних только кавычек, а это уже вообще показалось мне анекдотичным. Кроме того, параметры страницы все равно фильтруются, а отличить опасные кавычки от безопасных трудновато для анализа, который должен быть моментальным.

Вопросы производительности



К вопросу пометки клиентов надо подходить с большой осторожностью. В погоне за анализом запросов можно не разогнать, а окончательно заморозить сайт. Я анализом занимаюсь, но делаю это только в случае "плохих ури", то есть таких, которые не представляют собой ни одной реальной страницы и не могут быть показаны. То есть, анализ клиента является составной частью вывода страницы 404. И даже в этом случае я стараюсь не слишком загружать сервер. При использовании регулярных запросов, особенно если они собраны в массив и применяются в цикле, предпочтение приходится отдавать самым простым и быстрым. При обращении к базе данных стараться делать все операции в одном запросе. Ну и другие возможные методы оптимизации кода. Если операцию нельзя достаточно ускорить, то я оставляю ее для ручного просмотра.

Если IP адреса клиентов не только помечаются, но еще и блокируются


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

При проверке IP адреса на заблокированный, лучше, наверное, не искать адрес в общей таблице с тысячами адресов, а иметь отдельную табличку только одних заблокированных IP и искать по ней. Скорость поиска MySQL запроса довольно сильно зависит от количества записей. При поиске в базе данных стараться делать такие запросы, чтобы поиск шел не по данным с помощью индекса, а по одному только индексу.

Можно было бы попробовать искать заблокированные IP вообще не в базе. Есть мысль иметь на диске файл с сериализованным массивом заблокированных IP адресов. Тогда каждый скрипт читает файл, переводит сериализованную строку в массив и работает с ним. Есть подозрение, что такой метод доступа будет быстрее, чем обращение и поиск по базе данных. Но это надо проверять, а для моего сайта это не так важно ввиду его умеренной активности.

Список накопленных плохих ури и помеченных IP


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

  • В таблице учитываются ури в разрезе доменов
  • Каждые сутки таблица пополняется на 100-300 записей. База растет очень быстро и мне приходится ее чистить. Некоторые похожие друг на друга ури я сокращаю и перекачиваю в так называемую сводную таблицу. При этом теряется информация о клиенте, который этот ури вызвал. Но лично мне эти ури не нужны вообще. Я их сначала вообще смотрел и удалял. Потом стал хранить, только чтобы показать кому-нибудь, кому это было бы интересно. Практическая польза от плохих ури для меня не очень ясна.

    Процесс сокращения ури представляет собой нечто следующее: Например, есть частый ури вида "/some-page/12345/", где "12345" является изменяемой частью. Тогда все такие ури, их может быть очень много, сокращаются до "/some-page/###/". А если изменяются не цифры, а буквы, то тогда сокращенный ури может выглядеть "/some-page/ABCD/" или вообще "/some-page/_any_trifle_/".
  • Сервис находится в процессе постоянного развития. Чуть позже, в пределах недели, планируется сделать свободную раздачу (скачивание) помеченных IP адресов.
  • Сервис имеет недостатки. Так, например, не запоминается момент последнего плохого события для IP. Это весьма существенный недостаток, который не позволяет снимать отметку опасности IP по давности последнего плохого события. Также не реализован сервис пользовательской мануальной пометки IP в качестве хорошего.
  • В настоящее время выложен только лог плохих ури и сводый лог. Я собираюсь сервис совершенствовать.


Пожалуйста, не заходите на мой сайт по указанным в сервисе плохим ури! В этом случае ваш IP может быть помечен плохим. Если хотите проверить работоспособность сервиса, введите нейтральный несуществующий ури, типа /adfsadf/. Тогда IP попадет в список, но не будет помечен плохим.
Tags:
Hubs:
-4
Comments 11
Comments Comments 11

Articles