Гид по технологиям

Как логировать письма, отправленные через PHP-функцию mail(), чтобы обнаруживать спам в формах

• 5 min read • DevOps • Обновлено 28 Nov 2025
Логирование писем PHP mail() для обнаружения спама
Логирование писем PHP mail() для обнаружения спама

Этот гайд показывает, как заменить sendmail на обёртку, которая логирует вызовы PHP mail(), чтобы быстро находить уязвимые контактные формы и CMS, использующие ваш сервер для рассылки спама. Покрыты установка скрипта-обёртки, правки php.ini, тестирование, безопасность и рекомендации по отладке.

Автор: Till Brehm Версия 1.0

Что делает этот метод

Идея проста: вместо прямого вызова sendmail PHP будет использовать небольшой исполняемый PHP-скрипт (/usr/local/bin/phpsendmail). Скрипт читает входящие данные сообщения, записывает краткую строку с полями To/From и выполняет реальный sendmail. Лог помогает отследить, какая виртуальная хостинг-учётная запись или сайт отправляет спам.

Важно: в исходном примере скрипт по умолчанию записывает лог в /tmp/mail_php.log, а в инструкции создаётся /var/log/mail.form. Убедитесь, что путь лог-файла в скрипте соответствует тому, что вы собираетесь использовать.

Уровень навыков и требования

Кратко: нужен доступ root к серверу, навык редактирования файлов в Linux, понимание PHP и перезапуска Apache/Nginx. Работает на Debian и других дистрибутивах (путь к sendmail может отличаться).

1 Установка скрипта-обёртки

Откройте новый файл /usr/local/bin/phpsendmail:

vi  /usr/local/bin/phpsendmail

… и вставьте следующий код:

#!/usr/bin/php  
  
*/  
  
$sendmail_bin = '/usr/sbin/sendmail';  
$logfile = '/tmp/mail_php.log';  
  
//* Get the email content  
$logline = '';  
$pointer = fopen('php://stdin', 'r');  
  
while ($line = fgets($pointer)) {  
        if(preg_match('/^to:/i', $line) || preg_match('/^from:/i', $line)) {  
                $logline .= trim($line).' ';  
        }  
        $mail .= $line;  
}  
  
//* compose the sendmail command  
$command = 'echo ' . escapeshellarg($mail) . ' | '.$sendmail_bin.' -t -i';  
for ($i = 1; $i < $_SERVER['argc']; $i++) {  
        $command .= escapeshellarg($_SERVER['argv'][$i]).' ';  
}  
  
  
  
//* Write the log  
file_put_contents($logfile, date('Y-m-d H:i:s') . ' ' . $_ENV['PWD'] . ' ' . $logline, FILE_APPEND);  
//* Execute the command  
return shell_exec($command);  
?>

Примечание: если на вашей системе sendmail расположен в другом месте (например, /usr/bin/sendmail или установлен Postfix), скорректируйте переменную $sendmail_bin.

Сделайте скрипт исполняемым:

chmod +x  /usr/local/bin/phpsendmail

Создайте файл логов и назначьте права. Примеры:

touch /var/log/mail.form
chmod 660 /var/log/mail.form
chown root:adm /var/log/mail.form

Важно: не делайте лог-файл доступным для записи всем (chmod 777) на продуктивных серверах — это риск безопасности. Лучше дать доступ только нужной группе (adm или mail).

Если вы хотите, чтобы скрипт писал в /var/log/mail.form, измените в скрипте строку:

$logfile = '/var/log/mail.form';

2 Изменение php.ini

Найдите php.ini, используемый веб-сервером. На Debian/Ubuntu для модулей Apache это /etc/php5/apache2/php.ini (или /etc/php/X/apache2/php.ini для современных версий). Откройте файл:

vi /etc/php5/apache2/php.ini

Найдите секцию [mail function] и измените sendmail_path на путь к нашему скрипту. Исходные строки:

[mail function]
; For Win32 only.
SMTP = localhost
smtp_port = 25

; For Win32 only.
;sendmail_from = [email protected]

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
;sendmail_path =

Замените на:

[mail function]
; For Win32 only.
;SMTP = localhost
;smtp_port = 25

