Пост

Работа с образами в Docker. Часть 3

Поиск проблем в безопасности образов и способы их устранения

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

🔨 Сканер безопасности Trivy

Комплексное решение для сбора информации об образе, поиска известных уязвимостей (CVE), секретов и ошибок конфигураций.

🔸 Актуальную версию берем из релизов репозитория.

1
2
wget https://github.com/aquasecurity/trivy/releases/download/v0.58.1/trivy_0.58.1_Linux-64bit.deb
sudo dpkg -i trivy_0.58.1_Linux-64bit.deb

🔸 Пример работы инструмента с выводом результатов в табличном виде в консоль. Параметр --ignore-unfixed позволяет отфильтровать результаты, которые, по мнению trivy, нельзя исправить.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
trivy image testapp-image-name --ignore-unfixed

2025-01-06T23:50:29+03:00       INFO    [vuln] Vulnerability scanning is enabled
2025-01-06T23:50:29+03:00       INFO    [secret] Secret scanning is enabled
2025-01-06T23:50:29+03:00       INFO    Detected OS     family="debian" version="12.8"
2025-01-06T23:50:29+03:00       INFO    [debian] Detecting vulnerabilities...   os_version="12" pkg_num=105
2025-01-06T23:50:29+03:00       INFO    Number of language-specific files       num=1
2025-01-06T23:50:29+03:00       INFO    [python-pkg] Detecting vulnerabilities...

testapp-image-name (debian 12.8)

Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

2025-01-06T23:50:29+03:00       INFO    Table result includes only package filenames. Use '--format json' option to get the full path to the package file.

Python (python-pkg)

Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 1, CRITICAL: 0)

┌───────────────────────┬────────────────┬──────────┬────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
│        Library        │ Vulnerability  │ Severity │ Status │ Installed Version │ Fixed Version │                            Title                            │
├───────────────────────┼────────────────┼──────────┼────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
│ certifi (METADATA)    │ CVE-2024-39689 │ LOW      │ fixed  │ 2024.6.2          │ 2024.07.04    │ python-certifi: Remove root certificates from `GLOBALTRUST` │
│                       │                │          │        │                   │               │ from the root store                                         │
│                       │                │          │        │                   │               │ https://avd.aquasec.com/nvd/cve-2024-39689                  │
├───────────────────────┼────────────────┼──────────┤        ├───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
│ pip (METADATA)        │ CVE-2023-5752  │ MEDIUM   │        │ 23.0.1            │ 23.3          │ pip: Mercurial configuration injectable in repo revision    │
│                       │                │          │        │                   │               │ when installing via pip                                     │
│                       │                │          │        │                   │               │ https://avd.aquasec.com/nvd/cve-2023-5752                   │
├───────────────────────┼────────────────┼──────────┤        ├───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
│ setuptools (METADATA) │ CVE-2024-6345  │ HIGH     │        │ 65.5.1            │ 70.0.0        │ pypa/setuptools: Remote code execution via download         │
│                       │                │          │        │                   │               │ functions in the package_index module in...                 │
│                       │                │          │        │                   │               │ https://avd.aquasec.com/nvd/cve-2024-6345                   │
└───────────────────────┴────────────────┴──────────┴────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘

🔸 Для получения более детальной информации по каждому найденному случаю сохраняем результат в json.

1
trivy image testapp-image-name -f json -o trivy_testapp.json

☑️ По умолчанию ищет секреты и уязвимости. Дополнительно можно включить режим поиска ошибок конфигурации и лицензий.

Вернемся к проверке результатов чуть позже, а пока следующий инструмент.

🔨 Программа для проверки образов Dockle

Dockle - линтер и аудитор образов. Проверяет соответствие лучшим практикам по аналогии с Hadolint и рекомендациям или показателям CIS Benchmark for Docker Центра интернет-безопаcности (CIS). Полный перечень метрик, их описание и способы достижения в документации к dockle.

🔸 Следуем инструкции по установке или забираем актуальную версию из репозитория.

