惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
S
Schneier on Security
Forbes - Security
Forbes - Security
Cisco Talos Blog
Cisco Talos Blog
月光博客
月光博客
T
Threat Research - Cisco Blogs
I
InfoQ
量子位
NISL@THU
NISL@THU
C
Cisco Blogs
云风的 BLOG
云风的 BLOG
P
Privacy & Cybersecurity Law Blog
The Register - Security
The Register - Security
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
AWS News Blog
AWS News Blog
T
Troy Hunt's Blog
M
MIT News - Artificial intelligence
B
Blog
T
Tor Project blog
有赞技术团队
有赞技术团队
Hacker News: Ask HN
Hacker News: Ask HN
Y
Y Combinator Blog
L
LangChain Blog
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
L
LINUX DO - 热门话题
Schneier on Security
Schneier on Security
Cloudbric
Cloudbric
H
Hacker News: Front Page
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
V
V2EX
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
O
OpenAI News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 叶小钗
宝玉的分享
宝玉的分享
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Scott Helme
Scott Helme
Recorded Future
Recorded Future
Simon Willison's Weblog
Simon Willison's Weblog
J
Java Code Geeks
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
美团技术团队

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Инвентаризируем контейнеры с помощью Wazuh-агента
efer1992 · 2026-06-26 · via Все публикации подряд на Хабре

Контейнерные среды меняются быстро: новые образы разворачиваются автоматически, конфигурации обновляются в CI/CD-пайплайнах. Без непрерывной инвентаризации вы не знаете, что именно запущено прямо сейчас: какой образ, с каким дайджестом, из какого реестра, с какими привилегиями. 

На практике это означает, что небезопасная конфигурация или неподконтрольный образ могут месяцами работать незамеченными в вашей инфраструктуре. И позднее, когда возникнет инцидент или аудит, придется выяснять вручную, какие контейнеры были запущены и соответствуют ли они вообще требованиям безопасности. 

Автоматическая инвентаризация позволяет превратить эту информацию в события мониторинга и получать уведомления сразу же после появления, например, «рискованных» конфигураций.

На связи Андрей, руководитель направления безопасности облака в Selectel. Ранее я рассказывал про сам инструмент Wazuh и его функциональность, а в этой статье покажу пример использования механизма wodle command на практической задаче.

Wodle (сокращение от Wazuh module) — это модуль, который расширяет возможности агента. Он предназначен для выполнения целого ряда задач от сбора данных из внешних источников до запуска сканеров безопасности или выполнения пользовательских сценариев.

Проще говоря, это легковесный «плагин» к агенту Wazuh. Он работает в фоновом режиме, выполняет свою задачу, а результаты в виде логов отправляет менеджеру для дальнейшего анализа

Вкратце об архитектуре решения

Схема потока данных выглядит так: скрипт запускается агентом Wazuh по расписанию, обращается к Docker CLI и выводит JSON в stdout. Wazuh перехватывает вывод и отправляет его менеджеру в виде отдельных событий. 

Схема потока данных.

Схема потока данных.

Security Center

Рассказываем о лучших практиках и средствах ИБ, требованиях и изменениях в законодательстве.

Исследовать →

Шаг 1. Скрипт инвентаризации

Перейдем к самому скрипту. Он совместим с любым окружением Linux. Сохраните его по пути /var/ossec/custom-scripts/container_inventory.sh и выдайте права на исполнение.

#!/bin/sh

# Проверяем наличие docker и доступность демона
command -v docker >/dev/null 2>&1 || exit 0
docker info >/dev/null 2>&1 || exit 0

