Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
stop-bots — Автоматизируйте блокировку доступа вредоносных ботов к вашему серверу | Kitploit
Инструменты/GitHubGitHub/ivankovic/stop-bots
Оборонительные ИнструментыАудит конфигурацииСбор информацииВеб-безопасностьСетевая безопасностьУтилиты и фреймворкиОбнаружение ВторженийАнти-БотАнализ Журналов
GitHubivankovic/stop-bots

stop-bots

Автоматизируйте блокировку доступа вредоносных ботов к вашему серверу

121 день назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Репозиторий
Поделиться

Stop Bots

CI crates.io Coverage MSRV License: AGPL v3+

TUI, веб-интерфейс и CLI, которые помогают настроить сервер для блокировки нежелательных ботов без необходимости прятаться за CDN.

Он работает вместе с NGINX и вашим существующим межсетевым экраном (iptables или nftables), на двух отдельных уровнях:

  • Конфигурация NGINX. — Он классифицирует известных ботов по категориям (сканеры, поисковые системы, AI-краулеры) и блокирует или разрешает их, внедряя правило в конфигурацию вашего сайта. Он сканирует лог NGINX для динамического обнаружения ботов и блокирует их, даже если ни один набор правил их пока не отслеживает.
  • Скрипт межсетевого экрана. — Блокируйте целые страны, диапазоны IP дата-центров, известные диапазоны IP ботов или любой IP-адрес, который неоднократно пытается неудачно войти на ваш сервер.

Панель управления stop-bots: системные категории ботов, геоблокировка, автоматические детекторы и внутренний cron

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

Установка

Из crates.io:``` cargo install stop-bots

root@kitploit:~
Или соберите из рабочей копии:```
cargo install --path .

Предварительно собранный бинарник x86_64 для Linux доступен на GitHub в разделе releases.

Зависимости

Для сборки требуется Rust 1.88 или новее. На практике только Linux: программа вызывает systemctl, nginx -t и nft/iptables, так что хотя она и компилируется на других платформах, пользы там от неё будет немного.

Использование

Запустите бинарник без аргументов, чтобы открыть TUI, stop-bots web — для тех же экранов в браузере (см. Веб-интерфейс), или stop-bots --help — для полного списка подкоманд CLI. TUI и CLI можно использовать вместе. Настройте всё в TUI, а затем используйте CLI в crontab, чтобы поддерживать правила в актуальном состоянии.

Выйти из приложения или закрыть всплывающее окно/подменю можно клавишей 'q' или Escape.

Тема

Переключаться между тёмной и светлой темой можно клавишей 't'. Приложение попытается автоматически определить тему, но для некоторых комбинаций терминала и мультиплексора доступной информации недостаточно, чтобы сделать правильный выбор.

Экраны

1–4 (или d/b/s/p) переходят сразу к нужному экрану; Left/Right или их vim-алиасы h/l переключают их по порядку; ? в любой момент открывает полный справочник по привязкам клавиш, а : открывает палитру команд со списком всех действий по названию. Tab / Shift+Tab всегда перемещают между панелями текущего экрана, никогда между экранами.

Dashboard владеет всем, что попадает в firewall script; Site settings владеет всем, что попадает в NGINX config. Это разделение определяет, где живёт та или иная настройка.

  • Dashboard (экран по умолчанию): общесистемные настройки категорий по умолчанию (Scanners / Search Bots / AI Bots — Allowed или Blocked); геоблокировка на уровне хоста (блокировка или allow-list конкретных стран); панель "Automatic blocking" с переключателем вкл/выкл для каждого детектора и каждого стороннего блок-листа; панель "Firewall script" (сколько правил запишет рендер, устарел ли скрипт на диске и из каких сайтов и списков ботов он отрендерен); панель "Scheduled", показывающая задания внутреннего cron и когда они последний раз выполнялись (со спиннером рядом с любым заданием, выполняющимся в данный момент в фоне); и Log того, что приложение делало последним. Полоса статуса под вкладками показывает проверки состояния хоста на каждом экране. Up/Down перемещают между тремя списками; m переключает режим геоблокировки. Нажмите F, чтобы отрендерить текущие правила firewall в скрипт — во всплывающем окне также есть переключатель "apply after writing" (Space) для немедленного применения, вместо применения вручную afterward. Ещё три клавиши действуют на весь хост: u скачивает все списки, a применяет обе плоскости (NGINX, затем firewall), а w ставит эту консоль за NGINX — те же три, что в браузере представлены кнопками и панелью.
  • Bot settings: перечисляет все известные источники списков ботов (с действием для их обновления) и каждого отдельного бота, с поиском по имени, с переопределением для каждого бота (Allowed / Blocked / следовать категории по умолчанию).
  • Site settings: панель "NGINX settings" (Tab для фокуса на ней), содержащая общехостовые настройки, формирующие генерируемый конфиг — что получает заблокированный запрос в ответ (см. ниже), нужно ли отдавать сгенерированный robots.txt, и ограничение скорости — над каждым сайтом NGINX, обнаруженным на диске, каждый со статусом "up to date / stale / not found" в реальном времени и действиями для применения текущей политики к одному сайту или ко всем сразу. Изменение любой из этих настроек переводит каждый применённый сайт в STALE, что служит сигналом к повторному применению. Открытие сайта позволяет переопределить его политику категорий/ботов, включить любое из шести правил формы запроса и перечислить пути, исключённые из блокировки.
  • Dynamic Protection: живое, действенное представление того, что сейчас атакует сервер — "Top IPs attempting SSH connection" и "Top User Agents", каждый ранжирован по количеству и помечен NOT BLOCKED/BLOCKED (показано красным). Tab/Shift+Tab переключают, к какой из двух панелей применяются Up/Down; f циклически переключает общий фильтр (all / not blocked only / blocked only); Enter блокирует выбранную строку NOT BLOCKED или разблокирует её, если она уже BLOCKED. i инспектирует выбранный адрес: какие из репутационных фидов его содержат, находится ли он внутри опубликованного диапазона краулера (что и отличает настоящий Googlebot от user agent, который лишь заявляет себя таковым), к какой стране он принадлежит и под какими учётными записями он пытался войти. Всё это из списков, которые хост уже скачал — здесь нет обратного DNS или whois-запроса, потому что PTR-запись пишется тем, кто владеет адресом, и была бы предоставленным атакующим текстом, читающимся как авторитетный.
  • Help: полный справочник по привязкам клавиш.

