Агентные навыки для аудита безопасности и затрат инфраструктуры Hetzner с подтверждением путей атак.
Универсальный сканер уязвимостей для контейнеров, файловых систем, Git-репозиториев и IaC (Terraform, K8s, Dockerfile) от Aqua Security. …
Инструмент проверки конфигурации безопасности AWS/Azure/GCP на соответствие CIS Benchmarks, GDPR, HIPAA, PCI-DSS, NIST. 500+ проверок: открытые …
Сканер уязвимостей для образов контейнеров и файловых систем — использует SBOM и базы данных CVE.
Рантайм-детектор угроз для контейнеров, Kubernetes и облачной инфраструктуры — проект CNCF. Отслеживает системные вызовы в реальном …
npx skills add https://github.com/jpolec/hetzner-cloud-audit-skills/tree/v0.8.2 --skill hetzner-security-audit uvx hetzner-audit doctor --report-dir ./_output uvx hetzner-audit audit --format markdown --output _output/audit.md uvx hetzner-audit map --format svg --output _output/architecture.svg git clone https://github.com/jpolec/hetzner-cloud-audit-skills cd hetzner-cloud-audit-skills uv run hetzner-audit audit --format markdown --output _output/audit.md git clone https://github.com/jpolec/hetzner-cloud-audit-skills && cd hetzner-cloud-audit-skills uv run hetzner-audit audit --input benchmarks/scenarios/v0.1-insecure.json --format markdown --output demo.md unset HCLOUD_TOKEN
Бесплатно и с открытым исходным кодом (Apache-2.0). Никаких аккаунтов, SaaS или телеметрии. hetzner-audit запускается на вашей машине и не отправляет ничего никуда, кроме read-only GET запросов к API Hetzner.
Один read-only токен и одна команда отвечают на провайдерскую часть всего этого; детали хостов (UFW, Docker, базы данных) поступают из опционального read-only бандла, который вы запускаете сами. Вы получаете карту архитектуры, представление о радиусе поражения, разбивку затрат на каждую VM и ранжированный список того, что делать дальше. Каждый вывод подкреплён доказательствами.

Пример проекта, сгенерированного hetzner-audit map из read-only токена. Публичные IP-адреса никогда не отображаются.
Независимый open-source проект. Не связан с Hetzner, Cloudflare или любым другим провайдером, которого он распознаёт, и не одобрен ими. v0.8 — альфа: проверяйте каждый результат с высоким влиянием перед тем, как действовать на его основе.
| Безопасность | Публичная экспозиция, обход Cloudflare, радиус поражения в общих приватных сетях и пути через границы доверия | |
| Затраты | Стоимость каталога на VM, концентрация расходов, идентифицируемые потери и кандидаты на правкий размер или ARM | |
| Архитектура | AWS-стиль диаграммы: сетевая зона, приватная сеть, локации, уровни ролей и источники доверия | |
| За пределами API | Файрвол хоста, слушатели и Docker из бандла, запускаемого владельцем; дрифт Terraform; выделенные серверы Robot; Object Storage; Kubernetes; несколько проектов | |
| Действия | Ранжированный список дел: экономия, уровень доказательств, риск действий и конкретный следующий шаг | |
| Отслеживание изменений | Снапшоты с таймстемпами, diff с учётом покрытия, GitHub Action и SARIF | |
| Готовность к агентам | Поставляется как навык SKILL.md для Claude Code, OpenAI Codex и совместимых агентов | |
| Полный список того, что оно распознаёт (Cloudflare и другие CDN, Tailscale и другие mesh VPN, туннели, хостовые файрволы, Docker, базы данных, Robot, Object Storage, Kubernetes) с честным статусом live/fixture на каждую позицию: What hetzner-audit sees. |
Чем это отличается от дашборда затрат или сканера портов: оно разделяет то, что доказано, от того, что лишь подозревается.
| Результат | Значение |
|---|---|
confirmed / reachable |
Каждое звено в цепочке подтверждено доказательствами: сеть, файрвол, хостовое правило, слушатель, конфиг сервиса |
reachable_after_pivot |
Каждый слой пропускает трафик, но только после компрометации другого хоста, чего доказательства не подтверждают |
needs_validation / cloud_path_present |
Топология Hetzner позволяет это, но доказательств на уровне хоста или рантайма нет |
unknown |
Путь не обнаружен, но покрытие слишком неполное, чтобы заявлять об изоляции |
Отсутствующий коллектор сообщается как пробел. Он никогда не сообщается как «безопасно». Подтверждённые экономии остаются нулевыми, пока нет доказательств. Инструмент никогда не завышает цифры.
| AI agent skill: быстрее, рекомендуется | Командная строка | |
|---|---|---|
| Установка | npx skills add https://github.com/jpolec/hetzner-cloud-audit-skills/tree/v0.8.2 --skill hetzner-security-audit |
uvx hetzner-audit …, или git clone и uv run |
| Запуск | Спросите у агента: «аудит моей инфраструктуры Hetzner» | hetzner-audit audit, hetzner-audit map |
| Что происходит | Агент запускает preflight, снапшот, аудит и диаграммы. Затем объясняет находки простым языком и ведёт через исправления. | Markdown, JSON, SARIF и SVG файлы попадают в папку вывода |
| Подходит для | Первого взгляда, вопросов вроде «может ли staging достучаться до prod?» и توجيهного remediation | CI, cron, скриптов и повторяющихся отчётов |
Оба используют один и тот же read-only движок и одни и те же правила доказательств. Работает с Claude Code, OpenAI Codex и другими SKILL.md-совместимыми агентами.
Шаги 1 и 2 одинаковы для обоих способов. Затем выбирайте A (агент) или B (командная строка).
В Hetzner Console: ваш проект → Security → API tokens → Generate API token → Read.
Никогда не выбирайте Read & Write; инструмент делает только GET запросы. Иллюстрированное руководство по токену охватывает каждый шаг, включая отзыв.