docker ps --format "{{.Names}}|{{.ID}}" | while IFS="|" read -r name cid; do
  image=$(docker inspect --format '{{.Config.Image}}' "$cid" 2>/dev/null)
  [ -z "$image" ] && continue

  # Разбиваем repo:tag
  lastpart="${image##*/}"
  if echo "$lastpart" | grep -q ':'; then
    tag="${lastpart##*:}"
    repo="${image%:${tag}}"
  else
    tag="latest"
    repo="$image"
  fi

  # Определяем реестр по первому сегменту пути
  first="${repo%%/*}"
  if [ "$repo" = "$first" ]; then
    registry="docker.io"
  elif echo "$first" | grep -qE "\\.|:"; then
    registry="$first"
  else
    registry="docker.io"
  fi

  # Digest
  digests=$(docker image inspect --format "{{json .RepoDigests}}" "$image" 2>/dev/null)
  if [ -z "$digests" ] || [ "$digests" = "[]" ]; then
    digest="N/A"
    [ "$registry" = "docker.io" ] && registry="local"
  else
    digest=$(docker image inspect --format "{{index .RepoDigests 0}}" "$image" 2>/dev/null)
  fi

  # Привилегии, пользователь, capabilities
  ainfo=$(docker inspect \
    --format "{{.HostConfig.Privileged}}|{{.Config.User}}|{{json .HostConfig.CapAdd}}|{{json .HostConfig.CapDrop}}" \
    "$cid" 2>/dev/null)
  privileged="${ainfo%%|*}"
  r="${ainfo#*|}"
  user="${r%%|*}"
  r="${r#*|}"
  capadd="${r%%|*}"
  capdrop="${r##*|}"

  [ -z "$user" ]         && user="root"
  [ "$capadd" = "null" ] && capadd="[]"
  [ "$capdrop" = "null" ] && capdrop="[]"

  printf '{"type":"container_inventory","name":"%s","repo":"%s","tag":"%s","registry":"%s","privileged":%s,"user":"%s","cap_add":%s,"cap_drop":%s,"digest":"%s"}\n' \
    "$name" "$repo" "$tag" "$registry" "${privileged:-false}" \
    "$user" "$capadd" "$capdrop" "${digest:-N/A}"
done

exit 0

Установка прав:

chmod 750 /var/ossec/custom-scripts/container_inventory.sh
chown root:wazuh /var/ossec/custom-scripts/container_inventory.sh

Шаг 2. Конфигурация Wazuh-агента (wodle command)

На узле, где установлен Wazuh-агент, откройте файл /var/ossec/etc/ossec.conf и добавьте в секцию <ossec_config>следующий блок конфигурации:


      <!-- ossec.conf агента -->
<ossec_config>

  <wodle name="command">
    <disabled>no</disabled>

    <!-- Тег для фильтрации в дашборде -->
    <tag>container_inventory</tag>

    <command>/var/ossec/custom-scripts/container_inventory.sh</command>

    <!-- Интервал: каждые 6 часов -->
    <interval>6h</interval>

    <!-- ignore_output=no: передаём stdout в Wazuh -->
    <ignore_output>no</ignore_output>

    <!-- Таймаут: 60 секунд -->
    <timeout>60</timeout>

    <!-- Запускать сразу при старте агента -->
    <run_on_start>yes</run_on_start>
  </wodle>

</ossec_config>

Здесь механизм wodle command запускает произвольные команды по расписанию и перехватывает их вывод как события Wazuh.

После изменения конфигурации перезапустите Wazuh-агента:

systemctl restart wazuh-agent
# или
/var/ossec/bin/wazuh-control restart

Структура событий

Прежде чем приступить к настройке правил алертинга важно отметить, что строка вывода скрипта — это отдельное JSON-событие. Рассмотрим пример такого события:

{
  "type":       "container_inventory",
  "name":       "nginx-prod",
  "repo":       "nginx",
  "tag":        "1.25-alpine",
  "registry":   "docker.io",
  "privileged": false,
  "user":       "nginx",
  "cap_add":    [],
  "cap_drop":   ["ALL"],
  "digest":     "nginx@sha256:a49e14a8..."
}

Ниже для удобства привожу «шпаргалку» с описанием полей и их типами.

Поле

Тип

Описание

Интерес для ИБ

name

string

Имя контейнера

Позволяет быстро определить, какой сервис связан с событием безопасности. Упрощает расследование подозрительной сетевой активности и анализ инцидентов.

repo

string

Имя образа без тега

Используется для контроля происхождения образов и инвентаризации контейнерной среды. Появление образов из неутвержденных репозиториев может указывать на нарушение процессов поставки ПО.

tag

string

Тег образа. latest, если не задан

Помогает отслеживать версии приложений и сопоставлять их с известными уязвимостями. Использование latest усложняет аудит и воспроизводимость развертываний.

registry

string