; For Win32 only.
;sendmail_from = [email protected]

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
sendmail_path = /usr/local/bin/phpsendmail

Если PHP работает как CGI/FastCGI/suPHP, поменяйте такой же параметр в /etc/php5/cgi/php.ini или в соответствующем конфиге для версии PHP.

Перезапустите веб-сервер, чтобы изменения вступили в силу:

/etc/init.d/apache2 restart

Или для systemd:

systemctl restart apache2

3 Тестирование настройки

Создайте на одном из сайтов файл mailtest.php с содержимым:

Откройте его в браузере. Если всё настроено правильно, сообщение пройдет через phpsendmail и появится строка в лог-файле.

Проверка лога:

cat /var/log/mail.form

Если вы остаетесь без записи в лог, проверьте:

  • соответствует ли путь $logfile реальному файлу;
  • права доступа и владельца файла логов;
  • ошибки в журнале веб-сервера (error.log) и системном журнале.

Безопасность и жесткие меры

Важно:

  • Скрипт выполняется с привилегиями того пользователя, от имени которого запускается PHP. Никогда не давайте скрипту права на запись всем пользователям. Используйте chown/chmod так, чтобы только root или специальная группа могли писать лог.
  • Не храните в логе полные тела писем с пользовательскими данными, если это нарушает политику конфиденциальности. В примере записываются только поля To/From и текущая директория.
  • Рассмотрите фильтрацию записываемых данных на предмет потенциальной инъекции логов (удаление управляющих символов, ограничение размера). Если ожидается большой поток писем, настройте ротацию логов (logrotate).

Альтернативные подходы

  1. Использовать milter/SMTP-прокси: настроить Postfix/Exim с фильтрами, которые логируют и блокируют подозрительные исходящие сообщения. Подходит для крупных серверов.
  2. Встроенная логика в приложении: фиксировать отправки из контактных форм в отдельный лог или БД с привязкой к URL и учетной записи сайта.
  3. Использовать сторонние SaaS-решения для защиты форм и CAPTCHA, которые препятствуют массовым отправкам.

Каждый подход имеет свои преимущества: обёртка быстро внедряется, SMTP-прокси даёт централизованный контроль, а в приложении — точная привязка к уязвимому коду.

Руководство администратора — чеклист

  • Установить /usr/local/bin/phpsendmail и сделать исполняемым.
  • Настроить $sendmail_bin и $logfile в скрипте.
  • Создать лог-файл, установить безопасные права (например, 660) и владельца.
  • Изменить sendmail_path в php.ini для соответствующего SAPI.
  • Перезапустить веб-сервер.
  • Протестировать через простую mail()-страницу и проверить записи в логе.
  • Настроить logrotate для лог-файла.
  • Мониторить и анализировать логи; при обнаружении источника — закрыть уязвимость на стороне сайта.

Критерии приёмки

  • Вызов mail() из тестовой страницы записывает строку в лог с временной меткой и полями To/From.
  • Настройка не нарушает доставку почты (сообщения доходят до реального sendmail/postfix).
  • Лог-файл защищён от записи нежелательных пользователей.

Примеры ошибок и как их исправлять

  • Нет записей в логах: проверьте права на /usr/local/bin/phpsendmail и /var/log/mail.form, проверьте sendmail_path в том php.ini, который использует веб-сервер.
  • Сообщения не отправляются: проверьте переменную $sendmail_bin и работоспособность системного MTA.
  • Логи заполняются мусором: ограничьте информацию для записи и добавьте фильтрацию строк перед file_put_contents.

Мини-методология расследования спама

  1. Включаете лог-обёртку.
  2. Ждёте или запускаете нагрузочный тест с mailtest.php.
  3. Анализируете строки лога: определяете виртуальный хост (через $_ENV[‘PWD’] или добавляя getcwd()).
  4. Отключаете форму/плагин на найденном сайте, патчите уязвимость.
  5. По необходимости настраиваете блокировку исходящей почты на уровне MTA для этой учётной записи.

Итог и рекомендации

Использование простой обёртки для sendmail — быстрый и эффективный способ обнаруживать источники спама на хостинге. Для продакшн-серверов комбинируйте этот метод с централизованным мониторингом и ограничениями на отправку почты.

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

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро