
MCP-сервер для оркестрации устранения CVE/конфигурационных проблем: инвентаризация по SSH, запросы к OSV/NVD, предложения Ansible playbook с привязкой к CIS/DISA STIG.
См. OVERVIEW.md, чтобы получить высокоуровневое описание
назначения репозитория, его компонентов и области охвата перед внесением
изменений в поведение.
Оркестратор исправлений, предоставляемый как MCP-сервер. Подключите MCP-клиент (Claude Desktop, Claude Code или аналогичный) и отправьте запрос на естественном языке, например:
Войди на хост a.b.c, проверь установленные пакеты, найди CVE и предложи исправление — Ansible, если возможно, и скажи, каким контролям соответствия оно соответствует.
prescryb предоставляет примитивы (инвентаризация SSH, сопоставление CVE,
живые запросы к бюллетеням, сопоставление тем соответствия, рендеринг
Ansible-плейбуков). Подключённая модель выполняет рассуждения: какие находки
важны, в какие CVE углубляться, какой плейбук генерировать. prescryb никогда
ничего не применяет к целевому хосту — каждый инструмент либо работает только
на чтение по отношению к нему, либо представляет собой чисто текстовую или
данными генерацию.
| Инструмент | Что он делает |
|---|---|
inventory_host(host, user="", port=22, hostname="", identity_file="", trust_unknown_host=False) | Подключается по SSH, определяет дистрибутив, перечисляет установленные пакеты с версиями. |
check_cves(system, packages) | Пакетно сопоставляет версии пакетов с OSV.dev, используя его сравнение версий с учётом экосистемы (а не сопоставление только по имени). Каждое совпадение обогащается оценкой вероятности эксплуатации EPSS. |
fetch_advisory(cve_id) | Получает текущую запись NVD для одной CVE — описание, CVSS, CWE, ссылки — в реальном времени, а не из обучающих данных. |
fetch_epss(cve_ids) | Пакетно получает оценки вероятности эксплуатации EPSS для идентификаторов CVE, ещё не охваченных check_cves (например, из fetch_advisory или веб-поиска). |
map_compliance(area) | Сопоставляет тему в свободной форме ("ssh", "sudo", "kernel modules", ...) с тематическими областями CIS/DISA STIG и, если она присутствует в GitHub-репозитории konstruktoid.hardening, с соответствующей ролью — плюс техники и меры противодействия MITRE ATT&CK, которые охватывает эта область. |
lookup_cce(target, keyword, cce_id) | Ищет записи NIST CCE (Common Configuration Enumeration) для платформы (например, "rhel8"), полученные из общественного JSON-преобразования в konstruktoid/cce-web. |
list_cce_targets() | Перечисляет все платформы, которые может запрашивать lookup_cce. |
list_local_docs() | Перечисляет документы (Markdown/text/PDF), найденные в локальном, игнорируемом git каталоге LOCAL_DOCS_DIR. |
search_local_docs(query, top_k=5) | Семантический поиск в стиле RAG по этим локальным документам, полностью выполняемый на машине. |
generate_playbook(system, cve_matches, compliance_areas, hosts_alias) | Рендерит Ansible-плейбук в режиме только предложение: исправления CVE становятся задачами обновления пакетов, области соответствия становятся ссылками в roles:. |
Типичный поток: inventory_host, затем check_cves по возвращённым пакетам,
затем при необходимости fetch_advisory по интересным CVE, затем
map_compliance (и lookup_cce) для любых замеченных областей небезопасной
конфигурации, затем при необходимости search_local_docs для релевантного
внутреннего контекста runbook/политик, затем generate_playbook, чтобы
получить что-то для проверки.
flowchart TD
U["Operator: natural-language request"] --> M["Connected model\n(Claude Desktop / Claude Code)"]
M --> A["inventory_host\nSSH in, list packages"]
A --> B["check_cves\nOSV.dev match + EPSS score"]
B --> C{"Interesting\nCVE?"}
C -->|yes| D["fetch_advisory\nNVD detail for one CVE"]
C -->|no| E
D --> E["map_compliance / lookup_cce\nCIS/DISA STIG + ATT&CK mapping"]
E --> F["search_local_docs\ninternal runbooks (optional)"]
F --> G["generate_playbook\nsuggest-only Ansible playbook"]
G --> H["Model reasons over the results\nand presents findings + playbook"]
H --> R["Operator reviews\n(ansible-playbook --check --diff)\nand applies manually"]
style R fill:#f9f,stroke:#333,stroke-width:1px
Только инструментальные блоки относятся к prescryb: inventory_host, check_cves,
fetch_advisory, map_compliance/lookup_cce, search_local_docs и
generate_playbook — каждый представляет собой вызов только для чтения или чистую генерацию текста/данных.
Оператор и подключённая модель не являются частью prescryb, и
ничто в этой цепочке не затрагивает целевой хост за пределами
сеанса SSH только для чтения inventory_host — применение сгенерированного playbook является намеренным,
отдельным шагом, который оператор выполняет вне prescryb.
uv sync
Claude Code:
claude mcp add prescryb -- uv --directory /path/to/prescryb run prescryb
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"prescryb": {
"command": "uv",
"args": ["--directory", "/path/to/prescryb", "run", "prescryb"]
}
}
}
inventory_host никогда не принимает аргумент с паролем. Аргументы вызовов инструментов MCP могут регистрироваться клиентами в журналах и видны подключённой модели, поэтому учётные данные никогда не должны передаваться через них. Аутентификация работает точно так же, как если бы вы сами запустили ssh host:
~/.ssh/config.hostname/identity_file у inventory_host напрямую переопределяют определённый адрес/путь к ключу — для хостов, которые вы не хотите добавлять в ~/.ssh/config (передаётся только путь, никогда не содержимое ключа).trust_unknown_host=True
ssh host, чтобы закрепить ключ.qemu/vm.sh загружает облачный образ (almalinux10, trixie, resolute) под
QEMU с seed-образом cloud-init и пробросом SSH-порта на 127.0.0.1
(2201, 2202, 2203). Ему требуются qemu-system-x86_64, qemu-img, cloud-localds
(cloud-image-utils), curl и ssh; KVM используется, когда /dev/kvm доступен для записи.
Образы проверяются по контрольной сумме и кэшируются в qemu/.state/.
qemu/vm.sh up trixie
qemu/vm.sh ssh trixie true # retry until the guest answers
claude 'inventory 127.0.0.1 port 2202 user prescryb with identity file
qemu/.state/id_ed25519 (trust_unknown_host is fine, it is a throwaway VM),
check any vulnerabilities and suggest a fix, include compliance mapping if
possible, write the playbook suggestion to /tmp/ and print the file location'
qemu/vm.sh destroy trixie
Для хоста, уже доступного через ssh (разрешаемого через ~/.ssh/config,
ключ агента или файл идентичности по умолчанию), укажите имя хоста
напрямую; настройка порта или файла идентичности не требуется:
Проведи инвентаризацию prod-web-01, проверь установленные пакеты, найди CVE и предложи исправление — по возможности Ansible, и скажи, каким контролам соответствия это соответствует.
Если хост ещё не указан в ~/.ssh/config, добавьте блок Host или передайте
user/port/hostname/identity_file напрямую в inventory_host для
разового подключения — так же, как в примере с molecule ниже.
molecule converge -s default