Источник образа (docker.io, local, свой реестр)

Позволяет контролировать использование доверенных реестров. Образы из внешних или неавторизованных источников требуют дополнительной проверки.

privileged

bool

Признак запуска в привилегированном режиме

Один из наиболее важных признаков риска. Привилегированный контейнер получает расширенный доступ к ресурсам хоста и существенно увеличивает последствия возможной компрометации.

user

string

Пользователь внутри контейнера

Помогает проверить соблюдение принципа минимальных привилегий. Запуск процессов от root повышает риск развития атаки после получения доступа к контейнеру.

cap_add

array

Добавленные Linux-привилегии (capabilities) 

Позволяет выявить контейнеры с расширенными системными возможностями. Особое внимание стоит уделять CAP_SYS_ADMINCAP_SYS_PTRACE и другим привилегированным capabilities.

cap_drop

array

Отозванные capabilities

Показывает, какие возможности были дополнительно ограничены. Наличие ALL обычно свидетельствует о более строгой конфигурации безопасности контейнера.

digest

string

SHA256-дайджест манифеста. N/A — для локальных образов

Позволяет однозначно идентифицировать конкретную версию образа. Полезен для контроля целостности и выявления неподписанных или неучтенных артефактов.

Шаг 3. Настройка правил алертинга в Wazuh

Добавьте правила в /var/ossec/etc/rules/local_rules.xml на менеджере. Wazuh декодирует JSON-поля автоматически через динамический декодер.

В примере ниже используются несколько простых правил, которые позволяют выявлять наиболее распространенные проблемы: запуск привилегированных контейнеров, использование тега latest, работу от root и применение локальных образов без подтвержденного источника.

<group name="container_inventory,">

  <!-- Базовое правило: принимаем все события инвентаризации -->
  <rule id="100200" level="0">
    <decoded_as>json</decoded_as>
    <field name="type">^container_inventory$</field>
    <description>Container inventory event</description>
  </rule>

  <!-- Привилегированный контейнер — высокий уровень -->
  <rule id="100201" level="12">
    <if_sid>100200</if_sid>
    <field name="privileged">^true$</field>
    <description>Privileged container detected: $(name)</description>
    <group>docker_security,privileged_container</group>
  </rule>

  <!-- Контейнер с расширенными capabilities -->
  <rule id="100202" level="10">
    <if_sid>100200</if_sid>
    <field name="cap_add">^\["[^"]+"\]</field>
    <description>Container with extra capabilities: $(name) cap_add=$(cap_add)</description>
    <group>docker_security,capability_escalation</group>
  </rule>

  <!-- Образ с тегом latest -->
  <rule id="100203" level="5">
    <if_sid>100200</if_sid>
    <field name="tag">^latest$</field>
    <description>Container running 'latest' tag: $(name) / $(repo)</description>
    <group>docker_inventory,untagged_image</group>
  </rule>

  <!-- Контейнер запущен от root -->
  <rule id="100204" level="7">
    <if_sid>100200</if_sid>
    <field name="user">^root$</field>
    <description>Container process running as root: $(name)</description>
    <group>docker_security,root_container</group>
  </rule>

  <!-- Локальный образ (не из реестра) -->
  <rule id="100205" level="8">
    <if_sid>100200</if_sid>
    <field name="registry">^local$</field>
    <description>Container using local image (no registry): $(name) / $(repo)</description>
    <group>docker_security,local_image</group>
  </rule>

</group>

Шаг 4. Поиск событий в Wazuh Dashboards

После настройки правил полезно проверить, какие данные поступают в индекс и как они выглядят в поиске. Проще всего сделать это через Discover в Wazuh Dashboards. Ниже привожу несколько запросов, которые помогают быстро выявить потенциально рискованные контейнеры и проверить качество инвентаризации.

# Все события инвентаризации
data.type: container_inventory

# Только привилегированные контейнеры
data.type: container_inventory AND data.privileged: true

# Контейнеры с добавленными capabilities
data.type: container_inventory AND data.cap_add: [* TO *]

# Образы не из корпоративного реестра
data.type: container_inventory AND NOT data.registry: "registry.company.internal"

# Контейнеры с тегом latest, запущенные от root
data.type: container_inventory AND data.tag: "latest" AND data.user: "root"

