MAATRIX / Блог / Ботнет использовал ваш сервер для рассылки: последствия и разбор

Ботнет использовал ваш сервер для рассылки: последствия и разбор

MAATRIX

Письмо от хостера с темой «Abuse complaint» или внезапный отказ почты уходить наружу — обычно первый сигнал, что с сервера уже несколько часов льётся чужая рассылка. Сами вы это чаще всего не замечаете: сервер работает, сайт открывается, нагрузка на CPU не всегда даже заметна. А тем временем ваш IP уже попал в чёрные списки, и разгребать придётся не только техническую часть, но и репутацию домена на недели вперёд.

Как это обычно обнаруживается

В подавляющем большинстве случаев вы узнаёте о проблеме не сами, а со стороны:

  • Abuse-жалоба от хостера. Автоматика датацентра видит аномальный исходящий SMTP-трафик с вашего IP и присылает предупреждение — иногда с приложенным логом, иногда просто с требованием разобраться в течение 24-48 часов, иначе порт 25 блокируется, а в жёстких случаях сервер уходит в suspend.
  • Письмо от blacklist-провайдера (Spamhaus, SORBS, Barracuda и подобные) о том, что IP или домен внесён в список. Обычно приходит на abuse-контакт домена или технический e-mail из WHOIS.
  • Жалобы получателей — кто-то написал вам или в поддержку хостинга, что получил странное письмо якобы от вашего домена.
  • Собственная почта перестала уходить — вы заметили это, только когда попытались отправить письмо клиенту, а оно зависло в очереди или вернулось с ошибкой 550 от принимающего сервера ("blocked", "listed").

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

Диагностика: очередь и логи Postfix

Первым делом — не паниковать и не выключать сервер целиком, а посмотреть, что реально происходит с почтовой очередью.

Сколько писем стоит в очереди прямо сейчас:

mailq | tail -1
# или подробнее, с постраничным выводом
postqueue -p | less

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

# кто и через что отправляет — локальный процесс или сеть
grep "postfix/qmgr" /var/log/mail.log | tail -50

# массовая отправка через смтp-клиент (submission), а не через локальный sendmail
grep "postfix/smtpd" /var/log/mail.log | grep "client=" | awk -F'client=' '{print $2}' | awk -F'[' '{print $1}' | sort | uniq -c | sort -rn | head -20

# статистика по отправителям в очереди
mailq | grep -oE '^\S+@\S+' | sort | uniq -c | sort -rn | head -20

Обратите внимание на две принципиально разные картины:

  1. Письма уходят через локальный sendmail/PHP mail() — в логе видно postfix/pickup и postfix/cleanup без внешнего клиента. Это значит, что рассылку генерирует какой-то скрипт или процесс на самом сервере.
  2. Письма приходят через SMTP-авторизацию (submission, порт 587) от внешнего IP — это означает, что кто-то использует ваши учётные данные SMTP, подключаясь снаружи, а не через локальный скрипт.

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

Дополнительно проверьте темы и получателей в очереди — это подскажет, что именно рассылается:

postqueue -p | grep -B1 "MAILER-DAEMON" | head -20
mailq -j | python3 -m json.tool | head -50   # если доступен формат JSON (Postfix 3.x)

Если в очереди тысячи одинаковых по структуре писем на случайные адреса Gmail/Yahoo/Mail.ru с одинаковым содержимым (обычно реклама, фишинг или "письма счастья") — это классическая картина взлома.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Поиск скомпрометированного скрипта

Если рассылка идёт через локальный mail() (сценарий 1 выше), почти всегда источник — веб-приложение на этом же сервере. Типичные виновники:

  • Форма обратной связи без rate-limit и без проверки получателя — злоумышленник передаёт в скрипт произвольные заголовки (To, Cc, Bcc) через header injection, и скрипт послушно рассылает что угодно куда угодно.
  • Уязвимый плагин CMS — особенно старые версии WordPress-плагинов для форм и рассылок, устаревшие темы с включённым xmlrpc.php, заброшенные плагины без обновлений больше года.
  • Веб-шелл, залитый через уязвимость загрузки файлов — тогда рассылка идёт не через легитимный функционал сайта, а через отдельный PHP-файл, о существовании которого вы не подозревали.

