Skip to content

Обзор, проблемы, карта ресурсов ​

Первые разделы меню отвечают на главный вопрос: что на хосте на самом деле происходит и что сломано. Конфиги 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

Установка 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)