Например, запрос по привилегированным контейнерам позволяет быстро выявить сервисы с повышенными правами на хосте. Поиск образов не из корпоративного реестра помогает контролировать происхождение контейнеров и обнаруживать отклонения от вашей принятой политики.

Рекомендации по безопасности

На основе данных инвентаризации вы можете сразу улучшить конфигурацию контейнеров. Рассмотрим снова на примере небольшой «шпаргалки».

Проблема

Риск

Рекомендация

privileged: true

Контейнер имеет полный доступ к хосту

Убрать --privileged, заменить на конкретные capabilities

user: root

Эскалация при побеге из контейнера

Добавить USER в Dockerfile или --user при запуске

tag: latest

Непредсказуемые обновления, нет проверки целостности

Использовать фиксированные теги или digest-ссылки

registry: local

Образ создан вручную, нет аудит-следа

Пушить все образы в корпоративный реестр со сканированием

cap_add: [NET_ADMIN]

Возможность изменить сетевые настройки хоста

Добавить cap_drop: ALL + только необходимые capabilities

Эти проверки не заменяют анализ образов на этапе CI/CD, но позволяют быстро выявить отклонения в уже работающей инфраструктуре. На практике наиболее полезными обычно оказываются контроль привилегированных контейнеров, запуска от root и использования неподконтрольных образов.

Расширение скрипта

Базовый вариант собирает только сведения об образе и привилегиях контейнера. При необходимости вы можете дополнить его данными о сетевых настройках, точках монтирования и окружении процесса. Предлагайте в комментариях, какие пути расширения видите — будет интересно обсудить.

Порты и сетевые настройки

Информация о проброшенных портах и сетевом режиме помогает выявлять сервисы с неожиданной сетевой доступностью или использованием host-сети.

ports=$(docker inspect --format \
  '{{range $p, $conf := .NetworkSettings.Ports}}{{$p}}{{end}}' \
  "$cid" 2>/dev/null | tr '\n' ',')
network_mode=$(docker inspect --format '{{.HostConfig.NetworkMode}}' "$cid")

Смонтированные volumes

Данные о монтированиях полезны для поиска контейнеров с доступом к чувствительным каталогам хоста.

mounts=$(docker inspect --format '{{json .Mounts}}' "$cid")

Переменные среды (с маскированием секретов)

Переменные окружения могут содержать секреты и параметры подключения к внешним системам, поэтому их сбор требует дополнительной осторожности.

env_list=$(docker inspect --format '{{json .Config.Env}}' "$cid" | \
  sed 's/"[^"]*PASSWORD[^"]*"/"REDACTED"/gi')

Внимание! Не логируйте переменные среды без маскирования — они часто содержат токены, пароли и ключи API, которые могут попасть в индекс Wazuh и стать видимыми в дашборде.

Таймаут на большом количестве контейнеров

При 50+ контейнерах вызовы docker inspect могут занять больше 60 секунд. Увеличьте значение <timeout> в конфиге или оптимизируйте скрипт, объединив несколько inspect-вызовов в один.

Что в итоге

С помощью wodle command можно быстро расширить возможности Wazuh и собирать данные, которые отсутствуют в стандартной поставке агента. В рассмотренном примере мы настроили инвентаризацию контейнеров и превратили сведения об образах, привилегиях и настройках безопасности в события мониторинга и алерты.

Такой подход не заменяет проверку образов на этапе CI/CD и сканирование уязвимостей до развертывания, но помогает контролировать фактическое состояние контейнерной среды. Это особенно полезно в динамичной инфраструктуре, где контейнеры регулярно пересоздаются, обновляются или запускаются из разных пайплайнов.

При необходимости аналогичный механизм можно адаптировать для Podman, CRI-O или других контейнерных рантаймов, а сам скрипт дополнить сбором сетевых настроек, томов и других параметров, важных для вашей модели угроз. Если вы используете Wazuh для мониторинга контейнеров или собираете похожую инвентаризацию другими способами — расскажите в комментариях, какие проверки оказались наиболее полезными в вашей инфраструктуре.

Снижаем цены на выделенные серверы в реальном времени

Успейте арендовать со скидкой до 35%, пока лот не ушел другому.

Подробнее →