
LLM-first фреймворк обмана: "Ловушка, которая отвечает!™"
# honeyprompt

Представляем `honeyprompt` — ориентированную на LLM обманную среду, созданную веб-разработчиками для веб-разработчиков. Личный проект-увлечение [@alectrocute](https://github.com/alectrocute).
Поддерживает всех крупных облачных и локальных провайдеров LLM. SSH, HTTP, TLS, TCP, telnet и другое. Поставляется в виде небольшого контейнера (и одного статического бинарного файла), а все настройки собраны в одном `honeyprompt.yaml`.
Никаких плагинов для компиляции, никакой базы данных, легко расширяется и может быть развернут на слабом оборудовании.
## Демо-экземпляр
Демо-экземпляр доступен по адресу `172.233.151.216`, с неаутентифицированной веб-панелью здесь:
<http://172.233.151.216:9090>. Это публичный экземпляр honeyprompt, работающий на дешевом VPS от Linode, с `openrouter/free` в качестве единственного провайдера/модели LLM.
## Быстрый старт
Для самой простой настройки в 2026 году мы рекомендуем Docker и OpenRouter/`openrouter/free` в качестве провайдера LLM. Поддерживаются все крупные облачные и локальные провайдеры LLM. Три файла и одна команда поднимают полное развертывание по умолчанию: семь приманок на базе LLM, надежное хранение событий и панель оператора.
**1. Загрузите конфигурацию по умолчанию, файл compose и шаблон .env:**
```bash
# если у вас нет Docker:
# curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
mkdir honeypot && cd honeypot
wget https://raw.githubusercontent.com/alectrocute/honeyprompt/main/honeyprompt.yaml
wget https://raw.githubusercontent.com/alectrocute/honeyprompt/main/compose.yaml
wget -O .env https://raw.githubusercontent.com/alectrocute/honeyprompt/main/.env.example
```
(Или клонируйте репозиторий и перейдите в него — те же три файла.)
**2. Заполните `.env`.** Требуются два значения:
```dotenv
OPENROUTER_API_KEY=sk-or-... # используйте выделенный ключ с лимитом расходов
HONEYPROMPT_PANEL_PASSWORD=changeme # пароль для базовой аутентификации панели
```
**3. Запустите:**
```bash
docker compose up -d
```
**4. Протестируйте:**
```bash
ssh -p 2222 root@localhost # пароль: root — затем введите что угодно
curl http://localhost:2375/v1.54/containers/json # "открытый" API Docker
```
**5. Наблюдайте за происходящим** в панели только для чтения по адресу <http://127.0.0.1:9090> (войдите как `admin` с паролем панели). Каждое подключение, учетные данные и команда транслируются в реальном времени. Если вы развернуты на удаленном хосте, вам нужно будет открыть порт `:9090` в [`compose.yaml`](https://github.com/alectrocute/honeyprompt/blob/main/compose.yaml). Это не рекомендуется для продакшн-развертываний.
> Для продакшн-развертываний используйте пронумерованный релиз вместо `latest` — установите `HONEYPROMPT_IMAGE` в `.env`.
Только что загруженный вами [`honeyprompt.yaml`](https://github.com/alectrocute/honeyprompt/blob/main/honeyprompt.yaml) — это полностью аннотированная демонстрация. Он содержит профили для:
- **Типичного корпоративного веб-сервера** — порт 80, самая широкая сеть; `/` мгновенно отдает стандартную страницу приветствия nginx, а более глубокие пути передаются LLM для генерации полноценных HTML/CSS страниц интрасети, форм входа и панелей администратора, созданных, чтобы удержать атакующего.
- **MCP / агентских шлюзов** — Streamable HTTP обнаружение, метаданные OAuth, вызовы инструментов JSON-RPC и заманчивые производственные инструменты.
- **Docker Engine API 29.5** — неаутентифицированная поверхность порта 2375, используемая реальными облачными червями.
- **Kubernetes API v1.36** — обнаружение пространств имен, рабочих нагрузок, секретов, ConfigMap и RBAC.
- **Инфраструктуры сборки AI на Ubuntu 26.04** — SSH, рабочие нагрузки GPU, Docker, kubeconfigs, состояние CI и учетные данные провайдеров.
- **Redis 8.8** — типичные RESP-зонды, используемые для кражи учетных данных, сохранения состояния и латерального перемещения.
- **Промышленного периферийного / OT оборудования** — намеренно устаревшая плоскость управления Telnet, потому что современная защита все еще должна перехватывать атаки на старую инфраструктуру.
### Запуск без LLM
> [!ВАЖНО]
> Даже если вы используете LLM, определите наиболее часто используемые пути и добавьте для них статические правила. Это сэкономит огромное количество токенов LLM и ускорит ответы на запросы, которые не стоят затрат на вызов LLM. Случайные примеры: `whoami`, проверки работоспособности, favicon, зондирование версий и т.д.
Этот минимальный `honeyprompt.yaml` эмулирует SSH-машину с двумя статическими правилами и без LLM:
```yaml
panel:
enabled: true
address: "0.0.0.0:8080"
events:
buffer: 2000
file: /data/events.jsonl # долговременная активность атакующего
services:
- protocol: ssh
address: "0.0.0.0:2222"
description: "Ubuntu 26.04 LTS build runner"
serverName: "gpu-runner-07"
passwordRegex: "^(root|admin|123456)$" # какие пароли "работают"
commands:
- regex: "^whoami$"
handler: "root"
- regex: "^(.+)$"
handler: "bash: command not found"
```
```bash
docker run --rm \
-p 2222:2222 -p 8080:8080 \
-v "$(pwd)/honeyprompt.yaml:/etc/honeyprompt/honeyprompt.yaml:ro" \
-v honeyprompt-data:/data \
alectrocute/honeyprompt:latest
```
## Развертывание
Для постоянного развертывания используйте прилагаемый [`compose.yaml`](https://github.com/alectrocute/honeyprompt/blob/main/compose.yaml). [Руководство по развертыванию](https://github.com/alectrocute/honeyprompt/blob/main/DEPLOYMENT.md) охватывает выпуски на Docker Hub, необходимые секреты GitHub, настройку портов и брандмауэра, доступ к панели через SSH, обновления, откат, хранение событий и изоляцию.
## Кратко: почему обман на основе LLM
От honeypot требуется только одно: оставаться убедительным достаточно долго, чтобы атакующий продолжал печатать. Каждая выполненная им команда — разведданные: инструменты, к которым он тянется, учетные данные, которые он использует повторно, уязвимости (CVE), которые, по его мнению, вы не исправили. Статические honeypot'ы теряют маскировку, как только кто-то выполняет команду, которую автор не предусмотрел. honeyprompt передает этот момент LLM, поэтому оболочка отвечает на `dmesg | tail` или `cat /etc/shadow` так, как ответила бы настоящая, и сессия продолжается.
Посмотрите отличную презентацию Adel Karimi на DEF CON 32 о Galah, (первом?) LLM honeypot, которая вдохновила этот проект: <https://www.youtube.com/watch?v=XGsm4Qcc_Ag>
## Что логируется: два отдельных потока
Это стоит понять заранее, потому что эти два потока намеренно разделены:
- События обмана: Каждое взаимодействие атакующего: подключения, попытки аутентификации, каждая команда или запрос, ответ, отправленный honeyprompt, какой провайдер и модель ответили, и сколько времени это заняло. Это ваши данные об угрозах. Они хранятся в ограниченном буфере в памяти для панели в реальном времени, и вы можете сохранять все это на диск.
- Операционные логи: Запуск, какие порты были связаны, сбои провайдеров, остановка, внутренние ошибки. Это то, что вы читаете, когда неправильно ведет себя *среда выполнения*. Они не имеют ничего общего с активностью атакующего.
Вы настраиваете их отдельно:
```yaml
# Мед: активность атакующего.
events:
buffer: 2000 # последние события хранятся в памяти для панели
file: /data/events.jsonl # сохраняет каждое событие в формате JSON Lines
# Собственная диагностика среды выполнения.
logging:
level: info # debug | info | warn | error
format: text # как выглядит на консоли: text (человеко-читаемый) или json
file: /data/honeyprompt.log # опционально; на диске всегда JSON
```
`events.jsonl` — это один самодостаточный JSON-объект в строке — готов к `tail -f`, отправке в SIEM или воспроизведению с помощью `jq`. Команды Docker выше монтируют именованный том `honeyprompt-data` в `/data`, поэтому события переживают замену контейнера. Оба файла дополняются и сбрасываются при чистом завершении работы.
`format` влияет только на то, как операционные логи отображаются на консоли; файл операционных логов, если он включен, всегда структурированный JSON для удобства парсинга.
## Веб-панель

Опциональная панель только для чтения транслирует события обмана по мере их возникновения, группирует по протоколу и позволяет экспортировать все в JSON одним кликом:
```yaml
panel:
enabled: true
address: "0.0.0.0:8080"
auth: # опциональная базовая аутентификация
username: admin
password: "${HONEYPROMPT_PANEL_PASSWORD}"
```
Панель — это простой HTML, CSS и JavaScript ([`src/panel/assets`](https://github.com/alectrocute/honeyprompt/blob/main/src/panel/assets)), встроенные в бинарный файл. Оставьте `auth` неопределенным, чтобы отключить аутентификацию.
## Провайдеры
Каждый провайдер — это собственный модуль со своими таймаутами, повторными попытками, ограничениями скорости и заголовками. Ключи берутся из переменных окружения. Из коробки:
| Провайдер | `type` | Примечания |
| ----------------------- | ------------------- | -------------------------------------------- |
| Ollama | `ollama` | Локальные модели; по умолчанию `localhost:11434` |
| llama.cpp | `llamacpp` | Локальная конечная точка `server` OpenAI |
| OpenAI | `openai` | `OPENAI_API_KEY` |
| Azure OpenAI | `azure` | требуется `azure.deployment` + `azure.apiVersion` |
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
| Anthropic | `anthropic` | `ANTHROPIC_API_KEY` |
| Google Gemini | `google` | `GEMINI_API_KEY` |
| Любой OpenAI-совместимый| `openai-compatible` | укажите `baseUrl` на ваш шлюз |
### Балансировка нагрузки и отказоустойчивость
Настройте провайдеров, выберите `pool.strategy` (`round-robin`, `weighted`, `random` или `failover`), и honeyprompt будет распределять трафик между ними. Если выбранный провайдер превышает таймаут или возвращает повторяемую ошибку, honeyprompt прозрачно переключается на следующего — мертвый бэкенд никогда не выводит honeypot из строя. Неповторяемые ошибки (например, неверный ключ API) останавливают каскад, чтобы вы узнали о проблеме, а не тратили квоту молча.
Сервисы используют глобальный пул, если не указывают собственный поднабор провайдеров:
```yaml
llm:
enabled: true
providers: [local-ollama] # одно имя: принудительно использовать этого провайдера для этого сервиса
```
Укажите несколько имен, чтобы сохранить балансировку нагрузки и отказоустойчивость, но только в пределах этого поднабора:
```yaml
llm:
enabled: true
providers: [openai-primary, openrouter-backup]
```
### Именованные пулы
Когда несколько сервисов должны использовать одну и ту же группу провайдеров — или поднабору нужна своя стратегия вместо глобальной — определите **именованный пул**. Пул имеет имя, стратегию и упорядоченный список провайдеров, а сервис ссылается на него по имени в любом месте, где обычно указывает провайдера:
```yaml
pools:
- name: cheap-first
strategy: failover # сначала пробовать локальную модель, при сбое переходить на платный API
order: [local-ollama, openrouter]
- name: spread
strategy: round-robin
order: [openrouter, openai]
services:
- protocol: ssh
# ...
llm:
enabled: true
providers: [cheap-first] # имя пула, вместо провайдера
- protocol: http
# ...
llm:
enabled: true
providers: [spread]
```
Имя пула должно быть единственной записью в `providers` — смешивать пул с отдельными провайдерами в одном списке нельзя, так как было бы неясно, какая стратегия выигрывает. Имена пулов находятся в том же пространстве имен, что и имена провайдеров, и не могут с ними конфликтовать.
## Расширение ответов с помощью хуков
Когда "соответствие регулярному выражению" или "запрос модели" недостаточно, хуки позволяют вставить собственный TypeScript в путь запроса и ответа. Хук может переписать промпт до того, как он попадет к модели, или переписать ответ до того, как он попадет к атакующему.
```ts
import { registerHook } from "./src/engine/hooks.ts";
registerHook({
name: "fake-latency-notice",
transformResponse(response, ctx) {
if (ctx.protocol === "ssh" && /rm -rf/.test(ctx.input)) {
return "rm: cannot remove '/': Operation not permitted\n";
}
return response;
},
});
```
Ссылайтесь на него по имени из списка `hooks:` любого сервиса. Встроенный хук `redact-secrets` включен в пример конфигурации, чтобы модель никогда не могла выдать реальные учетные данные обратно.
## Метрики
Метрики Prometheus доступны по пути `/metrics` на панели (без аутентификации, поэтому сборщики просто работают):
```
honeyprompt_events_total{protocol="ssh"} 412
honeyprompt_llm_requests_total{provider="openai",protocol="ssh"} 118
honeyprompt_auth_attempts_total{protocol="ssh"} 87
honeyprompt_engine_errors_total{protocol="http"} 0
```
## Сборка из исходников
Хотите внести вклад или нужен нативный бинарник? Вам понадобится [Deno](https://deno.com) 2.x — единственная зависимость.
```bash
deno task check # проверка типов
deno task lint
deno task fmt
deno task test # модульные и интеграционные тесты
deno task start -- --config honeyprompt.yaml # запуск локально
deno task dev -- --config honeyprompt.yaml # запуск с отслеживанием файлов
deno task compile # -> ./dist/honeyprompt (самодостаточный бинарник)
```
`deno compile` встраивает среду выполнения, ресурсы панели и все остальное в один исполняемый файл без каких-либо зависимостей. Готовые бинарники для Linux, macOS и Windows прикреплены к каждому помеченному [релизу](../../releases).
CI запускает форматирование, линтинг, проверку типов, тесты, проверку конфигурации, кроссплатформенную `compile` и сборку Docker при каждом пуше. Тегирование `vX.Y.Z` создает бинарники релиза и публикует образ для нескольких архитектур с подтверждением происхождения и SBOM в [`alectrocute/honeyprompt`](https://hub.docker.com/r/alectrocute/honeyprompt).
## CLI
```
honeyprompt run [--config <path>] запустить все настроенные сервисы (по умолчанию)
honeyprompt validate [--config <path>] разобрать и проверить конфиг, затем выйти — отлично для CI
honeyprompt version
honeyprompt help
```
`--config` по умолчанию равен `./honeyprompt.yaml` или `$HONEYPROMPT_CONFIG`, если задан (контейнер устанавливает его в `/etc/honeyprompt/honeyprompt.yaml`).
## Предупреждение для пользователей и участников
Это инструмент для привлечения и изучения атакующих на инфраструктуру, **которую вы контролируете или имеете право тестировать**. Развертывание сервисов-приманок все равно означает развертывание сервисов; запускайте его на изолированных хостах, поддерживайте в актуальном состоянии и не направляйте на то, что вы не можете позволить себе зондировать. Обман не заменяет реальную защиту.
Если вы хотите внести вклад в этот проект и используете ИИ-агента или сильно полагаетесь на сгенерированный код, это совершенно нормально, но вас *ОБЯЗАТЕЛЬНО* лично спросят по каждой строке кода, которую вы предложите, и если вы не продемонстрируете немедленное понимание без помощи ИИ, ваш *ВЕСЬ* вклад будет отклонен и удален.
## Лицензия
[MIT](https://github.com/alectrocute/honeyprompt/blob/main/LICENSE).