printf 'Hetzner read-only token: '
IFS= read -rs HCLOUD_TOKEN; printf '\n'
export HCLOUD_TOKEN
Это держит токен вне истории шелла. Никогда не вставляйте его в промпт агента, аргумент команды, .env, скриншот или отчёт.
npx skills add https://github.com/jpolec/hetzner-cloud-audit-skills/tree/v0.8.2 --skill hetzner-security-audit
Часть /tree/v0.8.2 привязывает skill к тегированному релизу, что вы и хотите для инструмента безопасности. Уберите, чтобы следовать за main (разработка).
Запустите ваш агент (например claude или codex) из того же терминала, чтобы он унаследовал HCLOUD_TOKEN не видя его значения. Затем просто спросите:
audit my Hetzner infrastructure
Или перейдите сразу к тому, что вас интересует:
draw the architecture of my Hetzner project
can anything reach my production database?
where am I overpaying on Hetzner?
what changed since the last audit?
Агент проверяет настройку через doctor, подтверждает с вами область проекта и собирает read-only снапшот. Затем загружает сетевые, Linux, Docker, PostgreSQL, Redis, бэкап или cost-наставления только когда доказательства делают это релевантным. Для работы cost-first есть отдельный skill: --skill hetzner-cost-audit.
uvx hetzner-audit doctor --report-dir ./_output # preflight: token, API, project scope
uvx hetzner-audit audit --format markdown --output _output/audit.md
uvx hetzner-audit map --format svg --output _output/architecture.svg
uvx запускает PyPI пакет без установки. Можно также работать из исходников:
git clone https://github.com/jpolec/hetzner-cloud-audit-skills
cd hetzner-cloud-audit-skills
uv run hetzner-audit audit --format markdown --output _output/audit.md
Чтобы закрепить релиз, используйте uvx --from 'git+https://github.com/jpolec/hetzner-cloud-audit-skills@v0.8.2' hetzner-audit --help. Для CI см. GitHub Action.
doctor подтверждает, что токен работает, не печатая его. Показывает область проекта (количество серверов, файрволов, сетей и томов), чтобы вы могли проверить, выбрали ли правильный проект. Также предупреждает, если отчёты попадут в Git-отслеживаемую директорию.
git clone https://github.com/jpolec/hetzner-cloud-audit-skills && cd hetzner-cloud-audit-skills
uv run hetzner-audit audit --input benchmarks/scenarios/v0.1-insecure.json --format markdown --output demo.md
Это запускается против синтетического, намеренно небезопасного фикстуры. Вы также можете просто прочитать пример отчёта по безопасности и пример отчёта по затратам.
unset HCLOUD_TOKEN # then revoke the token in Hetzner Console
Относитесь к отчётам как к конфиденциальным. Они содержат имена, частные адреса и топологию. Не коммитьте реальные отчёты или снимки в публичный репозиторий.

