Давно хотел узнать, как отправлять почту через сторонний сервер с помощью стандартной функции 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
from *******@yandex.ru
host smtp.yandex.ru
port 587
protocol smtp
auth login
user *******@yandex.ru
password *******
logfile /var/log/msmtp.log
tls off
tls_starttls off
tls_certcheck off
Последняя строка — это таймаут для соединения с сервером. В случае отправки почты из 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');