Как обнаружить и убрать майнер (Kinsing / kdevtmpfsi) с Docker-сервера — подробный практический гайд

Инструкция по обнаружению, изоляции, удалению майнера из контейнера и защите сервера: логи, команды, примеры, чек‑лист и рекомендации по предотвращению повторного взлома.


Введение

Майнеры (например, Kinsing, kdevtmpfsi, xmrig) — частая проблема на публично доступных серверах и контейнерах. Они чаще проникают через открытые/незащищённые сервисы (ssh с паролем, Docker API на 2375, уязвимости веб‑приложений). Важно действовать быстро и аккуратно: минимально останавливать сервисы при критичном продакшне, собрать доказательства и затем восстановить.


Что мы делали (коротко)

  1. Зафиксировали артефакты из контейнера: docker cp и sha256sum бинарников.
  2. Остановили/скопировали подозрительный контейнер и удалили майнеры из файловой системы контейнера.
  3. Просканировали процессы, сетевые соединения и правила iptables/DOCKER-NAT.
  4. Проверили настройки PHP‑FPM / nginx (fastcgi_pass) и сопоставление портов Docker.
  5. Ввели временные iptables/ufw‑правила, установили fail2ban.
  6. Пересобрали инфицированный контейнер из чистого образа, сменили порты и проверили работу.

Детальные шаги и команды (пошагово)

1) Сохранение «вещественных доказательств» и бэкап

  • Скопировать бинарники из контейнера локально для анализа:
