Динамическая блокировка IP-адресов на сайте с высоким трафиком: лучшая стратегия?

#php #performance #apache

#php #Производительность #apache

Вопрос:

У меня есть несколько плохих ботов, нацеленных на мой сайт, и мне нужно динамически обрабатывать IP-адреса, с которых приходят эти боты. Это сайт с довольно высоким трафиком, мы получаем пару миллионов просмотров страниц в день, и именно поэтому мы используем 4 сервера (с балансировкой нагрузки). Мы не используем никакого кэширования (кроме ресурсов), потому что большинство наших ответов уникальны.

Code-технически это довольно маленький веб-сайт на PHP, который не выполняет запросы к базе данных и один XML-запрос на просмотр страницы. XML-запрос получает довольно быстрый ответ.

Я разработал скрипт для (очень часто) анализа того, какие IP-адреса выполняют оскорбительные запросы, и я хочу обрабатывать запросы с этих IP-адресов по-разному в течение определенного периода времени. Оскорбительные IP-адреса часто меняются, поэтому мне нужно блокировать разные IP-адреса каждые пару минут

Итак: я вижу, что IP xx.xx.xx.xx является оскорбительным, я записываю это где-нибудь, а затем я хочу придать этому IP-адресу особую обработку в течение следующих x минут, когда он выполняет запросы. Мне нужно сделать это быстро, потому что я не хочу замедлять работу сервера и заставлять законных пользователей страдать из-за этого.

Решение 1: файл

Запись оскорбительных IP-адресов в файл, а затем чтение этого файла для каждого запроса кажется слишком медленным. Вы согласны?

Решение 2: PHP включает

Я мог бы позволить моему сценарию анализа написать PHP include файл, который затем будет включать движок PHP для каждого запроса. Но: я могу себе представить, что при написании файла PHP многие пользователи, которые сразу выполняют запрос, получают сообщение об ошибке, потому что файл используется.

Я мог бы решить эту потенциальную проблему, записав файл, а затем изменив символическую ссылку (что может быть быстрее).

Решение 3: htaccess

Другим способом отделить нарушителей было бы написать htacces, который блокирует или перенаправляет их. Это может быть наиболее эффективным способом, но тогда мне нужно записывать файл htaccess каждые x минут.

Я хотел бы услышать некоторые мысли / реакции на предлагаемые мной решения, особенно в отношении скорости.

Комментарии:

1. Согласен с вашими 3 решениями. Я предполагаю, что есть четвертый вариант: я обрабатываю это с помощью iptables и fail2ban, а не с помощью ответа php сервера, но не проверял скорость обоих решений. Другим рабочим решением, о котором вы упомянули, является использование «Include /etc/apache2/extra/redirecting_rules» на вашем хост-сервере; Я также не проводил тестирование этого, но это может быть медленнее из-за систематического требуемого доступа к файлам.

2. .htaccess не масштабируется

Ответ №1:

Как насчет динамической настройки iptables для блокировки плохих IP-адресов? Я не вижу никаких причин делать «брандмауэр» в PHP…

Комментарии:

1. Я бы хотел не блокировать IP-адреса, а отправлять их на другую страницу с КАПЧЕЙ или каким-либо другим препятствием для входа. Если законный пользователь обрабатывается таким образом, он все равно может использовать сервис. Плохой бот не стал бы беспокоиться, по крайней мере, я надеюсь.

2. iptables вы можете сделать больше, чем блокировать — вы также можете изменить IP-адрес назначения, т.Е. Перенаправить на другой сервер, если хотите. Также я думаю, что любой приличный балансировщик нагрузки мог бы сделать это и для вас. Мне кажется, что все ваши 3 решения сводятся к чтению файла при каждом запросе, что, вероятно, может быть в порядке, если вы все еще обрабатываете только 20-30 транзакций в секунду, но, вероятно, хорошей идеей будет реализовать что-то более масштабируемое заранее.

3. Выполнение этого на уровне iptables выходит за рамки моей зоны комфорта и моей «юрисдикции» как разработчика. Также я хотел бы максимально контролировать это. Смотрите мой ответ о том, как я это реализовал.

4. Я дал вам принятый ответ, поскольку считаю, что iptables, вероятно, является наиболее эффективным решением, хотя решение, которое я выбрал, на данный момент достаточно эффективно для моих нужд.

Ответ №2:

Для записи я, наконец, решил пойти на (предложенное мной) решение № 2, создав PHP-файл, который включается в каждый запрос страницы.

Полное решение заключается в следующем: скрипт Python анализирует файл журнала доступа каждые x минут и распределяет «наказания» по определенным IP-адресам. Все текущие наказания записываются в довольно маленький (<1 КБ) PHP-файл. Этот PHP-файл включается для каждого запроса страницы. Сразу после генерации PHP-файла запускается задание rsync для отправки нового PHP-файла на другие 3 сервера за балансировщиком нагрузки.

В скрипте Python, который генерирует PHP-файл, я сначала объединяю полное содержимое файла. Затем я открываю, записываю и закрываю файл последовательно, чтобы заблокировать файл на как можно более короткий период.

Комментарии:

1. Я предпочитаю Python для выполнения серверных задач, не связанных с HTML, например, для анализа больших объемов данных.

Ответ №3:

Я бы серьезно подумал о создании другого сервера, который хранит (постоянно меняющийся) список блокировок в памяти и обслуживает интерфейсные серверы. Я реализовал такое решение с помощью Node.JS и нашел реализацию простой, а производительность очень хорошей. также можно использовать memcached, но я никогда не пробовал.