Bot settings, где живёт каждый источник списков и каждый отдельный бот:

Bot settings: три источника списков ботов с их количеством и поиск, совпадающий с пятью ботами по категориям

Site settings, где общехостовые настройки NGINX расположены над каждым сайтом, найденным на диске:

Site settings: ответ на блокировку, robots.txt и ограничение скорости, над двумя сайтами с метками UP TO DATE и STALE

Dynamic Protection, живое представление того, что атакует сервер прямо сейчас:

Dynamic Protection: неудачные SSH-логины и топ user agents, каждая строка помечена BLOCKED, BLOCKLIST или NOT BLOCKED

От чего это на самом деле защищает

Использование конфига NGINX

  • Известные боты, по категориям (scanner / search engine / AI crawler), из ArcJet's Well-Known Bots, ai.robots.txt и списка NGINX Ultimate Bad Bot Blocker. Блокировка категории внедряет правило if ($http_user_agent ...) в конфиг NGINX каждого сайта (apply-blocks / a/A в Site settings).

  • Слишком много запросов, через собственное ограничение скорости NGINX. В отличие от всего остального здесь, это применяется NGINX во время запроса, а не путём анализа лога после. По умолчанию выключено: лимит, настроенный под неправильный сайт, отваживает реальных посетителей.

  • Вежливо, сначала — опционально генерируемый robots.txt со списком всех ботов, которых вы блокируете, для краулеров, которые его соблюдают, плюс путь-приманка ниже. По умолчанию выключено, потому что он заменяет то, что ваш сайт отдаёт по /robots.txt сегодня.

  • Кроме случаев, когда вы указали иначе — исключения путей для каждого сайта, чтобы можно было блокировать AI-краулеров везде, кроме /blog.

  • Запросы, не похожие на браузер, для каждого сайта. Шесть независимых правил, каждое со своим переключателем и каждое по умолчанию выключено — по одному переключателю на правило, чтобы если что-то ваше перестанет работать, вы могли определить, какое правило это сделало:

    Ко всем ним применяются две меры предосторожности, и они принудительно соблюдаются, а не оставлены на вас:

    • Два правила, зависящих от TLS, записываются только в HTTPS-блоки server. Браузеры не используют HTTP/2 без TLS, поэтому на простом блоке listen 80 каждый запрос — HTTP/1.1, включая редирект, который браузер делает на пути к HTTPS. Ваши блоки для порта 80 и порта 443 обычно делят server_name, поэтому настройка достигает обоих; только TLS-блок получает эти правила. Правила формы заголовков работают поверх простого HTTP и записываются в оба.
    • /.well-known/ всегда исключается, как только включено любое правило. Именно там Let's Encrypt забирает свой HTTP-01 challenge, по HTTP/1.1 без Accept и часто без User-Agent — без этого исключения ваш сертификат перестанет обновляться через несколько недель.

Что на самом деле получает заблокированный запрос

Один общехостовый выбор в Site settings. Это не взаимозаменяемые коды состояния — каждый говорит что-то своё, и разница важнее всего для клиентов, которых вы не хотели поймать:

ОпцияДля чего она
403 Forbidden (по умолчанию)говорит, что блокировка была намеренной; единственная, на которую ошибочно пойманный человек может отреагировать
404 Not Foundскрывает, что что-либо вообще было заблокировано
410 Goneпросит благовоспитанных краулеров удалить URL навсегда — предпочитайте это 403, когда вы отваживаете краулеров, а не атакующих
429 Too Many Requestsговорит вежливому клиенту отступить и повторить попытку
418 I'm a teapotшутка из RFC 2324. Работает; просто не зарегистрирована в IANA, и NGINX отправляет её с пустым телом
444 close connectionвообще без ответа; самый дешёвый, но неотличим от недоступного сервера
Tarpitотвечает 403, но выдаёт тело по одному байту в секунду, так что клиент ждёт, вместо того чтобы двигаться дальше

Tarpit — самый мягкий вариант при ложном срабатывании: ошибочно пойманный клиент замедляется, а не отклоняется — и самый жёсткий по стоимости для бота, чьё соединение простаивает. Два момента, которые нужно знать перед его выбором: он удерживает одно из ваших worker-соединений на всё это время тоже, так что поток tarpit-клиентов конкурирует с реальными посетителями за worker_connections; и то, как долго он на самом деле длится, зависит от того, как NGINX решит записать небольшое тело ошибки, что отмечено в TODO.md как требующее проверки на реальном сервере.

Из ваших логов, автоматически

