в Администририрование

msmtp — это простой консольный клиент для отправки сообщений электронной почты по протоколу SMTP.

Можно, конечно, пойти сложным путем и поставить полноценный почтовый сервер, но зачем? Нам ведь требуется просто позволить скриптам и демонам отправлять почту, а заморачиваться с DKIM, SPF, заголовками и прочим — крайне лень. Поэтому мы будем отправлять почту с помощью почтового ящика на yandex.ru, и поможет нам в этом приложение под названием msmtp.

Важное замечание — в моем случае домен уже делегирован на яндекс, в DNS имеются все необходимые записи, почтовый ящик создан на странице pdd.yandex.ru, к нему прописаны алиасы вида no-reply, noreply, donotreply, do-not-reply для того, что бы была возможность иметь почтовый ящик с именем [email protected], но успешно отправлять письма от имени, например, [email protected].

Единственное но — в репозиториях находится старая и бажная версия. Самый критичный для нас баг — это неизменяемое поле Sender, т.е. мы не можем указать имя (или адрес? не помню) отправителя. Смотрим что есть в репозиториях:

$ yum info msmtp
# ...
Name        : msmtp
Version     : 1.4.32
Release     : 1.el7
Size        : 120 k
# ...

Смотрим информацию о релизах на официальном сайте — на момент написания этих строк это версия 1.6.5 (уже без описанного выше бага).

Все манипуляции производились на «чистой» системе CentOS 7.2.

Скачаем исходники и соберем приложение ручками.

$ cd ~
$ yum install git
$ git clone git://git.code.sf.net/p/msmtp/code msmtp
$ cd msmtp

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

$ yum install automake gcc gettext-devel gnutls-devel openssl-devel texinfo

Запускаем autoreconf:

$ autoreconf -i
autoreconf: configure.ac: AM_GNU_GETTEXT is used, but not AM_GNU_GETTEXT_VERSION
configure.ac:31: installing 'build-aux/config.guess'
configure.ac:31: installing 'build-aux/config.sub'
configure.ac:34: installing 'build-aux/install-sh'
configure.ac:34: installing 'build-aux/missing'
Makefile.am: installing './INSTALL'
doc/Makefile.am:3: installing 'build-aux/mdate-sh'
src/Makefile.am: installing 'build-aux/depcomp'

Конфигуряем:

$ ./configure
# ...
Install prefix ......... : /usr/local
TLS/SSL support ........ : yes (Library: GnuTLS) # <-- ВАЖНО
GNU SASL support ....... : no
IDN support ............ : no
NLS support ............ : yes
Libsecret support (GNOME): no
MacOS X Keychain support : no

И если предыдущая операция завершилась успешно (наличие поддержки TLS/SSL для нас критично), то собираем:

$ make

Если во время сборки вылезла ошибка вида:

