Укрепление безопасности образов контейнеров с помощью Wazuh и Trivy

Эта статья черпает вдохновение из записи в блоге Wazuh о повышении безопасности образов контейнеров с помощью Wazuh и Trivy.

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

Однако эта гибкость может создавать риски для безопасности, если образы контейнеров не защищены должным образом.

Уязвимости в этих образах могут подвергнуть всю вашу систему угрозам.

Вот где вступает в игру совместная мощь Wazuh и Trivy.

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

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

Образы контейнеров — это строительные блоки ваших контейнеризованных приложений.

Одна единственная уязвимость внутри образа может поставить под угрозу всю вашу систему, что приведет к:

Утечкам данных: Конфиденциальные данные могут быть доступны неавторизованным лицам.

Сбоям в обслуживании: Атаки могут вызвать простой и нарушить бизнес-операции.

Ущербу репутации: Инциденты безопасности могут подорвать доверие и нанести ущерб вашему бренду.

Проактивные меры безопасности, такие как интеграция Wazuh и Trivy, необходимы для снижения этих рисков.

Знакомство с Trivy: ваш сканер уязвимостей

Trivy — это быстрый и всесторонний сканер уязвимостей с открытым исходным кодом, который легко интегрируется в ваш CI/CD-конвейер. Он сканирует образы ваших контейнеров на наличие:

Уязвимостей операционной системы: Обнаруживает устаревшие пакеты и известные слабые места в базовой ОС.

Зависимостей приложений: Выявляет уязвимости в библиотеках и фреймворках, используемых вашим приложением.

Ошибок конфигурации: Раскрывает ошибки конфигурации безопасности, которые могут расширить вашу поверхность атаки.

Предварительные требования

Выполните все те же шаги по установки Trivy что и в оригинальной статье Так же необходимо установить docker библиотеку для python

pip install docker

Интеграция Trivy с Wazuh

Как и в оригинальной статье, необходимо написать скрипт интеграции между Trivy и Wazuh, но в отличие от оригинальной статьи я предпочитаю использовать python.

Скрипт следует создать на агенте, который вы планируете отслеживать. При этом его также можно запускать на сервере, но важно помнить: скрипт должен выполняться на той системе, где вы намерены проводить сканирование.

Создаем директорию

mkdir /var/ossec/custom-script

Эту директорию мы и будет использовать для нашего скрипта. Теперь пришло время создать скрипт для сканирования

vi /var/ossec/custom-script/trivy_scanner.py

Сам скрипт будет выглядеть следующем образом

#!/usr/bin/env python
import json
import subprocess
import sys
import docker


def get_all_images():
    client = docker.from_env()
    image_names = list({image.tags[0] for image in client.images.list() if image.tags})
    return image_names


def scan_result(images: list):
    all_results = []
    for image in images:
        if not images or images == [""]:
            print("No images found. Exiting...")
            sys.exit(1)
        try:
            result = subprocess.run(['trivy', 'image', image, '--format', 'json', '--scanners', 'vuln'],
                                    capture_output=True, text=True,
                                    check=True)
            trivy_json = json.loads(result.stdout)
            for result in trivy_json.get("Results", []):
                for vuln in result.get("Vulnerabilities", []):
                    pkg_name = vuln.get("PkgName", "N/A")
                    installed_version = vuln.get("InstalledVersion", "N/A")
                    vuln_id = vuln.get("VulnerabilityID", "N/A")
                    severity = vuln.get("Severity", "N/A")
                    title = vuln.get("Title", "N/A")
                    trivy_result = {
                        'image': image,
                        'package': pkg_name,
                        'version': installed_version,
                        'vulnerability_id': vuln_id,
                        'severity': severity,
                        'title': title
                    }
                    print(json.dumps(trivy_result))
        except (FileNotFoundError, subprocess.CalledProcessError, json.JSONDecodeError) as error:
            all_results.append({"error": str(error)})  # Log errors


if __name__ == '__main__':
    scan_result(get_all_images())

Сохраняем скрипт и устанавливаем необходимые права доступа.