Каждый из них — независимый переключатель на панели "Automatic blocking" в Dashboard, и каждый добавляет временную блокировку firewall, которая истекает сама и добавляется заново, если поведение продолжается.

Они работают по внутреннему таймеру, который перечитывает ваши SSH- и NGINX-логи доступа каждую минуту — но только пока запущен TUI или веб-интерфейс. Любой из них поддерживает то же расписание, в той же базе данных, так что оставить веб-интерфейс запущенным достаточно; ничего не обнаруживается, когда не запущен ни один. Для сервера, на котором вообще нет процесса stop-bots, см. Unattended, from cron ниже.

  • SSH- и веб-сканеры: IP с кучей неудачных SSH-логинов или множеством различных путей, отдавших 404. Никогда — IP с недавним успешным SSH-логином или находящийся внутри опубликованного диапазона известного краулера.
  • Поддельные краулеры: всё, что заявляет себя как Googlebot, Bingbot или GPTBot с адреса, который оператор этого краулера не публикует. Самая дешёвая распространённая маскировка, и опубликованные списки CIDR её разрешают. Неактивно, пока эти списки действительно не скачаны.
  • Поиск открытых секретов: один запрос к /.env, /.git/config, /wp-config.php и подобным сам по себе является решающим, так что порог здесь не нужен. Встроенный список намеренно опускает пути, которые где-то легитимны — /wp-login.php, /wp-admin/, /xmlrpc.php, /phpmyadmin — поскольку заблокировать собственного администратора было бы хуже, чем пропустить сканер, которого детектор 404 всё равно поймает. Добавляйте свои через set-probe-paths.
  • Honeypot: путь, опубликованный только как Disallow: в сгенерированном robots.txt и нигде не связанный. Достичь его означает проигнорировать robots.txt, чего ничто легитимное не делает случайно — самый сильный сигнал здесь и самая длинная блокировка. Для работы требует включённой генерации robots.txt.

Ещё три смотрят на то, как клиент ведёт себя, а не на то, что он запрашивает. Все три по умолчанию выключены, потому что у каждого есть ложное срабатывание, которое он не может исключить сам по себе — и все три исключают проверенных краулеров поисковых систем, которые иначе совпали бы с каждым из них:

  • Не загружает ресурсы: много различных страниц и ни одной таблицы стилей, скрипта или изображения. Браузеры загружают то, что идёт вместе со страницей. Не поймает API-клиента (он считает различные пути, а API-клиент обращается к немногим) или хорошо закэшированного возвращающегося посетителя (304 считается загруженным ресурсом). Не поможет на сайте, который вообще не отдаёт ресурсов — чистом JSON API.
  • Ротация user agent: несколько личностей с одного адреса. Значительно ослаблено NAT: шлюз оператора связи, кампуса или офиса представляет множество реальных браузеров на одном IP, и без разбора временных меток нет способа отличить это от одного скрапера, циклически меняющего агентов.
  • Краулинг без referer: много различных глубоких страниц, никогда Referer. Ослаблено Referrer-Policy: no-referrer и инструментами приватности; порог по различным путям — это то, что вообще делает его пригодным.

По адресу

  • Целые страны, через агрегированные списки CIDR от IPdeny — блокируйте конкретные страны или переключитесь в режим allow-list и блокируйте всё остальное.
  • Известно плохие адреса, через сторонние списки: FireHOL level 1, Tor exit nodes и blocklist.de. Все по умолчанию выключены.
  • Целые хостинг-провайдеры: AWS, Google Cloud и DigitalOcean публикуют своё адресное пространство, и жилые посетители не просматривают из него. Это грубые инструменты, и они помечены как таковые — они блокируют каждого посетителя, размещённого там, включая VPN-эндпоинты, корпоративный egress и API-клиентов, а не только ботов. По умолчанию выключено, с предупреждением при включении.
  • Соседние адреса, опционально: когда несколько адресов в одном IPv4 /24 помечены в одном проходе, блокируется /24. По умолчанию выключено — блокировка 256 адресов из-за трёх плохо себя ведущих — это сопутствующий ущерб по замыслу. (IPv6 отличается и не требует переключателя: обнаружение всегда блокирует /64, потому что /64 — это одна LAN, то же самое, что представляет один IPv4-адрес. Блокировка единственного адреса, который случилось использовать IPv6-атакующему, ничего бы не остановила — у него есть ещё 2^64.)
  • Всё остальное, вручную — добавьте правило allow или block для IP/CIDR напрямую или используйте экран Dynamic Protection, чтобы навсегда заблокировать конкретный IP или user agent, который вы заметили, прежде чем он вообще пересёк автоматический порог.

Это действительно работает?

Всё вышеперечисленное — сгенерировано. В силе ли что-либо из этого — отдельный вопрос, и stop-bots status — тот, кто на него отвечает:``` stop-bots status

root@kitploit:~
Семь проверок, и первая — та, ради которой всё это стоит делать: действительно ли сгенерированные правила находятся в ядре, или только на диске? Реальный хост проработал три недели с 48 860 правилами drop в `/etc/stop-bots/firewall.nft` и пустым набором правил, потому что написание скрипта и его загрузка — это два шага, и никто никогда не смотрел на второй.

Остальные: переживёт ли набор правил перезагрузку (включён ли `nftables.service`?), соответствует ли скрипт по-прежнему правилам, применены ли блоки NGINX, запускает ли консольная служба тот бинарник, который она называет, есть ли место для базы данных и могут ли детекторы читать свои логи.

Он завершается с ненулевым кодом, если что-либо **CRITICAL**, поэтому работает как проверка мониторинга. `--quiet` выводит только то, что требует внимания, — это форма для cron:```
0 * * * * /usr/local/bin/stop-bots status --quiet