docker stop tg-crm-app
docker cp tg-crm-app:/tmp/backup_miner /root/backup_miner_from_container
ls -lah /root/backup_miner_from_container
sha256sum /root/backup_miner_from_container/*
file /root/backup_miner_from_container/*

Сохраняйте хэши (sha256) — пригодятся при расследовании и блокировке сигнатур средствами EDR/AV.


2) Поиск и уничтожение запущенных бинарников

ps aux | egrep 'kdevtmpfsi|kinsing|xmrig' -n
# удалить файлы и процессы (осторожно, убедитесь что это именно майнер)
docker exec tg-crm-app rm -f /tmp/kinsing /tmp/kdevtmpfsi /tmp/kinsing* /tmp/kdevtmpfsi*

Примечание: иногда майнеры ставят systemd/unit файлы или crontab; проверьте systemctl, /etc/cron*, /var/spool/cron.


3) Сетевая проверка — какие порты проброшены и кто слушает

  • Список контейнеров и их портов:
docker ps --format "table {{.Names}}\t{{.Ports}}"
  • NAT‑правила Docker в iptables (DNAT):
sudo iptables -t nat -L -n -v
  • Общие правила и блокировки:
sudo iptables -L -n -v --line-numbers
sudo iptables -t nat -L DOCKER -n -v
sudo iptables -L DOCKER-USER -n -v --line-numbers

Если сайт не отвечает, проверьте, что php‑fpm слушает на ожидаемом интерфейсе, а nginx настраивает fastcgi на правильный хост/порт:

docker exec tg-crm-app grep -n "^listen" /usr/local/etc/php-fpm.d/www.conf
docker exec nginx-tg-crm grep -Rni "fastcgi_pass|upstream" /etc/nginx

4) Когда сайт упал из‑за блока порта

В реальном случае порт 9000 (php‑fpm) был заблокирован iptables/ufw. Проверили и увидели DROP tcp dpt:9000 / DROP tcp dpt:9567 и DNAT записи в nat цепочке Docker. Решение — либо удалить «drop» правило, либо изменить порт на безопасный и пересобрать контейнер. Примеры команд правки Docker run:

# Пересоздание контейнера с переменной FPM_LISTEN_PORT
docker rm -f tg-crm-app && docker run -d --name tg-crm-app --network tg-crm_default -e FPM_LISTEN_PORT=9567 tg-crm-php-fpm

Если iptables блокирует DNAT трафик — добавьте правило в DOCKER-USER или удалите DROP там.


5) Проверка логов аутентификации (SSH) и истории входов

  • Просмотреть попытки входа SSH (journalctl):
journalctl -u ssh -S "2025-10-20" --no-pager | tail -n 200
  • last, who, sshd — чтобы понять, кем и откуда подключались.

Если вы видите множество Failed password — это брутфорс. Признак успешного взлома — строка Accepted password или Accepted publickey (в логах). Обратите внимание на IP и время.


6) Установка и настройка Fail2Ban

Установите и настройте fail2ban для SSH и других сервисов (пример секции sshd в /etc/fail2ban/jail.local):

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
ignoreip = 127.0.0.1/8 109.71.229.151 144.31.2.208

Запуск:

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

7) Блокировка Docker API и других опасных сервисов

  • Проверьте, не слушает ли Docker daemon порт 2375 (небезопасный, без TLS):
sudo ss -ltnp | grep 2375 || true
  • Если Docker API открыт — закройте/защитите его (разрешать только через unix socket или включить TLS).

8) Очистка образов/контейнеров и восстановление

  1. Удалите заражённый контейнер docker rm -f <name>.
  2. Пересоберите образ из исходников или вытяните чистый образ из доверенного реестра.
  3. Замените секреты/пароли, пересоздайте контейнер с новыми переменными окружения.

Важно: не перезапускайте заражённый контейнер — сначала создайте копию образа/данных для анализа.


Чек‑лист безопасности (после инцидента)

  • Установить Fail2Ban и настроить SSH без паролей (только ключи).
  • Отключить root‑логин по паролю в /etc/ssh/sshd_config (PermitRootLogin prohibit-password).
  • Отключить Docker API на 2375 или ограничить доступ по сети/TLS.
  • Включить UFW: ufw default deny incoming; ufw allow 22; ufw allow 80; ufw allow 443.
  • Проверить crontab, systemd‑units, /tmp и /var/tmp на неизвестные исполняемые файлы.
  • Просканировать образы на наличия встроенных бэктреков/скриптов сборки.
  • Сменить ключи и пароли (особенно для аккаунтов с доступом).
  • Внедрить мониторинг (CPU spike alerts), EDR/AV если можно.

Где обычно «прорываются» майнеры

  • Открытые SSH с паролями — автоматические брутфорс‑боты.
  • Открытый Docker API (2375) — позволяет запустить контейнеры/ползунов прямо удалённо.
  • Уязвимости веб‑приложений (RCE) и устаревшие CMS.
  • Скомпрометированные CI/CD секреты, ключи доступа.

Почему часто заражается только один контейнер

  • Взломщик ищет путь с наименьшим сопротивлением — попав в один контейнер, он может запускать майнеры только в нём (или в контейнер с доступом к сети хоста). Если у контейнера нет прав на Docker socket, он не сможет создать новые контейнеры.
  • Возможно, заражённый контейнер был запущен с уязвимыми томами/переменными, через которые загрузили бинарь.
  • Если вы быстро остановили и удалили контейнер — «следы» на хосте могут быть минимальны.

Полезные команды для расследования (подборка)

# Поиск странных файлов
find / -type f -name 'kinsing*' -o -name 'kdevtmpfsi*' 2>/dev/null
# Процессы
ps aux | egrep 'kdevtmpfsi|kinsing|xmrig|minerd'
# Docker
docker ps -a
docker inspect --format '{{json .NetworkSettings.Networks}}' <container>
# Сетевые соединения
ss -ltnp
netstat -tnp | grep ESTABLISHED
# Логи SSH
journalctl -u ssh -S "2025-10-20" --no-pager | tail
# Iptables
sudo iptables -L -n -v --line-numbers
sudo iptables -t nat -L -n -v --line-numbers

Рекомендации на будущее (проактивно)

  • Запретить вход по паролю (включить PasswordAuthentication no).
  • Разогнать доступ SSH по IP (firewall + fail2ban + allowlist).
  • Не пробрасывать Docker socket в контейнеры (-v /var/run/docker.sock:/var/run/docker.sock — опасно).
  • Хранить секреты в vault (HashiCorp/Cloud provider) вместо ENV.
  • Регулярные обновления образов, ОС и зависимостей.
  • Ограничить права контейнеров (user namespaces, readonly rootfs, seccomp, capabilities).

Заключение

Инцидент с майнером — неприятен, но часто решается быстро: сохранить доказательства, удалить заражённый контейнер, пересобрать образ из проверенных источников и усилить доступы: отключить SSH‑пароли, поставить fail2ban, закрыть Docker API и настроить firewall. Если нужно — я подготовлю отдельную страницу в формате Markdown/HTML с разметкой для SEO и готовыми картинками/подсказками по скриншотам.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

MrRoot
Обновлено: 23 октября, 2025