Каждый аудит начинается с трёх пунктов:
Где исправление — это простая команда hcloud (защита от удаления, метки, удаление правила всех портов), действие включает предлагаемую команду для человеческого ревью. Такие команды требуют токен Read & Write, поэтому hetzner-audit никогда не запускает их, а имена провайдеров санитизированы, чтобы сфальсифицированное имя не могло инжектить шелл-синтаксис.
Затем следуют детальные находки, каждая с цепочкой доказательств, влиянием и способом устранения. Косвенные пути держатся отдельно от прямого воздействия: база данных, доступная только через пивот через другой хост, не сообщается как интернет-экспонированная.
Из коробки API-only слой проверяет:
scripts/update_provider_ranges.py --check).environment или role;owner);environment-policy).Помечайте базы данных и хосты секретов меткой sensitivity=high, чтобы обнаружение не зависело от имён серверов.
[roles.db] internet_egress = false или ["tcp/443"]), что вызывает HETZ-EGR-001.Каждое замечание также указывает, выполнялось ли его правило против живого проекта Hetzner или только против фикстур.
Вы контролируете шум. Добавьте audit.ignore=true или audit.ignore.HETZ-BCP-001=true для одного правила к ресурсу, который намеренно отличается, например к временному билд-боксу. Замечание перемещается в раздел Suppressed by owner labels отчёта вместо того чтобы исчезнуть молча.
Hetzner Cloud Firewalls не фильтруют трафик частной сети (Hetzner FAQ). Каждый участник частной сети имеет маршрут к любому другому участнику, и правила файрвола с диапазонами частных источников не влияют на этот трафик. Достижимость порта определяется слушателем, его bind-адресом, хостовым файрволом и управлением приложением.
hetzner-auditмоделирует это так: частный путь —cloud_path_present, пока доказательства хоста не подтвердят или не опровергнут его.

Задавайте прямые вопросы:
hetzner-audit ask "Can the Internet reach any database?" --input snapshot.json
hetzner-audit path --from staging-worker --to prod-db --protocol tcp --port 5432 --input snapshot.json
hetzner-audit explain HETZ-XLY-002-0123456789abcdef --input snapshot.json
explain выводит сохранённую цепочку доказательств, путь атаки, вызов верификатора, неразрешённые предварительные условия и способ устранения. Он не просит модель придумать новое объяснение.

API Hetzner не видит слушателей хоста, публикацию портов Docker, PostgreSQL HBA, Redis ACL или память гостя. Без доказательств хоста такие замечания остаются needs_validation и показывают, чего не хватает. Следующий раздел закрывает этот пробел.
hetzner-audit host-bundle > host-bundle.sh # review it: a fixed list of read-only commands
ssh web-1 'sudo HETZNER_AUDIT_SERVER=web-1 sh -s' < host-bundle.sh > _output/web-1.bundle
hetzner-audit audit --host-bundle _output/web-1.bundle --output _output/audit.md
hetzner-audit map --format svg --view host --host-bundle _output/web-1.bundle --output _output/host.svg
hetzner-audit никогда не подключается к вашим серверам. Вы запускаете скрипт сами; он выводит правила UFW, nftables и iptables, слушателей (ss), эффективные настройки sshd, настройки изоляции Docker и опубликованные порты, pg_hba.conf и состояние bind/ACL Redis. Он не выводит переменные окружения, пароли (Redis показывает только <set>) и хеши ACL.
С бандлом публичная доступность определяется пересечением потоков: Cloud Firewall ∩ хостовый файрвол ∩ слушатель. Замечание становится confirmed, когда каждый слой допускает порт, и rejected, когда доказательства хоста его опровергают. Если слой не удалось прочитать (например, UFW без root, цепочка прыжков firewalld или нет ss), замечание остаётся needs_validation. Неизвестное никогда не считается безопасным.
Что оно находит, чего не может найти один API:
pg_hba.conf в порядке первого совпадения. Ранний reject скрывает поздний trust только когда он действительно его покрывает (тип соединения, семейство адресов, диапазон).
Каждый источник опционален, доступен только для чтения и имеет свои учётные данные или сохранённый файл:
| Источник | Как | Что проверяет |
|---|---|---|
| Terraform | --terraform plan.json (terraform show -json, state или сохранённый план) |
Ресурсы вне Terraform, ресурсы, удалённые вне него, дрифт защиты/бэкапов/файрволов/меток, источники файрвола, отличающиеся от кода, безопасные изменения в плане |
| История изменений провайдера | автоматически (последние 30 дней /actions) |
Режим восстановления, консольные сессии, сброс паролей, пересборки, удаление файрвола, отключение защиты |
| Несколько проектов | snapshot --project prod --token-env HCLOUD_TOKEN_PROD, затем merge |
Один отчёт; файрвол в одном проекте доверяет публичному адресу другого проекта; продакшн смешан с другими окружениями |
| Hetzner Robot | --robot (GET с пользователем веб-сервиса) или сохранённый файл |
Выделенные серверы без активного файрвола Robot, чувствительные порты, которые он пропускает (первое совпадение, только SYN), нефильтрованный IPv6, связь vSwitch с Cloud-сетями, слабые ключи |
| Object Storage | --object-storage (S3 GET, SigV4) или сохранённый файл |
Публичные ACL, политики бакетов с масками (чтение или запись), отключённое версионирование; с --verify-public-buckets публичный доступ подтверждается одним анонимным листингом |
| Kubernetes | --k8s cluster.json (kubectl get nodes,pods,services -A -o json) |
NodePorts, которые Cloud Firewall открывает в интернет на нодах, нагрузки с доступом на уровне ноды, обнаружение CCM/CSI |
| Телеметрия гостей | hetzner-audit metrics --prometheus URL > metrics.json, затем --node-metrics |
RAM p95, пик RAM и пик корневой ФС; подбор размера предлагает только типы, им соответствующие |
| Чек-лист консоли | hetzner-audit checklist, ответы через --attestations |
2FA у каждого участника, роли участников, токены Read & Write, вход в Robot, ключи S3, под-аккаунты Storage Box, контакты для восстановления |
| Представление архитектуры добавляет всё это под сеткой серверов: балансировщики нагрузки, кластер Kubernetes, серверы Robot и vSwitch, а также бакеты. |
hetzner-audit cost --metrics-days 30 --format markdown --output cost.md
hetzner-audit map --format svg --view cost --output cost.svg
hetzner-audit diff before.json after.json оценивает оба снимка по более раннему каталогу, поэтому экономия от вашего изменения отделена от изменений цен провайдера. Это дельта каталога, а не сверка со счётом, и пробелы в сборе блокируют её.--node-metrics меньший тип предлагается только если RAM p95 остаётся ниже 70%, пик RAM ниже 90%, а использование диска ниже 80% от кандидата.
Аудит стоимости намеренно консервативен. Остановленный сервер всё ещё оплачивается. Экономия на ARM требует валидации образа, зависимостей и производительности. Инструмент не имеет действий по изменению размера, остановке, удалению, откреплению или покупке.

hetzner-audit map --format svg --view architecture --output architecture.svg # --theme dark available
hetzner-audit map --format svg --view connectivity --output connectivity.svg
hetzner-audit map --format svg --view cost --output cost.svg
hetzner-audit map --format svg --view host --output host.svg # needs --host-bundle
hetzner-audit map --format svg --view posture --output posture.svg
hetzner-audit map --format markdown --output network-map.md # Mermaid; renders on GitHub
Представление архитектуры расположено как диаграмма AWS или OCI:
Галерея примеров: другие стеки, тот же аудит. Четыре синтетических проекта (каждое имя и адрес вымышлены), отрисованные через hetzner-audit map:
Представление posture — это матрица доменов (сеть, хост, данные, идентичность, отказоустойчивость, управление) по серьёзности. Показывает подтверждённые находки рядом с теми, что ещё нужно валидировать, с полосами покрытия и источниками доказательств.

--max-actions управляет количеством отрисованных действий.
| Раскрытие | Значение |
|---|---|
| critical | Чувствительный порт или все порты открыты для любого адреса, или у сервера нет облачного фаервола |
| public | Другие порты открыты для любого адреса |
| proxied | Доступен только из диапазонов пограничного прокси (таблетка называет его, например VIA CF или VIA FASTLY) |
| private | Нет публичного входа, кроме UDP-порта mesh-VPN (Tailscale, WireGuard/NetBird, ZeroTier) |
| Карты показывают намерения файрволов, а не управление хостами или приложениями. Они никогда не печатают публичные IP-адреса, но раскрывают вашу топологию, поэтому храните их в приватности. См. пример карты. |
hetzner-audit snapshot --output before.json --read-only --no-ssh
# ... later ...
hetzner-audit snapshot --output after.json --read-only --no-ssh
hetzner-audit diff before.json after.json --fail-on-regression # broad: new world/wide exposure
hetzner-audit diff before.json after.json --fail-on-regression --regression-policy strict # any growth
Diff сравнивает точные пространства разрешённых потоков, а не рёбра графа: для каждого сервера и балансировщика нагрузки, по семейству адресов и протоколу, множество пар (адрес источника, порт назначения), которые файрволы допускают на вход, и то же самое для выхода. after − before вычисляется точно и затем классифицируется (world, wide, edge provider, allow-list):
80-443 до 80-8443, или открытие порта только на IPv6 — это новый риск (broad и strict);203.0.113.4/32 до 203.0.113.0/24, замена одного доверенного адреса на другой, или новый исходящий доступ в Интернет — изменение, на котором проваливается strict;Закрытый риск также перечисляется. Также сообщается об изменениях активов и фактов, а также регрессиях покрытия коллектора. Ресурс, который не удалось собрать, не сообщается как удалённый. Каждый факт записывает свой источник, время наблюдения, версию коллектора и ID запуска.
- uses: jpolec/hetzner-cloud-audit-skills@v0.8.2
env:
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}
with:
mode: audit
policy: policies/infrastructure.toml
fail-on: confirmed-high # hypotheses never fail the job
format: sarif
output: hetzner-audit.sarif
Установите fail-on: confirmed или confirmed-high, чтобы проваливать задачу только на подтверждённых выводах. Гипотезы needs_validation никогда не проваливают задачу, и они появляются в SARIF на уровне none. Зелёная задача означает, что на этом пороге ничего не было подтверждено; это не означает, что инфраструктура безопасна.
Запускайте живую сборку только из защищённых задач schedule или workflow_dispatch, и никогда не выставляйте токен в код форков. См. полное руководство по GitHub Action. SARIF работает лучше всего, когда вывод маппится на IaC. Выводы только о runtime-топологии остаются в Markdown и JSON.
Скажите ему, что такое «правильно». Общие лучшие практики слабее, чем ваш собственный архитектурный контракт:
[environments.production]
may_receive_from = ["production"]
[services.postgres]
public = false
[ssh]
public = false
hetzner-audit audit --policy policies/example-policy.toml --format markdown --output audit.md
Наблюдаемые факты, политика владельца, декларации IaC и выведенные гипотезы хранятся как отдельные записи.
POST, PUT или DELETE. Используйте токен Read всё равно.--verify-public-buckets, чтобы подтвердить, что бакет, который уже выглядит публичным, действительно таковым является.HROBOT_USER/HROBOT_PASSWORD (пользователь Robot webservice), HETZNER_S3_ACCESS_KEY/HETZNER_S3_SECRET_KEY, и PROMETHEUS_TOKEN читаются из окружения и никогда не печатаются. doctor предупредит, если любой из них лежит в .env файле.user_data;Retry-After. Пагинация и поиск по пути ограничены.См. модель угроз и разрешения.
flowchart LR
H[Hetzner GET-only API] --> F[Temporal facts]
I[IaC and owner policy] --> F
R[Host bundles, Robot, S3, kubectl, telemetry] --> F
F --> G[Typed evidence graph]
G --> P[Attack paths]
G --> D[Temporal diff]
G --> S[Security findings]
G --> C[Cost and architecture candidates]
P --> V[Deterministic verification]
D --> V
S --> V
C --> V
V --> A[Ranked recommended actions]
A --> O[Markdown / SVG / JSON / SARIF]
Конвейер: collect → reason → verify → recommend. Детерминированный верификатор — отдельный компонент, а не независимый человек или агент-ревьюер. Кандидаты, сгенерированные агентом, без независимого верификатора остаются в статусе needs_validation.
Подробнее: архитектура, архитектура FinOps, эталонный анализ Cloudflare, ландшафт.
| Возможность | Статус v0.8 |
|---|---|
Инвентаризация с покрытием по эндпойнтам, doctor префлайт, повторные попытки/бэкофф |
Бета, протестировано на живом проекте |
| Публичная экспозиция (~30 сервисов), качество фаервола, обход Cloudflare | Бета, протестировано на живом проекте |
| Радиус поражения приватной сети | Бета (хост/рантайм остаются needs_validation) |
| Экспозиция Storage Box и план снимков; управление лейблами | Бета, протестировано на живом проекте |
| Балансировщики нагрузки (вкл. рёбра графов атак и обход), сертификаты, DNS, жизненный цикл ОС, размещение | Бета, только фикстуры (позитивный кейс и чистый твин) |
| Сила и возраст SSH-ключей | Бета: поля проверены на живом проекте (слабых ключей не было, поэтому позитивный кейс протестирован фикстурами и бенчмарками) |
| Квота трафика и перерасход | Бета, протестировано на живом проекте |
| Семантический diff экспозиции (наборы потоков, не ID рёбер) | Бета, property-тестирование против брутфорса |
| Рекомендуемые действия с уровнями доказательств; пять представлений (архитектура, связность, стоимость, хост, позиция) | Бета |
История изменений провайдера (/actions) |
Бета, протестировано на живом проекте |
| Пакет доказательств хоста и пересечение потоков | Бета, только фикстуры (модель реального UFW + Docker хост, плюс adversarial-кейсы парсера); ещё не запускалось на живом |
| Дрифт Terraform, Robot, Object Storage, Kubernetes, чек-лист консоли | Бета, только фикстуры. Подписание Object Storage верифицировано против тестовых векторов AWS SigV4 |
| Слияние мульти-проектов | Бета, слияние протестировано на одном живом проекте; кросс-проектные правила — только фикстуры |
| Телеметрия RAM/диска гостя и тиры экономии | Экспериментально, только фикстуры |
| Точный diff пространства потоков (вход и выход), широкие/строгие политики | Бета, property-тестирование против брутфорса |
| Модель исходящего трафика и политика egress по ролям | Бета, протестировано на живом проекте |
| IP-таргеты балансировщиков (Cloud и Robot) | Бета, только фикстуры |
anonymize и скорер валидационного корпуса |
Бета; анонимизированный вывод тестировался на живом для получения идентичных находок; корпус пока пуст |
Снимки и diff; GitHub Action с fail-on; SARIF |
Бета |
| Стоимость: отходы, концентрация, райзизинг и ARM-кандидаты | Экспериментально |
needs_validation. Скрипт только читает; вы всё ещё решаете, где его запускать.Используйте для топологии, публичной экспозиции, радиуса поражения приватной сети, дрифта фаервола и ранжированного списка фиксов. Не рассматривайте как единственный аудит безопасности или FinOps.
См. дорожную карту.
Помогите измерить реальную точность. hetzner-audit anonymize snapshot.json --output anon.json заменяет имена, значения лейблов, адреса, ID, нестандартные порты и свободный текст последовательно, так что находки остаются теми же. Разметьте находки анонимизированного проекта и scripts/corpus_eval.py покажет ложно-подтверждённый рейт — это то число, что важно для аудитора (руководство по корпусу).
needs_validation.Оба измеряют правила против их спецификации, а не точность обнаружения в реальном мире (методология).
Приветствуются issues, идеи правил и pull requests, особенно реальные случаи, где инструмент ошибается. См. CONTRIBUTING.md и AGENTS.md.
uv sync --extra dev
uv run ruff check . && uv run mypy src && uv run pytest
./scripts/demo.sh # regenerate examples/reports
uv run python scripts/validate_artifacts.py
Код времени выполнения использует только стандартную библиотеку Python. Лицензирован под Apache-2.0 за его явное предоставление патента.
Создан и поддерживается Jakub Połeć.
Сообщайте о проблемах безопасности через GitHub private vulnerability reporting, а не через публичный issue.
Если hetzner-audit сэкономил вам деньги или поймал что-то страшное, ⭐ на GitHub поможет другим найти его.