Использование собственной OC при выделенном сервере или VDS дает намного больше возможностей эффективно бороться с подбором паролей к админке WP и со спамом в комментариях. Довольно простая утилитка fail2ban под linux поможет существенно снизить нагрузку на сервер, когда уютненький WP-сайтик долбят толпы Хрумеров (или еще какой гадостью) через сотню-другую проксей.

Как я уже писал ранее, в последние годы сайтами я не занимался, но приходилось часто ковыряться в настройках серверов и VDSок. Кстати, пару месяцев назад съехал с выделенного сервера на три VDS от DigitalOcean, по причине малой надежности (HDD начал сбоить), а также существенной экономии. К посту это не относится, но за счет всех этих переездов я получил шапочный скилл по настройке веб-серверов, а также решение проблем, связанных с сильной нагрузкой, с ДДОСами, подборами паролей и прочей веселухой.

Классика жанра — анти-спамерский плагин Akismet — хорош в том случае, когда у вас идет небольшой поток спама, где-то до нескольких тысяч спам-сообщений в сутки. Данный плагин никак не снижает нагрузку, ведь комментарий должен быть сначала написан, отправлен и обработан, чтобы Akismet понял, что это спам. Другие плагины, основной метод которых заключается в показе каптчи, уже некоторым образом снижают нагрузку — не происходит записи комментария в БД, а лишь дергается php-скрипт, проверяющий правильность ввода каптчи. Хотя, это тоже зависит от реализации плагина. Примерно также работают и большинство (если не все) других анти-спам плагинов.

В поисках правильного я потратил некоторое время и думал, что нашел такой, называется он просто — Anti-spam. Когда плагин понимает (js, еще что-то, не знаю), что идет попытка оставить спам-коммен, он отдает клиенту 500-ю ошибку. Казалось бы, круто, никаких вам каптч и лишних вызовов скрипта. Нагрузка действительно немного снизилась, но не настолько, чтобы вернуться к прежним показателям. Поковырявшись, я понял, что даже этот плагин использует php-интерпретатор и отдает 500 ошибку посредством php-фунции. Таким образом, при достаточно активной атаке спамеров (от 5 запросов в секунду и больше) у меня кончалось количество дочерних процессов php. Нужно было другое решение, на уровне nginx или системы.

На другом сайте, тоже WP, возникла похожая, но другая проблема: кто-то очень активно долбился в админку. Сначала с двух IP, которые были забанены вручную, затем подключив уже хорошую базу проксей. И снова я вначале обратился к WP-плагинам, попробовав Rename wp-login.php. Плагин меняет путь к админке на любой, который вам захочется. Действительно, теперь все попытки ботов авторизироваться попадали на теперь уже несуществующую страницу. Проблема в том, что эта страница обрабатывалась WP, то есть, загружался весь его движок. Таким образом, нагрузка немного снизилась, но по-прежнему была высока. Нужно блокировать плохих парней, не используя PHP.

Внимательный просмотр лог-файлов помог мне найти решение. Спамеры обычно не утруждают себя полностью имитировать действия клиентского браузера, и отправляют сразу POST-данные скрипту, отвечающему за авторизацию (/wp-login.php) или отправку комментария (/wp-comment-post.php). В логах это выглядит так:

wp-login

Решение оказалось достаточно простым. Есть такая тулза fail2ban. Ставим:

apt-get install fail2ban

Суть работы проста. Она мониторит log-файлы различных служб и при совпадении заданного шаблона с записью блокирует IP через iptables на определенное время. Там можно много чего менять и настраивать, мы же перейдем непосредственно к решению вышенаписанных проблем. Фильтры, применяющиеся к логам, находятся в папке /etc/fail2ban/filter.d, где мы и создаем наш новый фильтр, обозвав, скажем, wp-ddos.conf:

vim /etc/fail2ban/filter.d/wp-ddos.conf

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

[Definition]
failregex = .*POST (/wp-comments-post\.php|/wp-login\.php)

Важно! Эта регулярка будет отличаться, если у вас другой формат log-файла. По идее, если формат не менялся, то должна заработать. Неправильное регулярное выражение может привести к тому, что будут баняться все IP, которые засветились в лог-файле!

Далее настраиваем саму тулзу, что делать с плохими парнями. Открываем jail.conf:

vim /etc/fail2ban/jail.conf

Прописываем в конец:

[wp-ddos]
enabled = true
port = 80, 443
filter = wp-ddos
logpath = /var/log/nginx/site.ru/access.log
bantime = 36000

logpath — путь к лог-файлу, который fail2ban будет парсить, filter — тот, что мы прописывали шагом ранее, bantime — время бана в секундах (у меня 10 часов)

Перезагружаем сервис:

/etc/init.d/fail2ban restart

Ждем несколько минут и смотрим результат:

vim /var/log/fail2ban.log

fail2ban_works

Красота! :)