Как искать:

# php-файлы, изменённые или созданные за последние 3 дня
find /var/www -name "*.php" -mtime -3 -type f

# подозрительные функции в свежих файлах
grep -rl "mail(\|shell_exec\|eval(\|base64_decode\|system(" /var/www/*/wp-content/uploads/ 2>/dev/null

# в access-логе веб-сервера — кто дергал подозрительные пути
grep -E "\.php" /var/log/nginx/access.log | grep -E "uploads|tmp|cache" | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

Отдельно проверьте, не является ли PHP-конфигурация проблемой сама по себе: если disable_functions в php.ini пуст, а mail() доступна из любого каталога сайта без ограничений — это открытая дверь для любого скрипта, который получится залить через любую другую уязвимость (не обязательно связанную с почтой).

Полезно свериться с общим планом действий при компрометации — он описывает те же шаги розыска шелла и подмены файлов подробнее: пошаговый план при взломе сервера. Если источником оказался именно WordPress, отдельно разобран частый сценарий с уязвимым плагином: сайт на WordPress взломали — причины и решение.

Как это вообще стало возможно

За рассылкой обычно стоит одна из трёх причин — и часто не одна, а комбинация:

Открытый relay. Postfix по умолчанию не должен пересылать почту от кого попало куда попало, но неверная настройка mynetworks (например, случайно указанный слишком широкий диапазон вместо 127.0.0.0/8) превращает сервер в открытый ретранслятор для всего интернета. Проверить текущие настройки:

postconf mynetworks
postconf smtpd_relay_restrictions

Если в mynetworks фигурирует что-то шире вашей локальной сети и доверенных IP — это и есть дыра.

Скомпрометированные учётные данные SMTP. Пароль от почтового ящика или от submission-аккаунта утёк — через фишинг, через брутфорс слабого пароля, через утечку из другого сервиса, где логин-пароль совпадали. Ботнет просто логинится и шлёт письма как легитимный пользователь, а Postfix честно их пересылает — с точки зрения сервера это авторизованная отправка.

Уязвимый скрипт на сайте — см. предыдущий раздел. Отдельно от relay и учётных данных: сервер отправляет почту от своего имени через mail(), но управляет процессом внешний злоумышленник через уязвимость в веб-приложении.

Если вы только настраиваете почтовый сервер с нуля и хотите сразу закрыть типичные дыры, стоит свериться с базовым чек-листом до того, как сервер уйдёт в продакшн: чек-лист безопасности нового сервера.

Немедленные действия

Порядок действий, когда факт рассылки подтверждён:

  1. Остановите рассылку немедленно. Если очередь забита чужими письмами — не ждите, пока они сами уйдут:
# посмотреть, сколько писем реально стоит
mailq | tail -1

# удалить ВСЮ очередь (осторожно — удалит и легитимные письма, если они там есть)
postsuper -d ALL

# либо точечно — по отправителю или получателю, если видно паттерн
mailq | grep -B2 "spam@example" | grep -oE '^[A-F0-9]+' | tr -d '*' | postsuper -d -

Если проблема в скомпрометированных SMTP-credentials — временно отключите submission на 587/465 или ограничьте его конкретным доверенным IP, пока не смените пароли.

  1. Найдите и устраните уязвимость. Если это скрипт — удалите или изолируйте его, обновите CMS и все плагины, проверьте права на файлы (веб-сервер не должен иметь возможность создавать исполняемые PHP-файлы в uploads/). Если это открытый relay — исправьте mynetworks и перезапустите Postfix:
postconf -e 'mynetworks = 127.0.0.0/8 [::1]/128'
systemctl restart postfix
  1. Смените все пароли SMTP и почтовых ящиков на сервере — не только тот, что предположительно скомпрометирован. Если пароли были слабыми или переиспользовались, есть шанс, что скомпрометировано больше одного аккаунта.
  1. Включите или проверьте лимиты на отправку (rate limiting) — чтобы даже в случае повторного взлома объём ущерба был ограничен, а не рос без предела за считаные часы:
postconf -e 'smtpd_client_message_rate_limit = 30'
postconf -e 'anvil_rate_time_unit = 60s'
  1. Проверьте, не осталось ли других следов взлома — новых пользователей в системе, посторонних cron-задач, изменённых конфигов. Рассылка спама редко бывает единственным, что сделал злоумышленник, попавший на сервер.

Если это был не первый подобный инцидент или вы не уверены, что нашли все последствия, имеет смысл пройти по более полному плану реагирования: план реагирования на инцидент — что делать при взломе. А если проблема оказалась не в скрипте, а именно в переполненной аномальными письмами очереди Postfix, отдельно разобраны причины и типовые решения: Postfix — переполнена очередь, причины и решение.

Репутационные последствия и восстановление

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

Что происходит с IP и доменом:

  • IP попадает в один или несколько DNSBL (Spamhaus, SORBS, Barracuda, UCEPROTECT и другие) — это происходит автоматически, как только объём и паттерн исходящей почты выглядит как спам.
  • Некоторые списки (например, Spamhaus SBL/CSS) снимают блокировку сами через какое-то время после прекращения рассылки, другие требуют явного запроса на делистинг через форму на сайте списка.
  • Домен, если он использовался в теле писем (не только IP-адрес отправителя), тоже может получить репутационный урон в почтовых сервисах — Gmail и Outlook помнят паттерн даже после того, как IP делистингован из публичных чёрных списков.

Что нужно сделать после устранения дыры:

ШагЗачем
Проверить IP по нескольким blacklist-чекерам (mxtoolbox.com/blacklists.aspx и аналоги)Понять, в скольких списках вы оказались
Подать запрос на делистинг в каждый список отдельноАвтоматически снимается не всегда, часто нужна ручная заявка
Проверить и усилить SPF/DKIM/DMARC для доменаСнижает шанс, что легитимная почта тоже будет помечаться как спам заодно с последствиями инцидента
Мониторить репутацию IP/домена 2-4 неделиДелистинг из одного списка не гарантирует, что вас не занесёт снова из-за кэшей и репутационных баз других провайдеров

Важный момент, который стоит держать в голове: это отдельная задача, растянутая не на один день, а иногда на 2-3 недели. Технически вы можете закрыть дыру и остановить рассылку за час, но делистинг из части чёрных списков идёт по расписанию их собственных проверок, а крупные почтовые провайдеры (Gmail, Microsoft) восстанавливают доверие к IP постепенно, по мере того как видят от него только легитимный трафик. Не рассчитывайте, что после исправления скрипта почта тут же снова начнёт доходить без сбоев — дайте репутации время восстановиться и не пытайтесь форсировать объём отправки в эти недели.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли просто выключить сервер, пока разбираешься?

Можно, это остановит рассылку мгновенно, но если на сервере есть другие сервисы (сайты, база данных), это создаст простой для легитимных пользователей. Обычно быстрее и точнее — остановить именно Postfix (systemctl stop postfix) или очистить очередь, а не гасить весь сервер.

Как понять, что рассылка точно прекратилась, а не просто временно затихла?

Смотрите mailq | tail -1 в динамике несколько раз в течение часа после исправления — очередь не должна пополняться новыми подозрительными записями. Также проверьте grep "postfix/smtpd" /var/log/mail.log на предмет новых подключений с тех же IP, что были в атаке.

Хостер грозит заблокировать сервер за abuse — что ему ответить?

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

Нужно ли менять IP сервера, если репутация сильно испорчена?

Не всегда обязательно — часть списков делистингует автоматически за 1-2 недели без спам-активности. Но если IP заблокирован сразу в нескольких крупных списках и почта критична для бизнеса прямо сейчас, смена IP (или перенос почты на отдельный сервер с чистым IP) может быть быстрее, чем ждать делистинга.

Как защититься от повтора, если дыру нашли и закрыли один раз?

Обновляйте CMS и плагины регулярно, ограничьте disable_functions в PHP там, где mail() не нужна, включите rate-limit на отправку в Postfix и настройте мониторинг размера очереди с алертом при аномальном росте — тогда следующий подобный инцидент будет замечен за минуты, а не за сутки от жалобы хостера.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →