Как настроить отправку почты через postfix в Битрикс24
Почему так происходит?
Скорость отправки писем напрямую зависит от того, как настроена отправка почты в Битрикс24. На агентах или на хитах? А так же зависит от вида отправляемых писем. Например, отправка рассылок из CRM выполняется только на агентах — такие письма обрабатываются cron'ом по расписанию.Если все агенты, которые выполняют получение и отправку писем исполняются на хитах (задан параметр немедленной доставки) или разработчик напрямую использует функцию mail(), то в этом случае она будет зависеть от активности сотрудников, которые работают на портале Битрикс24. Поэтому, если на портале отсутствует активность, рассылка писем будет выполняться достаточно медленно, при каждом хите сотрудника по несколько писем.
Переходить на Postfix имеет смысл если:
- не устраивает низкая скорость отправки почты через msmtp
- нужно настроить DKIM-подпись отправляемых писем
- отправляемые письма не доходят до адресатов
Разберем настройку отправки почтовых сообщений с помощью Postfix. Будем считать, что наш Битрикс24 развёрнут на домене example.com и в его MX-записях прописаны сервера Яндекса.
Настраиваем Postfix
Ставим необходимые пакеты.$ yum -y install postfix cyrus-sasl-plainДобавляем в /etc/postfix/canonical указание через какой аккаунт отправлять почту:
# Слева - регулярное выражение, применяемое к отправителю # Справа - отправитель, которого нужно поставить /.+/ mail@example.comДобавляем в /etc/postfix/generic отправку почты админу на внешний ящик:
# Слева - локальный пользователь # Справа - отправитель, которого нужно поставить root@localhost mail@example.com bitrix@localhost mail@example.comДобавляем в /etc/postfix/mailpasswd логин и пароль релей-хостов:
# [SMTP_HOST]:SMTP_PORT SMTP_USER:SMTP_PASSWORD [smtp.yandex.ru] mail@example.com:SecretPassword** в этом примере мы создаем учетную запись для аутентификации на Яндексе. При отправке писем от mail@example.com необходимо авторизоваться на сервере Яндекса от этой же учетной записи с паролем SecretPassword
Добавляем в /etc/postfix/sender_relay привязку доменов и конкретных отправителей к внешним службам:
# Слева - отправитель, справа - релей mail@example.com [smtp.yandex.ru]**в этом примере мы все сообщения, отправляемые от домена example.com переправляем через сервер smtp.yandex.ru.
Настройка значений From и Reply-To
По-умолчанию Битрикс24 будет использовать в качестве отправителя адрес, заданный в настройках главного модуля. Но вот в карточках лидов, контактов и компаний система использует мейл текущего авторизованного пользователя. Заголовки, например:From: Иван Петров <i.petrov@example.com> To: Фёдор Сидоров <f.sidorov@example.com>В некоторых случаях это даже будет работать, но в основном нет. Такие сервисы, как Яндекс и Гугл блокируют отправку почты, если для авторизации SMTP используется один аккаунт, а в поле “From” стоит другое значение.
Чтобы этого не происходило — можно настроить замену заголовка From на статичное значение, которое невозможно изменить из Битрикс24. Но неправильно просто затереть значение, которое там стояло - нужно оставить возможность пользователю ответить на отправленное ему письмо.
Для этого у нас есть заголовок Reply-To. Но и это не все! При ответе пользователя на письмо, в качестве получателей будет подставляться два адреса (два поля Reply-To). Первый — сам отправитель, второй — технический адрес, с которого это письмо было отправлено. Сделаем, так чтобы технический адрес Postfix игнорировал и письмо отправлялось только его отправителю.
Добавляем блок в /etc/postfix/header_checks:
# Добавить в Reply-To значение, использованное в From /^From: (.*)/ PREPEND Reply-To: $1 # Перезаписать From на значение по-умолчанию /^From: (.*)/ REPLACE From: mail@example.com # Удалить добавление технического адреса в ответном письме /^(Reply-To:.*)/ IGNOREВключаем обработку заголовков в /etc/postfix/main.cf:
header_checks = regexp:/etc/postfix/header_checksДобавляем блок в /etc/postfix/main.cf:
# Отключаем ipv6, потому что он толком не работает inet_protocols = ipv4 # Указываем все письма отсылать через этот релей relayhost = [smtp.yandex.ru] # Включение аутентификации на стороне клиента $ smtp_sasl_auth_enable = yes # Указывает на файл, в котором хранится база связок логин/пароль $ smtp_sasl_password_maps = hash:/etc/postfix/mailpasswd # Опции SASL. noanonymous указывает на запрет анонимной аутентификации $ smtp_sasl_security_options = noanonymous # Задает плагин SASL для аутентификации $ smtp_sasl_type = cyrus # Перечисляет механизмы проверки пользователя и пароля $ smtp_sasl_mechanism_filter = login # Включает зависящую от отправителя аутентификацию, отключает кэширование SMTP-соединения $ smtp_sender_dependent_authentication = yes # Указание на список адресов и почтовых серверов, через которые нужно отправлять письма на эти адреса sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay # Добавляет для домена указание через какой аккаунт отправлять почту sender_canonical_maps = hash:/etc/postfix/canonical # Добавляет отправку почты админу на внешний ящик smtp_generic_maps = hash:/etc/postfix/generic # Указывает, использовать ли TLS для SMTP smtp_use_tls = yesЛоги о неработающем IPv6 выглядят как-то так:
Mar 5 19:48:28 MegaRoss-207-Krasnodar postfix/smtp[43577]: connect to smtp.gmail.com[2a00:1450:4010:c0b::6c]:587: Network is unreachable Mar 5 19:48:28 MegaRoss-207-Krasnodar postfix/smtp[43577]: 919BB1A3E6E: to=<user@example.com>, relay=none, delay=0.44, delays=0.02/0/0.43/0, dsn=4.4.1, status=deferred (connect to smtp.gmail.com[2a00:1450:4010:c0b::6c]:587: Network is unreachable)Редактируем параметр sendmail_path в /etc/php.d/bitrixenv.ini:
# Удаляем работу через msmtp ; sendmail_path = msmtp -t -i # Добавляем работу через postfix sendmail_path = /usr/sbin/sendmail -t -i -f mail@example.comГенерируем индексированные файлы:
$ postmap /etc/postfix/generic $ postmap /etc/postfix/canonical $ postmap /etc/postfix/mailpasswd $ postmap /etc/postfix/sender_relayДобавляем в автозагрузку и запускаем сервис:
$ systemctl enable postfix $ systemctl start postfix
Отправка тестового письма
Выполняем из консоли следующую команду:$ echo "Test message" | mail -s "Test subject" user@example.comСмотрим логи, ищем фразу “status=sent”:
$ tail /var/log/maillog Mar 6 10:33:43 MegaRoss-207-Krasnodar postfix/pickup[45768]: 24FD91A3E6F: uid=0 from=<root> Mar 6 10:33:43 MegaRoss-207-Krasnodar postfix/cleanup[46875]: 24FD91A3E6F: message-id=<20190306073343.24FD91A3E6F@megaross-207-krasnodar.ugtel.ru> Mar 6 10:33:43 MegaRoss-207-Krasnodar postfix/qmgr[45769]: 24FD91A3E6F: from=<mail@example.com>, size=478, nrcpt=1 (queue active) Mar 6 10:33:44 MegaRoss-207-Krasnodar postfix/smtp[46877]: 24FD91A3E6F: to=<user@example.com>, relay=smtp.yandex.ru[187.150.150.138]:25, delay=1.3, delays=0.03/0.01/0.33/0.89, dsn=2.0.0, <strong>status=sent</strong> (250 2.0.0 Ok: queued on smtp2o.mail.yandex.net as 1551857624-LUq73TrSs8-XhiW0rUr) Mar 6 10:33:44 MegaRoss-207-Krasnodar postfix/qmgr[45769]: 24FD91A3E6F: removedПоздравляем, тестовое письмо успешно отправлено! :)
Настраиваем DKIM
Переходим к настройке DKIM. Это нужно для массовой рассылки писем, так как наличие DKIM-подписи — обязательное условие для большинства почтовых провайдеров. Письма с отсутствием такой подписи скорее всего попадут в спам.С помощью этого ключа сервер определяет подлинность DKIM-подписи и решает, что делать с письмом. В зависимости от результатов проверки, письмо может быть принято, отклонено или отправлено в спам. При этом информация с результатами проверки добавляется в заголовок сообщения, которая в дальнейшем может быть использована антиспам фильтрами.
Чтобы снизить вероятность попадания писем в спам (повысить доверие почтовых серверов к отправляемым письмам), настроим добавление подписи DKIM в заголовок. Ставим нужные пакеты:
# Пакет opendkim-tools требуется для генерации ключей $ yum -y install opendkim opendkim-toolsГенерируем ключи:
$ opendkim-genkey -D /etc/opendkim/keys -d example.com -s default** после выполнения команды в директории /etc/opendkim/ должны появится ключи (публичный и приватный) для домена example.com Смотрим результат:
$ ls -alh /etc/opendkim/keys total 8,0K drwxr-x--- 2 opendkim opendkim 48 мар 4 15:24 . drwxr-xr-x 3 root opendkim 74 мар 4 15:33 .. -rw-r----- 1 opendkim opendkim 887 мар 4 15:24 default.private -rw-r----- 1 opendkim opendkim 316 мар 4 15:24 default.txtИзменяем права на файлы и директории:
$ chgrp opendkim /etc/opendkim/* $ chgrp opendkim /etc/opendkim/keys/* $ chmod g+r /etc/opendkim/keys/* $ gpasswd -a postfix opendkimДобавляем в автозагрузку и запускаем сервис:
$ systemctl enable opendkim $ systemctl start opendkimИдём в настройки DNS домена и добавляем TXT-запись для поддомена default._domainkey, в содержимое ставим содержимое публичного ключа:
$ cat /etc/opendkim/keys/default.txt default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GC5qGSIb3DQEBAQUAA4GNADCBiQKBgQDDW...JtXs1XbcZ6qHNJKXw1DAQAB" ) ; ----- DKIM key default for example.comПроверим, что всё работает:
$ dig TXT default._domainkey.example.com ;; <<>> DiG 9.10.3-P4-Ubuntu <<>> TXT default._domainkey.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50978 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;default._domainkey.example.com. IN TXT ;; ANSWER SECTION: default._domainkey.example.com. 599 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GC5qGSIb3DQEBAQUAA4GNADCBiQKBgQDDW...JtXs1XbcZ6qHNJKXw1DAQAB" ;; Query time: 94 msec ;; SERVER: 127.0.1.1#53(127.0.1.1) ;; WHEN: Wed Mar 06 10:40:22 MSK 2019 ;; MSG SIZE rcvd: 296Добавляем блок в /etc/opendkim/KeyTable (одной строкой):
# Полное имя ключа - домен - селектор - путь к приватному ключу (одной строкой) default._domainkey.example.com example.com:default:/etc/opendkim/keys/default.privateДобавляем блок в /etc/opendkim/SigningTable:
# Какие домены - каким ключом подписывать *@example.com default._domainkey.example.comИ пишем в /etc/opendkim.conf:
# Режим работы - подписывать(signer)(s) и валидировать/контролировать(verified)(v) Mode sv # Указываем список ключей KeyTable file:/etc/opendkim/keytable # Соответствие ключей и доменов SigningTable file:/etc/opendkim/signingtableУкажем postfix’у использовать opendkim - добавляем блок в /etc/postfix/main.cf:
# Обработка ошибок при фильтрации писем до попадания сообщений в очередь milter_default_action = accept # Версия протокола: 2 для 2.3 ≤ Postfix ≤ 2.5, 6 для Postfix ≥ 2.6 milter_protocol = 2 # Подписывать сообщения, полученные по SMTP с других серверов smtpd_milters = inet:127.0.0.1:8891 # Подписывать сообщения, приходящие из sendmail non_smtpd_milters = inet:127.0.0.1:8891Перезапускаем postfix и opendkim:
$ systemctl restart postfix $ systemctl restart opendkimПроверяем работу - ищем в лог-файле почты строку “DKIM-Signature field added”:
$ tail -20 /var/log/maillog Mar 6 09:34:25 server1 postfix/pickup[29010]: 0A2AA407C6EA: uid=600 from=<bitrix24@example.com> Mar 6 09:34:25 server1 postfix/cleanup[29684]: 0A2AA407C6EA: prepend: header From: =?UTF-8?B?0JzQsNC60YHQuNC8INCU0L7RgNC+0YnQtdC90LrQvg==?= <user2@example.com> from local; from=<bitrix24@example.com>: Reply-To: =?UTF-8?B?0JzQsNC60YHQuNC8INCU0L7RgNC+0YnQtdC90LrQvg==?= <user2@example.com> Mar 6 09:34:25 server1 postfix/cleanup[29684]: 0A2AA407C6EA: message-id=<crm.activity.9434-0ZQRGV@bitrix24.example.com> Mar 6 09:34:25 server1 opendkim[23286]: 0A2AA407C6EA: DKIM-Signature field added (s=default, d=example.com) Mar 6 09:34:25 server1 postfix/qmgr[29011]: 0A2AA407C6EA: from=<bitrix24@example.com>, size=1282, nrcpt=2 (queue active) Mar 6 09:34:25 server1 postfix/smtp[29687]: 0A2AA407C6EA: to=<0123456@example.com>, relay=121.145.167.190[121.145.167.190]:25, delay=0.27, delays=0.1/0/0.12/0.05, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 44DkWP1dDJz3X8r) Mar 6 09:34:25 server1 postfix/smtp[29687]: 0A2AA407C6EA: to=<user2@example.com>, relay=121.145.167.190[121.145.167.190]:25, delay=0.27, delays=0.1/0/0.12/0.05, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 44DkWP1dDJz3X8r) Mar 6 09:34:25 server1 postfix/qmgr[29011]: 0A2AA407C6EA: removed
Настраиваем DMARC
Теперь перейдем к настройке записи DMARC. Это нужно, чтобы получатель мог быть уверен, что письмо с адреса durov@vk.com действительно отправил Павел Дуров, а не злоумышленник. В настройках домена, добавляем DNS-запись TXT для поддомена _dmarc.example.com с таким значением:v=DMARC1; p=quarantineПроверяем, что всё работает:
$ dig TXT _dmarc.example.com ;; <<>> DiG 9.10.3-P4-Ubuntu <<>> TXT _dmarc.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22795 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;_dmarc.example.com. IN TXT ;; ANSWER SECTION: _dmarc.example.com. 600 IN TXT "v=DMARC1; p=quarantine" ;; Query time: 52 msec ;; SERVER: 127.0.1.1#53(127.0.1.1) ;; WHEN: Wed Mar 06 10:40:55 MSK 2019 ;; MSG SIZE rcvd: 83
Опциональная автоматизация настройки Postfix через ansible
Практически всё можно автоматизировать. Мы используем ansible, вот ссылка на репозиторийПользуйтесь:)