1
2
wget https://github.com/goodwithtech/dockle/releases/download/v0.4.15/dockle_0.4.15_Linux-64bit.deb
sudo dpkg -i dockle_0.4.15_Linux-64bit.deb

🔸 Пример вызова

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# с сохранением в json
dockle -f json -o dockle_testapp.json testapp-image-name

# с выводом в консоль
dockle testapp-image-name

WARN    - CIS-DI-0001: Create a user for the container
        * Last user should not be root
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO    - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
        * not found HEALTHCHECK statement
INFO    - CIS-DI-0008: Confirm safety of setuid/setgid files
        * setuid file: urwxr-xr-x usr/bin/umount
        * setuid file: urwxr-xr-x usr/bin/chfn
        * setuid file: urwxr-xr-x usr/bin/passwd
        * setuid file: urwxr-xr-x usr/bin/newgrp
        * setgid file: grwxr-xr-x usr/sbin/unix_chkpwd
        * setgid file: grwxr-xr-x usr/bin/chage
        * setuid file: urwxr-xr-x usr/bin/su
        * setgid file: grwxr-xr-x usr/bin/expiry
        * setuid file: urwxr-xr-x usr/bin/chsh
        * setuid file: urwxr-xr-x usr/bin/gpasswd
        * setuid file: urwxr-xr-x usr/bin/mount
INFO    - DKL-LI-0003: Only put necessary files
        * unnecessary file : testapp/Dockerfile

❗️❓ Несколько важных моментов касательно рассмотренных выше утилит были отмечены в докладе Анатолия Карпенко из Luntry.

  • trivy имеет список исключений при сканировании секретов, согласно которому файлы, содержащие в имени test, example и другие будут проигнорированы, о чем следует помнить во время использования программы.

  • dockle проверяет фиксированный список имен файлов при поиске чувствительной информации, что также снижает эффективность инструмента в этой конкретной задаче.

⚒️ Syft и Grype

Про утилиту syft я уже рассказывал в предыдущей заметке цикла. Результаты ее работы использует сканер уязвимостей grype. Принцип аналогичен работе trivy - сканируем, формируем детальный отчет для дальнейшего анализа.

🔸 Собираем SBOMs с помощью syft

1
syft testapp-image-id -o syft-json=syft.json

🔸 Устанавливаем grype

1
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sudo sh -s -- -b /usr/local/bin

🔸 Запускаем с сохранением отчета в json

1
2
3
4
grype sbom:syft.json --output json --file grype.json
 ✔ Scanned for vulnerabilities     [93 vulnerability matches]
   ├── by severity: 1 critical, 3 high, 17 medium, 6 low, 60 negligible (6 unknown)
   └── by status:   6 fixed, 87 not-fixed, 0 ignored

⚡️ Способы устранения

trivy и grype на выходе предоставили нам отчеты в формате json, в которых описаны разной степени важности уязвимости в исследуемом образе. Часть из них может быть исправлена в автоматическом режиме и имеет соответствующую метку fixed, другая же часть не поддерживает исправление или вовсе неизвестна.

🔹 Как починить образ?

Используем программу для модификации слоев copa.

  • Добавляет патч слой к целевому образу и формирует новый, расширенный образ.
  • Работает на основе результатов сканнеров уязвимостей.
  • По умолчанию принимает результаты от trivi, однако, за счет возможности подключения плагинов, появилась и поддержка grype.

Пример вызова

1
sudo ./copa patch -i testapp_image_name -r trivy_testapp.json -t patched_testapp_image_name

🔹 Что еще можно сделать?

fixed уязвимости поправили, но остался целый пласт незатронутых проблем.

  • Заменить полный базовый образ системы на минималистичный (distroless, alpine) по возможности.
  • Поддерживать актуальные версии используемых библиотек и утилит.
  • Очистить образ от неиспользуемых ресурсов с помощью программы mint.
    • Убирает “ненужные” исполняемые файлы.
    • Отслеживает работу через временный контейнер, собираем детальную информацию об обращениях и вызовах приложения, генерирует новый, облегченный образ.
  • Удалить промежуточные слои со временными или чувствительными данными с помощью docker-squash.
Больше полезной информации в Telegram-канале