*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version 0.19 but the autoconf macros are from gettext version 0.18
make[2]: *** [stamp-po] Error 1
make[2]: Leaving directory `/root/msmtp/po'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/msmtp'
make: *** [all] Error 2

То правим один файл:

$ nano ./po/Makefile.in.in

Где заменяем строку GETTEXT_MACRO_VERSION = 0.19 на GETTEXT_MACRO_VERSION = 0.18. После этого повторяем:

$ make

Выполняем установку только при успешной сборке (отсутствии каких-либо ошибок):

$ make install

Проверяем:

$ /usr/local/bin/msmtp --version
msmtp version 1.6.5
Platform: x86_64-unknown-linux-gnu
TLS/SSL library: GnuTLS # <-- ВАЖНО
Authentication library: built-in
Supported authentication methods:
plain external cram-md5 login
IDN support: disabled
NLS: enabled, LOCALEDIR is /usr/local/share/locale
Keyring support: none
System configuration file name: /usr/local/etc/msmtprc
User configuration file name: /root/.msmtprc

Copyright (C) 2016 Martin Lambers and others.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License .
There is NO WARRANTY, to the extent permitted by law.

Создаем симлинки и заменяем «стандартный» sendmail (убедись предварительно что он удален/не установлен):

$ ln -s /usr/local/bin/msmtp /etc/alternatives/mta
$ ln -s /usr/local/bin/msmtp /usr/bin/msmtp
$ ln -s /etc/alternatives/mta /usr/lib/mail
$ ln -s /etc/alternatives/mta /usr/bin/mail
$ ln -s /etc/alternatives/mta /usr/sbin/mail
$ ln -s /etc/alternatives/mta /usr/lib/sendmail
$ ln -s /etc/alternatives/mta /usr/bin/sendmail
$ ln -s /etc/alternatives/mta /usr/sbin/sendmail

Создаем системный конфиг и симлинк на него в /etc:

$ touch /usr/local/etc/msmtprc
$ ln -s /usr/local/etc/msmtprc /etc/msmtprc

Выставляем права на файл и меняем группу файла для того, чтобы php-fpm (и другие члены этой группы) смогли читать его:

$ chmod 640 /usr/local/etc/msmtprc
$ chown :www-data /usr/local/etc/msmtprc

После этого переходим непосредственно к настройке:

$ nano /etc/msmtprc
defaults
tls on
auth on
tls_starttls on
tls_certcheck off
logfile /var/log/msmtp.log
timeout 20

account yandex
host smtp.yandex.ru
port 587
maildomain your_domain_name.ru
from [email protected]_domain_name.ru
keepbcc on
user [email protected]_domain_name.ru
password MAILBOX_PASSWORD

account default : yandex

И проверяем работу запуская как из консоли, так и из php-скрипта:

$ echo -e "\nSome test 1" | msmtp -d [email protected]
$ php -r "mail('[email protected]','Subject','Some test 2');"

Письма должны успешно приходить на [email protected]. Так же стоит проверить работу непосредственно из-под php-fpm, например, таким скриптом:

<?php

  set_time_limit(15);
  error_reporting(E_ALL);
  ini_set('display_errors', 1);

  $result = mail('[email protected]', 'Subject', 'Some test 3');
  echo '<pre>'; var_dump($result); echo '</pre>';

  if ($result) {
    echo 'все путем';
  } else {
    echo 'что-то не так';
  }

И обратившись к нему из web. Если необходимо позволить какому-либо локальному пользователю так же из консоли отправлять письма, то необходимо создать новую группу, и добавить в неё необходимых пользователей, не забыв так же добавить в неё и php-fpm.

Несколько почтовых ящиков и nginx

Так как на одном сервере могут располагаться несколько сайтов — наверняка возникнет потребность отправлять письма с разных сайтов от разных отправителей. Поясню — на одном сервере расположены сайты с доменными именами site1.ru и site2.ru. Соответственно, отправитель в исходящих письмах с сайта site1.ru должен быть вида [email protected], а в исходящих письмах с сайта site2.ru — вида [email protected]. Для того что бы этого добиться нам необходимо прописать требуемые аккаунты в файле настроек msmtp:

defaults
tls on
auth on
tls_starttls on
tls_certcheck off
logfile /var/log/msmtp.log
timeout 20

account site1
host smtp.yandex.ru
port 587
maildomain site1.ru
from [email protected]
user [email protected]
password password_here

account site2
host smtp.yandex.ru
port 587
maildomain site2.ru
from [email protected]
user [email protected]
password password_here

account default : site1

Теперь по умолчанию письма будут уходить от имени аккаунта site1, так как он у нас указан как аккаунт по умолчанию. Для того что бы сообщить скриптам на сайте site2.ru использовать аккаунт site2 необходимо добавить следующую строку в конфигурацию сервера site2.ru nginx:

  location ~ \.php$ {
    # ...
    fastcgi_param PHP_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -a site2";
    # ...
  }

И после этого всё начнет работать так как надо.

Бабахнуть комментарий

Комментарии

  1. Испытываю чувство огромной благодарности! Единственное толковое описание решения задачи отправки почты из скриптов.

  2. Огромное спасибо за статью! Единственное работающее описание установки, найденное мной на просторах интернета