Проверка, которая не смогла выполниться — nft list требует root — сообщает UNKNOWN, а не OK. Проверка состояния, которая говорит, что всё в порядке, потому что не смогла посмотреть, хуже, чем её отсутствие, потому что ей верят.

Тот же отчёт есть на Dashboard как в консоли, так и в TUI, снимается ежечасно внутренним cron, а не при каждом рендере: nft list на большом наборе правил — это мегабайты текста.

Ничего не происходит без вас

Каждое решение по фаерволу выше генерируется, но никогда не применяется автоматически: render-firewall (или клавиша f на Dashboard) записывает скрипт iptables или nftables, чтобы вы сами его просмотрели и применили, и отказывается записывать такой, который заблокировал бы текущую подключённую SSH-сессию.

Применить его за вас могут три вещи, и все три требуют вашего запроса: попап рендера в TUI ("apply after writing") или его клавиша a, панель фаервола веб-консоли ("run it after writing") или её кнопка "Apply everything", и batch --apply из crontab, который написали вы — см. Unattended, from cron. Ни одно из них не является побочным эффектом чего-либо автоматического: внутренний cron рендерит скрипт и никогда его не запускает.

То же самое касается стороны NGINX: изменение настройки меняет лишь то, что было бы записано. Настройки сайтов показывают каждый сайт как STALE, пока вы не примените.

Отключение детектора никогда не удаляет блокировки, которые он уже добавил — они истекают сами. "Stop detecting" и "undo what was detected" намеренно разделены; второе — это экран Dynamic Protection или remove-firewall-rule.

Есть также простой подсчёт по access-логам, независимый от блокировки: record-access-stats / list-access-stats считают, как часто каждый user agent появляется в успешных (не ошибочных) запросах, так что вы видите, кто на самом деле посещает сайт, помимо того, кто блокируется.

Unattended, from cron

stop-bots batch — это один проход по всему, что TUI делает вручную: обновить каждый список, просканировать логи, записать правила блокировки NGINX и скрипт фаервола.```

One full pass a night. Refreshes the lists, scans the logs, applies both.

0 4 * * * root /usr/local/bin/stop-bots batch --apply --ssh-log /var/log/auth.log

And detection every ten minutes, without re-downloading lists that change weekly.

*/10 * * * * root /usr/local/bin/stop-bots batch --apply --no-fetch --ssh-log /var/log/auth.log

root@kitploit:~
Он ничего не сообщает, когда всё сработало, поэтому успешный ночной запуск не отправляет вам письмо. Неудачный
шаг выводит сообщение в stderr и устанавливает ненулевой код завершения — именно поэтому cron сообщает вам
об этом. Сначала запустите его вручную с `--verbose` — это выводит по строке на каждый шаг и является
самым простым способом увидеть, что он на самом деле делает.

**Именно `--apply` заставляет его что-либо применять.** Без него `batch` записывает конфигурацию NGINX
и скрипт брандмауэра и останавливается: конфигурация ничего не делает до перезагрузки, скрипт ничего не делает
до его запуска. Это поведение по умолчанию для этого проекта везде, и здесь оно остаётся поведением по умолчанию.

`batch` и долго работающий фронтенд безопасно сосуществуют. TUI, веб-интерфейс и `batch` —
все записывают то, что они сделали, через одни и те же ключи в одной и той же базе данных, поэтому кто бы ни добрался до задачи
первым, выполняет её, а остальные обнаруживают, что она больше не подлежит выполнению — вы не получаете двух проходов обнаружения, и
панель «Запланированные задачи» на Dashboard показывает то, что действительно произошло, а не утверждает,
что всё просрочено. Если вы уже держите веб-интерфейс запущенным, ночная запись `batch` — это дополнительная подстраховка,
а не необходимость; если нет, это единственное, что поддерживает
обнаружение в актуальном состоянии.

**С `--apply` защита от блокировки SSH может отказать — а отказ означает, что ничего не применяется.**
Она отказывает, если правила заблокировали бы клиента, подключённого прямо сейчас, *и* если ни один журнал SSH
вообще не удалось прочитать, потому что тогда проверка не могла выполниться. Интерактивный
`render-firewall` в этом втором случае лишь выводит примечание, исходя из того, что за терминалом наблюдает человек;
из cron никто не наблюдает. **Передавайте `--ssh-log` явно**: cron работает от имени root, поэтому `/var/log/auth.log` обычно читается
нормально, но на хосте только с journald `journalctl` под cron может вернуть пустой результат — и это ровно тот случай, в котором она отказывает. `--force` переопределяет
защиту, если вы действительно этого хотите.

Отказ одного шага никогда не останавливает остальные, и половины NGINX и брандмауэра независимы —
неудачная перезагрузка NGINX всё равно оставляет брандмауэр применённым, и наоборот.

`batch` записывает каждый шаг в соответствии с тем же расписанием, которое использует внутренний cron TUI, поэтому они
согласуются насчёт того, что уже было запущено, вместо того чтобы делать это обоим, и панель «Запланированные
задачи» на Dashboard показывает то, что сделал ваш настоящий cron.

# Веб-интерфейс

`stop-bots web` обслуживает те же пять экранов в браузере.```
stop-bots web

