Обзор, проблемы, карта ресурсов
Первые разделы меню отвечают на главный вопрос: что на хосте на самом деле происходит и что сломано. Конфиги nginx, haproxy, caddy, docker compose, firewall и сертификаты разбираются и сверяются с живым состоянием — выводом ss, счётчиками iptables, запущенными контейнерами, настоящим TLS-соединением к сокету.
Обзор

- Сводка: ОС, ядро, время работы, нагрузка, память, диски, сеть.
- Аптайм под сводкой: «Работает 27 дн. 4 ч». Зелёным — машина не перезагружалась с вашего прошлого захода (аптайм вырос ровно на прошедшее время), красным — перезагружалась (стал меньше прежнего). Прошлое значение помнится в браузере по имени хоста; хаб про перезагрузку пишет оповещение сам.
- Счётчики: проблемы по серьёзности, объявленные и публичные слушатели, контейнеры, доступность за сутки, обновления пакетов. Каждый ведёт в свой раздел.
- Что изменилось с прошлого захода — новые и исчезнувшие проблемы, сервисы, контейнеры, сертификаты: открыли утром — видно, что случилось ночью.
- Пакеты-помощники (htop, ncdu, jq, tmux…) с отметкой «установлен» и установкой в один клик.
- «Пересканировать» — свежий скан хоста прямо сейчас, не дожидаясь расписания.
Проблемы

Каждая находка — серьёзность, объяснение простыми словами, файл и строка, конкретное действие для исправления и ссылки на документацию. Поиск и фильтр по серьёзности, сервису и тексту.
Под находкой — кнопки, ведущие туда, где она исправляется:
- Открыть на строке N — файл в «Конфигурациях», нужная строка подсвечена и прокручена в видимую часть;
- К сертификату — «Сертификаты», строка сертификата подсвечена; там же «Продлить» с живым журналом certbot;
- Логи, Перезапустить, Запустить — у контейнера в цикле перезапусков или не запущенного: логи открываются в окне, запуск и перезапуск — с подтверждением и живым журналом, как в «Docker» (только администратору и при разрешённых действиях);
- Firewall — у открытого наружу порта, Docker и Kubernetes в обход правил, устаревшего правила;
- Порт N в Firewall и На карте ресурсов — у неучтённого слушателя: в «Firewall» подсвечены правила и сокет этого порта, на карте открыт его узел (или свёрнутая служба с ним);
- К вредоносному — вкладка «Вредоносное» в «Уязвимостях», карточка находки подсвечена; Открыть в файлах — проводник «Дисков» на строке файла (если файл лежит под корнем проводника);
- Fail2ban — у находок fail2ban;
- К службе nginx (haproxy, caddy, docker, fail2ban…) — «Сервисы» с подсвеченной строкой службы; К контейнеру — «Контейнеры» с подсвеченной строкой.
Те же кнопки — у каждой находки в «Что сломано» на обзоре.
Что проверяется:
- Сеть и firewall — конфликты портов, «объявлено, но не слушает», «слушает, но не объявлено», нет default deny, публичный порт закрыт firewall'ом, контейнер Docker публикует порт в обход ufw, устаревшие правила, Redis/PostgreSQL/MongoDB на всех интерфейсах.
- TLS — слабые протоколы, нет HSTS, сертификат не указан, просрочен, истекает, ещё не действителен, не читается, не покрывает имя, не продлевается автоматически, осиротевшая линейка certbot, самоподписанный, слабый ключ, сервис не перечитал сертификат (сокет отдаёт не то, что на диске), HTTP-прокси без шифрования.
- Пулы и контейнеры — несуществующий или неиспользуемый upstream, бэкенд не слушает, все бэкенды выключены, единственный бэкенд, нет health-check, контейнер в цикле перезапуска, не запущен, не объявлен, без политики перезапуска, панель haproxy без пароля, демон docker без клиента (Debian 13: docker.io без docker-cli).
- Kubernetes (на control plane) — под в CrashLoopBackOff или ImagePullBackOff, рестарт пода за последний час, долгий Pending, узел NotReady, Deployment или StatefulSet без части реплик, висящий PVC, истекающий сертификат API-сервера, поды с privileged/hostNetwork, NodePort и LoadBalancer мимо файрвола; контейнеры без limits, образы без версии, cluster-admin у ServiceAccount и людей, namespace без NetworkPolicy.
- Расхождение с профилем — если к хосту применён профиль, отклонения от него тоже показываются здесь.
Полный список правил с кодами — ниже.
Уязвимости
Сканирование на CVE через trivy: установленные пакеты ОС хоста, пакеты внутри инстансов LXD и машин libvirt (у контейнеров LXD — напрямую, у VM LXD — через lxd-agent, у машин libvirt — через qemu-guest-agent) и образы контейнеров Docker/Podman, а на control plane Kubernetes — образы всех подов кластера (из containerd узла или прямо из registry). Источник каждой находки виден в списке, у образа пода — и поды, где он работает. trivy ставится сам при первом скане, база уязвимостей скачивается автоматически (или берётся с хаба — у него она общая для всех хостов). Список: серьёзность, пакет, исправленная версия, ссылки; ход сканирования — в реальном времени.
Порядок «по опасности» (по умолчанию) ставит первым то, до чего можно достучаться из сети, затем — по серьёзности, а при равных — то, что исправляется обновлением:
- колонка «Из сети» — порты, по которым уязвимое доступно: служба пакета ОС слушает не только loopback (пакет — владелец бинарника слушающего процесса,
dpkg -Sилиrpm -qf) или контейнер с этим образом публикует порт не на 127.0.0.1; - фильтры «только доступные из сети» и «только с исправлением»;
- порядок «по серьёзности» — прежний, без учёта сети.
Библиотеки (например, libssl внутри nginx) со службами пока не связываются: уязвимость в них стоит по серьёзности, без пометки «в сети».
У каждой строки — переход туда, где это исправляется: К пакету — «Пакеты», отфильтрованные по имени, ячейка пакета подсвечена; К контейнерам — «Контейнеры» с подсвеченными строками контейнеров этого образа.

