PHP: почта через SMTP с аутентификацией или msmtp
Давно хотел узнать, как отправлять почту через сторонний сервер с помощью стандартной функции mail, так как считаю неправльным использовать всякие классы-надстройки, а держать SMTP-сервер только для этих целей зачастую нежелательно. И вроде бы нашел решение для Linux и FreeBSD: программа msmtp.
Во многих дистрибутивах она изначально есть в пакетах, поэтому ее установка проблем не составляет. В Debian Linux пишем:
# apt-get install msmtp
В FreeBSD:
# cd /usr/ports/mail/msmtp
# make && make install && make clean
# rehash
Теперь выполним
# msmtp --version
чтобы узнать, где находится системный файл конфигурации (обычно под Linux это /etc/msmtprc, под FreeBSD — /usr/local/etc/msmtprs). Теперь можно приступить к его редактированию. Файл может содержать настройки для нескольких аккаунтов. В простейшем случае для аутентификации достаточно указать следующее:
account default
auth on
user имя_пользователя
password пароль
from ящик_отправителя
timeout 5
Последняя строка — это таймаут для соединения с сервером. В случае отправки почты из PHP-скриптов он должен быть небольшим, чтобы если SMTP-сервер упадет, это не сильно сказалось на работе сайта.
Проверим, что подключение к серверу проходит нормально:
# msmtp --serverinfo
Далее найдем в php.ini строку sendmail_path и укажем в ней путь к msmtp (пример для FreeBSD):
sendmail_path = "/usr/local/bin/msmtp -t"
Не забываем про кавычки, их отсутствие будет приводить к ошибке.
Казалось бы, на этом все, и после перезапуска Apache отправка почты должна заработать, но обнаружилась одна тонкость. При отправке письма с опцией -t msmtp создает где-то (скорее всего, в текущем каталоге) временный файл, и в ряде случаев на это может не хватить прав. В этом случае письмо не отправится, и запись в лог об этом так же не будет сделана. Чтобы избежать такого, нужно прописать в переменную TMPDIR каталог, который точно открыт для записи, например, /tmp. Сделать это можно разными способами, самый простой — добавить в скрипт перед вызовом функции mail вот такую строку:
putenv('TMPDIR=/tmp');
После этого отправка писем через внешний сервер должна заработать.
# apt-get install mstmp
правильно будет:
# apt-get install msmtp