Он привязывается к 127.0.0.1:8787 — доступен только с этой машины — и выводит сгенерированный пароль один раз, при первом запуске. Получите к нему доступ со своего ноутбука через SSH-туннель:``` ssh -L 8787:127.0.0.1:8787 your-server

root@kitploit:~
затем откройте <http://127.0.0.1:8787/>.

![Панель управления веб-консоли: индикаторы состояния и две кнопки для всего хоста в заголовке, политика, геоблокировка и сторонние фиды в одной колонке, автоматическая блокировка и запланированные задачи в другой](https://assets.kitploit.com/production/public/readmes/55148/73bbcc92f0f3d2c9d0586bd71ad18f1b4d582fa59824b4f5e3c97e08575f5070/bb45db648f6a59192f56b1e14a019f50f0816bff651766316c377cbe79f700b6-display-v1.webp)

Консоль следует светлой или тёмной теме операционной системы, с переключателем в
заголовке; приведённые выше скриншоты TUI — это тёмная тема, а эти — светлая. Клавиши,
которые использует TUI, работают и здесь: `1`–`4` переключают экраны, `/` переводит фокус на поле поиска, `?` открывает справку.

![Страница динамической защиты веб-консоли: неудачные входы по SSH и топ пользовательских агентов, каждый со шкалой количества и тегом состояния, и кнопкой блокировки или разблокировки в каждой строке](https://assets.kitploit.com/production/public/readmes/55148/090d4d2151eb00a69781c44351abe10f268d8031816199b9aeb5b4d2cddfc5f5/52a05387d1227288e7f45ece3c33e4af17957d8e9e73fb7c0213d64c49dc7419-display-v1.webp)

Три действия для всего хоста находятся в заголовке — в браузере в виде кнопок, а в TUI
в виде отдельных клавиш:

- **Обновить всё** (`u`) загружает каждый список ботов, каждый диапазон IP сканеров, каждый
  *включённый* фид репутации и каждую *выбранную* страну — тот же набор, который загружает `stop-bots batch`, по тому же плану. Сбой одного источника не останавливает остальные, и ничего не применяется, пока что-то это не применит.
- **Применить всё** (`a`) записывает и перезагружает конфигурацию NGINX, затем записывает и запускает
  скрипт межсетевого экрана. Эти два уровня независимы: что бы ни отказало, другой всё равно получит
  свой ход, потому что наполовину применённый хост лучше, чем тот, где синтаксическая ошибка NGINX также оставила
  межсетевой экран устаревшим.
- **Веб-доступ** (`w`) настраивает NGINX для обслуживания самой консоли — см.
  [За NGINX](#behind-nginx-a-subdomain-or-a-path-prefix).

## Как служба (Debian)```
sudo stop-bots install web

Записывает /etc/systemd/system/stop-bots-web.service, создаёт /var/lib/stop-bots (0700 — там хранится хеш пароля консоли) и /etc/stop-bots, генерирует пароль, если его нет, и включает и запускает юнит.

--dry-run выводит весь план и ничего не меняет. Это единственная команда в проекте, которая запускает демон, так что начните с неё. --prefix <dir> записывает то же дерево куда-нибудь, где вы можете прочитать его без root. Если юнит уже существует и вы его отредактировали, установщик останавливается и сообщает об этом, вместо того чтобы заменить вашу правку; --force, если вы это имели в виду.

Служба работает от имени root, потому что консоль перезаписывает /etc/nginx, записывает скрипт брандмауэра и запускает nginx -t и systemctl reload nginx. Нет непривилегированного разделения, которое сохранило бы набор функций нетронутым. Юнит несёт в себе ту защиту, которая выживает при этом требовании, и комментарий, объясняющий, какая защита была опущена и почему.

Адрес привязки, список разрешённых хостов и префикс пути намеренно не указаны в юните — работающий сервер перечитывает их из базы данных, поэтому их размещение в ExecStart дало бы им два источника истины. Изменяйте их с помощью stop-bots web --save ... и перезапускайте.

Одна вещь меняется, когда это запускается от имени root: ежедневная задача RenderFirewall внутреннего cron теперь может записывать /etc/stop-bots/firewall.nft, чего она не могла, когда вы запускали консоль вручную от своего имени. Ничто не применяет этот скрипт — его запуск по-прежнему остаётся за вами.

Проверяется только Debian, потому что именно он был протестирован; юнит, скорее всего, корректен на любом дистрибутиве с systemd, но путь к журналу SSH, который он предполагает, — дебиановский.

Его раскрытие

Привязка к чему-либо, кроме loopback, требует второго, намеренного флага, потому что эта консоль может перезаписать брандмауэр и конфигурацию NGINX хоста, на котором она работает:``` stop-bots web --bind 0.0.0.0:8787 --expose --allowed-hosts admin.example.com --save

root@kitploit:~
`--allowed-hosts` на практике не является необязательным: запрос с именем хоста, которого нет
в списке, отклоняется. Именно это делает атаку DNS rebinding на консоль невозможной, и именно
поэтому открытый сервер, к которому обращаются по имени, требует явного указания этого имени.

Разместите его за NGINX с TLS — тем же NGINX, который защищает этот инструмент. Если вы так
сделаете и прокси устанавливает `X-Forwarded-For`, сообщите консоли, что она может доверять этому
заголовку, иначе она не сможет определить, с какого адреса на самом деле пришёл запрос:```
stop-bots web --bind 127.0.0.1:8787   # and set web:trust_forwarded_for