Вкладка «Вредоносное» — проверка на майнеры и признаки взлома без сторонних программ (процессы с именами майнеров, соединения с пулами, бинарники из /tmp или удалённые с диска, cron с «curl | sh», юниты из временных каталогов, чужие SUID, /etc/ld.so.preload, блокировки в /etc/hosts) в каждом скане, а ниже — ClamAV: установка, база сигнатур, скан каталогов хоста и образов контейнеров, карантин. У каждой находки — переходы: файл — в проводник «Дисков» на его строке (если он под корнем проводника), файл в /etc — в «Конфигурации», контейнер — в «Контейнеры».

Установка ClamAV, обновление базы (freshclam) и сканирование идут заданиями хоста, по одному за раз: при запуске открывается стандартное окно журнала с ходом операции, пока задание идёт, в карточке видно, что именно выполняется, с кнопками Журнал и Отмена. Отмена останавливает и сам clamscan (на хосте с systemd — весь его временный юнит), а развёрнутый для проверки образ удаляется; прошлый результат сканирования остаётся. Отменить можно и из окна журнала любого задания — кнопкой Отменить задание.
Карта ресурсов

Граф, где трафик читается слева направо:
внешняя сеть → сервис → слушатель → пул → бэкенд → контейнер или машина → сетьСвязи берутся из конфигов (proxy_pass, upstream, use_backend, опубликованные порты), состояние узлов — из живых слушателей, контейнеров и находок. Раскладка по колонкам стабильна между сканами; масштаб и перетаскивание — мышью, подсветка связей — по наведению. Щелчок по узлу открывает окно с его подробностями: вид, состояние, проблемы узла и все его параметры целиком; там же кнопка к тому, кто за него отвечает: служба — «Сервисы» с подсвеченной строкой, слушатель или пул — его конфиг, контейнер Docker или Podman — его строка в «Контейнерах», LXD, машины и Kubernetes — их вкладка, сеть — «Сетевые интерфейсы», неописанный слушатель — «Firewall» с подсвеченными правилами его порта.
Карта перетаскивается мышью при любом масштабе, текст подписей при этом не выделяется, а отпускание после сдвига не открывает узел под курсором.
Порты одной службы сворачиваются. Если у службы (nginx с десятком server-блоков, процесс, открывший много портов) слушателей больше порога, на карте они — один узел «nginx · 12 портов» со связями всех портов. Порог задаётся в строке над картой рядом с галочками («Сворачивать порты службы больше», по умолчанию 4) и запоминается в браузере. Щелчок по свёрнутому узлу открывает окно со списком портов: у каждого состояние, число проблем и кнопка в раздел, где он настраивается (конфиг слушателя, порт в «Firewall»); Развернуть на карте показывает порты службы по отдельности.
Машины libvirt и инстансы LXD связаны со своими сетями (мост libvirt, сеть LXD) и с бэкендами, которые смотрят на их адрес, — видно, какой сайт живёт на какой машине. Проброшенные порты LXD — вход с хоста в инстанс. В сведениях узла машины — адрес, ping, текущие процессор и память и уязвимости пакетов внутри; не отвечает на ping — узел красный, есть критические уязвимости — жёлтый.
Кластер Kubernetes (на control plane) — свои колонки: Ingress → Service → поды → узел кластера, а узел связан с машиной хоста, на которой работает. Сервис без подов и Ingress на несуществующий сервис подсвечены.
Правила и коды
Каждая находка — с объяснением, ссылкой на файл и строку и конкретным действием. Коды видны в API (/api/findings) и в nkt scan.
Сеть и firewall
| Правило | Серьёзность | Что находит |
|---|---|---|
port-conflict | высокая | Два сервиса объявляют один и тот же порт на пересекающихся адресах |
declared-not-listening | высокая | Порт описан в конфиге, но ничего его не слушает |
listening-not-declared | средняя/инфо | Процесс слушает порт, не описанный ни в одном конфиге |
no-default-deny | высокая | Политика INPUT — ACCEPT, а ufw выключен |
public-port-blocked | средняя | Сервис слушает 0.0.0.0, но firewall его блокирует |
docker-bypasses-firewall | критическая/высокая | Контейнер публикует порт на 0.0.0.0 — DNAT обходит INPUT и ufw |
stale-firewall-rule | низкая | Правило разрешает порт, который никто не слушает |
sensitive-port-public | критическая/высокая | Redis, PostgreSQL, MongoDB и подобные слушают все интерфейсы |
TLS и сертификаты
| Правило | Серьёзность | Что находит |
|---|---|---|
weak-tls | средняя | TLSv1 / TLSv1.1 оставлены в ssl_protocols |
missing-hsts | низкая | TLS-сервер не отправляет Strict-Transport-Security |
tls-cert-missing | высокая | listen ... ssl без ssl_certificate |
tls-cert-expired / -expiring | критическая / высокая-средняя | Просрочен, либо истекает через 7–30 дней |
tls-cert-not-yet-valid | высокая | Ещё не действителен — обычно неверные часы на хосте |
tls-cert-unreadable | высокая | Файл, на который указывает конфиг, не читается |
tls-cert-name-mismatch | высокая | Сертификат не покрывает имя, которым отвечает сервер |
tls-cert-renewal-not-automatic | средняя | certbot знает о сертификате, но ни таймер, ни cron его не продлят |
tls-cert-orphan-lineage | высокая | Лежит в /etc/letsencrypt/live, но конфига продления нет |
tls-cert-self-signed / -weak-key / -weak-signature | низкая / средняя | Самоподписанный, RSA короче 2048, или подпись SHA-1/MD5 |
tls-cert-not-reloaded | высокая | Сокет отдаёт другой сертификат, чем указан в конфиге — сервис не перечитал файл |
public-plaintext-proxy | средняя | Публичный HTTP-слушатель проксирует трафик без шифрования |
Пулы и контейнеры
| Правило | Серьёзность | Что находит |
|---|---|---|
upstream-undefined / -orphan | высокая / низкая | Маршрут ссылается на несуществующий пул; пул объявлен, но нигде не используется |
upstream-member-down | высокая | Локальный бэкенд пула не слушает свой порт |
all-backends-disabled | критическая | Все серверы в пуле помечены down/backup |
single-backend / backend-no-healthcheck | инфо / средняя | Нет избыточности; нет health-check при нескольких серверах |
container-restarting | высокая | Контейнер застрял в цикле перезапуска |
container-not-running / -undeclared / -no-restart-policy | средняя / низкая / низкая | Объявлен, но не запущен; запущен, но не объявлен; нет политики перезапуска |
admin-interface-open | высокая/средняя | Панель статистики haproxy доступна без пароля |
malware-* | критическая–средняя | Майнер в процессах или контейнере, соединение с пулом, удалённый/временный бинарник, ld.so.preload, cron «curl | sh», юнит из /tmp, чужой SUID, блокировки в /etc/hosts |
docker-cli-missing | средняя | Демон docker работает, а команды docker нет (Debian 13: docker.io без docker-cli) |