chmod 750 /var/ossec/custom-script/trivy_scanner.py
chown root:wazuh -R /var/ossec/custom-script/ 

Далее нужно создать правила для выявления уязвимостей. Создаем файл /var/ossec/etc/rules/trivy_rules.xml с содержанием


<group name="trivy,">
  <!-- Parent Rule for Trivy alerts -->
  <rule id="100201" level="0">
    <decoded_as>json</decoded_as>
    <description>Trivy alert detected.</description>
  </rule>

  <!-- This rule detects a critical severity vulnerability in a container image -->
  <rule id="100202" level="14">
    <if_sid>100201</if_sid>
    <field name="severity">CRITICAL</field>
    <description>Trivy alert [CRITICAL]: Vulnerabilty '$(vulnerability_id)' detected in package '$(package)' version '$(version)' on container image '$(image)'.</description>
  </rule>

  <!-- This rule detects a high severity vulnerability in a container image -->
  <rule id="100203" level="12">
    <if_sid>100201</if_sid>
    <field name="severity">HIGH</field>
    <description>Trivy alert [HIGH]: Vulnerabilty '$(vulnerability_id)' detected in package '$(package)' version '$(version)' on container image '$(image)'.</description>
  </rule>

  <!-- This rule detects a medium severity vulnerability in a container image -->
  <rule id="100204" level="7">
    <if_sid>100201</if_sid>
    <field name="severity">MEDIUM</field>
    <description>Trivy alert [MEDIUM]: Vulnerabilty '$(vulnerability_id)' detected in package '$(package)' version '$(version)' on container image '$(image)'.</description>
  </rule>

  <!-- This rule detects a low severity vulnerability in a container image -->
  <rule id="100205" level="4">
    <if_sid>100201</if_sid>
    <field name="severity">LOW</field>
    <description>Trivy alert [LOW]: Vulnerabilty '$(vulnerability_id)' detected in package '$(package)' version '$(version)' on container image '$(image)'.</description>
  </rule>

  <!-- This rule detects an unknown severity vulnerability in a container image -->
  <rule id="100206" level="7">
    <if_sid>100201</if_sid>
    <field name="severity">UNKNOWN</field>
    <description>Trivy alert [UNKNOWN]: Vulnerabilty '$(vulnerability_id)' detected in package '$(package)' version '$(version)' on container image '$(image)'.</description>
  </rule>
</group>

После этого настраиваем Wazuh для запуска нашего скрипта, для этого необходимо внести изменения в файл ossec.conf

vi /var/ossec/etc/ossec.conf 

Добавляем запуск скрипта

<wodle name="command">
  <disabled>no</disabled>
  <command>/var/ossec/custom-script/trivy_scanner.py</command>
  <interval>6d</interval>
  <ignore_output>no</ignore_output>
  <run_on_start>yes</run_on_start>
  <timeout>0</timeout>
</wodle>

Интервал запуска скрипта можно настроить под ваши потребности; в моём примере он установлен на каждые 6 дней. Сохраняем и перезапускам

systemctl restart wazuh-manager.service 

Перезапускаем агент

systemctl restart wazuh-agent

После этого вы начнете получать результаты сканирования.

Пример события:

2025 Mar 28 14:24:07 compute-vm-14-28-100-ssd-1740727139038->command_
Rule: 100202 (level 14) -> 'Trivy alert [CRITICAL]: Vulnerabilty 'CVE-2023-45853' detected in package 'zlib1g' version '1:1.2.13.dfsg-1' on container image 'nginx:stable'.'
{"image": "nginx:stable", "package": "zlib1g", "version": "1:1.2.13.dfsg-1", "vulnerability_id": "CVE-2023-45853", "severity": "CRITICAL", "title": "zlib: integer overflow and resultant heap-based buffer overflow in zipOpenNewFileInZip4_6"}
image: nginx:stable
package: zlib1g
version: 1:1.2.13.dfsg-1
vulnerability_id: CVE-2023-45853
severity: CRITICAL
title: zlib: integer overflow and resultant heap-based buffer overflow in zipOpenNewFileInZip4_6

Смотрите также