За TLS также установите web:secure_cookie. Без него браузер будет отправлять сессионный cookie и на http:// URL для того же хоста.

web:trust_forwarded_for важнее, чем кажется. Без него каждый запрос за прокси приходит с 127.0.0.1, поэтому консоль не может отличить одного клиента от другого — а это значит, что поток попыток входа делит одно и то же ведро throttle с вами, и защита, которая не даёт вам заблокировать собственный адрес, не с чем сравнивать. С ним и то, и другое работает для каждого клиента отдельно.

За NGINX: поддомен или префикс пути

Консоль может настроить это за вас, как и TUI (w на Dashboard). Оба записывают конфигурацию NGINX, сохраняют префикс пути и добавляют имя хоста в allowlist — три вещи, которые должны согласовываться, потому что отсутствующий префикс заставляет каждую ссылку покидать блок location, а отсутствующее имя хоста делает каждый запрос 403. Оба проверяют с помощью nginx -t перед тем, как конфигурация вступит в силу, откатывают её при неудаче и записывают новый адрес только после успешной проверки.

Два режима, и path является режимом по умолчанию не просто так: он добавляет блок location к сайту, который у вас уже есть, поэтому консоль наследует сертификат этого сайта. Поддомену нужен собственный, и пока не выполнен certbot --nginx -d <host>, форма пароля этой консоли и сессионный cookie передаются по сети в открытом виде.

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

Поддомен — более простое развёртывание, и его стоит выбрать, если у вас есть такая возможность:```nginx server { server_name stopbots.example.com; location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; } }

root@kitploit:~
```yaml
- name: "Test"
  uses: actions/checkout@v4

2. Настройка конфигурации

Создайте файл config.yaml:

root@kitploit:~
# Конфигурация сканера
scanner:
  # Целевые URL для сканирования
  targets:
    - "https://example.com"
    - "https://test.example.com"
  
  # Настройки сканирования
  settings:
    timeout: 30
    threads: 10
    user_agent: "SecurityScanner/1.0"
    
  # Модули для включения
  modules:
    - xss
    - sqli
    - lfi
    - rce
    
  # Настройки вывода
  output:
    format: "json"
    file: "scan_results.json"
    verbose: true

3. Запуск сканирования

root@kitploit:~
# Базовое сканирование
python scanner.py --config config.yaml

# Сканирование с переопределением параметров
python scanner.py --url https://target.com --modules xss,sqli --output results.json

# Сканирование с аутентификацией
python scanner.py --url https://target.com --auth-token "your_token_here"

Расширенное использование

Пользовательские полезные нагрузки

Создайте собственные полезные нагрузки в директории payloads/:

root@kitploit:~
# payloads/custom_xss.py
XSS_PAYLOADS = [
    "<script>alert('XSS')</script>",
    "",
    "<svg onload=alert('XSS')>",
    # Добавьте свои полезные нагрузки здесь
]

Интеграция с CI/CD

Пример интеграции с GitHub Actions:

root@kitploit:~
name: Security Scan

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.9'
    
    - name: Install dependencies
      run: |
        pip install -r requirements.txt
    
    - name: Run security scan
      run: |
        python scanner.py --config config.yaml --output results.json
    
    - name: Upload results
      uses: actions/upload-artifact@v3
      with:
        name: scan-results
        path: results.json

Справочник по API

Класс Scanner

root@kitploit:~
from scanner import Scanner

# Инициализация сканера
scanner = Scanner(
    target="https://example.com",
    modules=["xss", "sqli"],
    threads=10,
    timeout=30
)

# Запуск сканирования
results = scanner.scan()

# Обработка результатов
for vulnerability in results.vulnerabilities:
    print(f"Найдено: {vulnerability.type}")
    print(f"URL: {vulnerability.url}")
    print(f"Серьёзность: {vulnerability.severity}")

Методы

МетодОписаниеПараметры
scan()Запуск полного сканированияНет
scan_url(url)Сканирование одного URLurl (str)
add_module(module)Добавление модуля сканированияmodule (str)
set_auth(token)Установка токена аутентификацииtoken (str)
export(format)Экспорт результатовformat (str)

Устранение неполадок

Распространённые проблемы

Проблема: Сканирование зависает или не завершается

Решение: Увеличьте значение таймаута и уменьшите количество потоков:

root@kitploit:~
python scanner.py --timeout 60 --threads 5

Проблема: Ошибки SSL-сертификата

Решение: Используйте флаг --insecure для пропуска проверки SSL:

root@kitploit:~
python scanner.py --url https://target.com --insecure

Проблема: Ложноположительные срабатывания

Решение: Настройте уровни серьёзности и исключите определённые шаблоны:

root@kitploit:~
scanner:
  settings:
    min_severity: "medium"
    exclude_patterns:
      - "*.css"
      - "*.js"
      - "/static/*"

Участие в разработке

Мы приветствуем вклад в развитие проекта! Пожалуйста, следуйте этим рекомендациям:

  1. Форкните репозиторий
  2. Создайте ветку для функции (git checkout -b feature/amazing-feature)
  3. Зафиксируйте изменения (git commit -m 'Add amazing feature')
  4. Отправьте в ветку (git push origin feature/amazing-feature)
  5. Откройте Pull Request

Стандарты кодирования

  • Следуйте руководству по стилю PEP 8
  • Добавляйте docstring ко всем функциям и классам
  • Включайте тесты для новых функций
  • Обновляйте документацию при необходимости

Лицензия

