Я надеялся, что Discourse сможет записывать попытки неудачного входа в файл журнала, даже если для этого потребуется дополнительная настройка. Тогда я смогу создать собственный фильтр и правило блокировки (jail) для Discourse.
Я использую централизованный сервер fail2ban. Принцип его работы таков: все мои контейнеры, образы Docker и виртуальные машины используют кастомное действие блокировки.
В fail2ban вы указываете действие, которое нужно выполнить в правиле блокировки, например: action = iptables-allports
Затем вам нужно лишь отредактировать это действие: sudo nano /etc/fail2ban/action.d/iptables-allports.conf
С такой настройкой ваш контейнер/Docker/ВМ будет блокировать нарушителей локально через fail2ban, но также передаст эту информацию на ваш центральный сервер fail2ban. Центральный сервер может собирать все заблокированные IP-адреса и предоставлять их в виде текстового списка блокировок, например: https://fail2ban.YourDomain.com/banned.txt
Затем ваш фаервол pfSense может подписаться на этот список блокировок, и вы даже сможете делиться им с другими роутерами pfSense. Таким образом, если злоумышленник попытается взломать одно приложение, он будет заблокирован во всех остальных. Эта схема отлично работает у меня уже много лет.
И всё, что мне нужно для реализации этого для Discourse, — чтобы Discourse записывал запись в файл журнала при каждой неудачной попытке входа
Логи NGINX
Иногда логи NGINX могут содержать полезные подсказки, они находятся здесь:
cd /var/discourse
./launcher enter app
cd /var/log/nginx
Там будут файлы access.log и error.log, а также множество сжатых ротированных файлов. Команда less access.log.2.gz автоматически распакует и отобразит логфайл.
Эта директория также доступна на хосте по пути /var/discourse/shared/standalone/log/var-log/nginx.
К сожалению, файлы nginx error.log и access.log не фиксируют попытки неудачного входа.
Привет, @Falco, спасибо за ответ. Я сразу же проверил логи: попытка с правильным паролем и попытка с неправильным паролем выглядят для меня одинаково (ответ 200):
(Я обезличил IP-адрес и домен, остальное без изменений)
Поскольку в обоих случаях возвращается ответ 200, использовать это для fail2ban нельзя — вы заблокируете всех пользователей, независимо от того, правильный у них пароль или нет.
Twitter возвращает 400 при неверном пароле, а Facebook, LinkedIn, Google и Amazon возвращают 200. На мой взгляд, 200 звучит неправильно, но, похоже, это «стандартное» поведение?
Может быть, стоит начать с плагина, который подключается к этому методу здесь:
Отлично, спасибо за ответ! Как только у меня появится немного свободного времени, я попробую создать плагин для генерации этой информации! (Мне нужно только, чтобы IP-адрес записывался в файл, когда кто-то пытается войти с неверным паролем, например: неудачная попытка входа с IP 10.111.222.33 )
Я пишу о ролях самоучки-вебмастера и обычного конечного пользователя, но…
Неверный логин по определению — это ошибка 200. Конечно, это может и должно быть внутренней ошибкой приложения, и в какой-то момент генерировать что-то другое, например ошибку 403 плюс, скажем, отправку ссылки для восстановления, но это не должно или не может происходить сразу.
Fail2ban — хороший инструмент, но действительно переоценённый. Давайте забудем про Docker, потому что он всё усложняет, но сам факт, что он может обходить iptables на VPS, для меня действительно загадка. Но боты склонны менять IP после каждой третьей попытки, что делает Fail2ban довольно бессильным против чистого брутфорса через вход.
Скрипт-кидди — это уже другая история, конечно. Они копируют и вставляют всё, что находят, запускают и не возятся с IP-адресами. Тогда Fail2ban может их остановить, хотя они редко могут нанести какой-либо вред, кроме увеличения нагрузки. Настоящая проблема — это количество скрипт-кидди при мгновенном флуде.
Но пока VPS справляется с такой ситуацией, это просто не имеет значения. Сейчас 2023 год, и в основном эти придурки атакуют древние уязвимости WordPress на сайте с Discourse
Но нам всё же нужна какая-то логика для остановки постоянных попыток входа, даже если это не ежедневная угроза, полагаю.