Этот проект лицензирован под лицензией MIT — подробности см. в файле LICENSE.

Благодарности

  • Спасибо всем участникам проекта
  • Особая благодарность сообществу за сообщения об ошибках и предложения
  • Вдохновлено различными инструментами безопасности с открытым исходным кодом

Контакты

  • Автор: Your Name
  • Email: [email protected]
  • GitHub: @yourusername

Отказ от ответственности

Этот инструмент предназначен только для законного тестирования на проникновение и оценки безопасности. Пользователи несут ответственность за соблюдение всех применимых законов и получение надлежащего разрешения перед сканированием любых систем. Авторы не несут ответственности за любое неправомерное использование или ущерб, причинённый этим программным обеспечением.``` stop-bots web --allowed-hosts stopbots.example.com --save

root@kitploit:~
**Префикс пути тоже работает**, но консоли нужно об этом сообщить — она должна
генерировать каждую ссылку, действие формы, перенаправление и путь cookie уже с
префиксом, и она не может догадаться:```
stop-bots web --base-path /stop-bots --allowed-hosts example.com --save

| --proxy | Прокси-сервер для использования (например, http://127.0.0.1:8080) | | --timeout | Тайм-аут запроса в секундах (по умолчанию: 10) | | --user-agent | Пользовательский User-Agent | | --headers | Дополнительные заголовки в формате Key: Value (можно повторять) | | --cookie | Строка cookie для отправки | | --follow-redirects | Следовать перенаправлениям HTTP | | --verify-ssl | Проверять SSL-сертификаты (по умолчанию: true) | | --threads | Количество параллельных потоков (по умолчанию: 10) | | --delay | Задержка между запросами в секундах | | --output | Путь к выходному файлу | | --format | Формат вывода: json, csv, table (по умолчанию: table) | | --verbose | Включить подробное логирование | | --quiet | Подавить весь вывод, кроме результатов | | --config | Путь к файлу конфигурации |

Примеры

root@kitploit:~
# Базовое сканирование
python3 scanner.py -u https://example.com

# Сканирование со списком URL
python3 scanner.py -f urls.txt --threads 20

# Использование прокси и пользовательских заголовков
python3 scanner.py -u https://example.com --proxy http://127.0.0.1:8080 --headers "Authorization: Bearer token"

# Вывод в формате JSON
python3 scanner.py -u https://example.com --format json --output results.json

# Подробный режим с задержкой
python3 scanner.py -u https://example.com --verbose --delay 1

Конфигурация

Инструмент поддерживает файл конфигурации в формате YAML. По умолчанию он ищет файл config.yaml в текущем каталоге.

root@kitploit:~
# Пример config.yaml
targets:
  - https://example.com
  - https://test.example.com

options:
  threads: 10
  timeout: 10
  follow_redirects: true
  verify_ssl: true
  user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"

headers:
  Authorization: "Bearer your-token-here"
  X-Custom-Header: "custom-value"

output:
  format: json
  path: results.json

Вывод

Инструмент поддерживает несколько форматов вывода:

Формат таблицы (по умолчанию)

root@kitploit:~
+---------------------+--------+---------------------+
| URL                 | Статус | Детали              |
+---------------------+--------+---------------------+
| https://example.com | 200    | OK                  |
| https://test.com    | 404    | Not Found           |
+---------------------+--------+---------------------+

Формат JSON

root@kitploit:~
{
  "results": [
    {
      "url": "https://example.com",
      "status": 200,
      "details": "OK",
      "timestamp": "2024-01-15T10:30:00Z"
    }
  ],
  "summary": {
    "total": 1,
    "success": 1,
    "failed": 0
  }
}

Формат CSV

root@kitploit:~
url,status,details,timestamp
https://example.com,200,OK,2024-01-15T10:30:00Z

Расширенное использование

Пользовательские модули

Вы можете расширить функциональность инструмента, создав пользовательские модули. Каждый модуль должен реализовывать следующий интерфейс:

root@kitploit:~
class CustomModule:
    def __init__(self, options):
        self.options = options

    def run(self, target):
        # Ваша логика здесь
        return {
            "url": target,
            "status": "success",
            "data": {}
        }

Интеграция с CI/CD

Инструмент можно легко интегрировать в конвейеры CI/CD:

root@kitploit:~
# Пример GitHub Actions
name: Security Scan
on: [push]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run scanner
        run: |
          python3 scanner.py -u https://example.com --format json --output results.json
      - name: Upload results
        uses: actions/upload-artifact@v2
        with:
          name: scan-results
          path: results.json

Устранение неполадок

Распространённые проблемы

Проблема: ModuleNotFoundError: No module named 'requests'

Решение: Установите отсутствующие зависимости:

root@kitploit:~
pip install -r requirements.txt

Проблема: Тайм-аут соединения

Решение: Увеличьте значение тайм-аута или проверьте сетевое подключение:

root@kitploit:~
python3 scanner.py -u https://example.com --timeout 30

Проблема: Ошибки SSL-сертификата

Решение: Отключите проверку SSL (только для тестирования):

root@kitploit:~
python3 scanner.py -u https://example.com --verify-ssl false

Режим отладки

Для получения подробной информации об отладке используйте флаг --verbose:

root@kitploit:~
python3 scanner.py -u https://example.com --verbose

Это выведет подробные журналы, включая HTTP-запросы, ответы и внутренние операции.

Участие в разработке

Мы приветствуем вклад в развитие проекта! Пожалуйста, следуйте этим рекомендациям:

  1. Форкните репозиторий
  2. Создайте ветку для функции (git checkout -b feature/amazing-feature)
  3. Зафиксируйте изменения (git commit -m 'Add amazing feature')
  4. Отправьте в ветку (git push origin feature/amazing-feature)
  5. Откройте Pull Request

Стиль кода

  • Следуйте рекомендациям PEP 8
  • Добавляйте docstring к функциям и классам
  • Включайте тесты для новых функций
  • Обновляйте документацию при необходимости

Лицензия

Этот проект лицензирован под лицензией MIT — подробности см. в файле LICENSE.

Благодарности

  • Спасибо всем участникам, которые внесли свой вклад в этот проект
  • Особая благодарность сообществу open-source за их бесценные инструменты и ресурсы

Контакты

  • Автор: Your Name
  • Email: [email protected]
  • GitHub: @yourusername

Отказ от ответственности

Этот инструмент предназначен только для образовательных целей и легального тестирования на проникновение. Пользователи несут ответственность за соблюдение всех применимых законов и получение надлежащего разрешения перед использованием этого инструмента в любой системе. Авторы не несут ответственности за любой ущерб, причинённый в результате использования или неправильного использования этого программного обеспечения.```nginx location /stop-bots/ { proxy_pass http://127.0.0.1:8787; # NO trailing slash proxy_set_header Host $host; }

root@kitploit:~
**Завершающая косая черта в `proxy_pass` имеет значение, и именно её отсутствие — весь трюк.**
Без неё NGINX передаёт полный путь целиком, и `stop-bots` видит
`/stop-bots/whatever`, что он теперь и обслуживает, и генерирует. *С* завершающей
косой чертой NGINX отсекает префикс — и тогда браузер разрешает ссылки на странице
относительно корня домена, выходит за пределы блока `location`, и всё отдаёт 404. Никакая
аккуратность на стороне сервера это не исправит, поэтому префикс должен выжить при
проксировании.

Извне это ничем не принуждается, но сбой получается громким, а не тонким: при
настроенном префиксе запрос без префикса — это обычный 404, а не страница, которая
работает наполовину.

## Чего он не будет делать

Две вещи отсутствуют намеренно, и экран Help сообщает об этом вместе с причинами:

- **Он не разблокирует то, что заблокировал загруженный список** — следующее обновление этого
  списка молча отменило бы это.
- **Он не меняет свой собственный пароль.** Используйте `stop-bots web --set-password` на хосте.

Он также отказывается блокировать адрес, с которого вы подключены, — это отняло бы
консоль, которой вы бы воспользовались, чтобы это отменить.

**Раньше их было три.** Применение скрипта брандмауэра было третьим, на том основании, что
его запуск — единственная операция, способная отключить хост от сети. Теперь это
доступно — «Apply everything» на Dashboard (`a` в TUI), или галочка «run it after
writing» на панели брандмауэра — потому что защита, делающая его безопасным при запуске из cron, делает его безопасным и при
нажатии кнопки: правила проверяются против клиентов, в данный момент подключённых по SSH, в
том порядке, в котором их будет вычислять сам скрипт, и правило, которое заблокировало бы одного из них, — это
отказ, а не предупреждение. Запустите консоль с `--no-apply`, чтобы вернуть прежнее
поведение только для записи.

Попытки входа ограничиваются по частоте. Не потому, что пароль можно угадать — он генерируется,
144 бита — а потому, что его проверка запускает Argon2id, и позволить неаутентифицированному вызывающему
управлять этим так быстро, как он только может отправлять запросы, — это отказ в обслуживании против хоста, который этот инструмент
должен защищать. Десять неверных попыток бесплатны; сверх этого клиент отступает
экспоненциально, а глобальный лимит ограничивает нагрузку на CPU независимо от того, со скольких адресов
приходят попытки.

## Запуск NGINX в контейнере

Если NGINX работает в Docker и его конфигурация находится на bind mount, `systemctl reload nginx` не перезагружает
ничего. Направьте обе команды на контейнер вместо этого — это относится и к CLI, и к
TUI:```
stop-bots set-nginx-commands \
  --test   "docker exec web nginx -t" \
  --reload "docker exec web nginx -s reload"

Команда разбивается на слова и выполняется напрямую. Она никогда не проходит через оболочку, поэтому ;, | и $VAR являются обычными символами, а не синтаксисом.

Участие в разработке

Как устроен код, как он тестируется и по каким правилам написан, описано в CONTRIBUTING.md. Процесс выпуска описан в RELEASING.md.

Контакты

Вы можете связаться со мной по адресу [email protected].

Лицензия

Copyright (C) 2026 Marko Ivankovic

Эта программа является свободным программным обеспечением: вы можете распространять её и/или изменять на условиях GNU Affero General Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, либо (по вашему выбору) любой более поздней версии.

Полный текст Лицензии см. в файле LICENSE.

Не можете использовать AGPL-программы?

Альтернативное лицензирование НЕ доступно.

Скачать инструмент
ПравилоОтклоняет, помимо ботов
HTTP/1.0 и HTTP/1.1краулеры и API-клиенты, не говорящие на HTTP/2
Нет заголовка Acceptнекоторые API-клиенты не отправляют его
Нет Accept-Languageинструменты приватности его удаляют
Пустой/отсутствующий User-Agentскрипты и проверки состояния часто его опускают
Host — голый IPломает доступ к сайту по IP
TLS 1.0 / 1.1только очень старые клиенты