Содержание

  1. Что это и зачем

  2. Настройка вручную

    1. Аутентификация на локальном сервере Exim

    2. Шифрование TLS

    3. Аутентификация на внешних почтовых серверах

    4. Настройки подключения к серверам

    5. Правила отправки почты

    6. Логика маршрутизации и аутентификации

  3. Завершение настройки и проверка

  4. Настройка с помощью Ansible

Что это и зачем

Сегодня мы наконец настроим почтовый сервер Exim (версии 4) для одного распространенного сценария использования, который, к сожалению, последовательно, хотя и не без причины, игнорируется разработчиками дистрибутивов.

Exim выбран почтовым сервером по умолчанию в Debian и в производных от него дистрибутивах. Если вам уже приходилось устанавливать Exim, то, вероятно, вы имели дело с одним из таких дистрибутивов и системой конфигурации, в которой предусмотрен вариант "отправка почты через smarthost". Для домашнего пользователя таким smarthost ("умным" хостом) обычно будет крупный сервис электронной почты вроде Gmail. В корпоративной сети, возможно, будет свой "умный" хост.

Проблема: smarthost в стандартной конфигурации может быть только один. Некуда вписать пароли от всех ваших учетных записей на Gmail, Mail.ru, Яндекс и так далее и заставить Exim самостоятельно отправлять ваши письма на нужный сервис в зависимости, например, от обратного адреса.

Разумеется, Exim сам по себе способен сделать с почтой все, что угодно, вопрос только в конфигурации. К сожалению, простого и, что самое главное, общепринятого решения этой проблемы не придумано. Можно найти некоторые предложения 1 , 2 , 3 , 4, но все они страдают определенными ограничениями.

Решение. Ниже показан вариант, требующий минимальных изменений в стандартной конфигурации. При этом все ее возможности сохраняются. Способ настройки рассчитан на систему конфигурации Exim4 в Debian с раздельными файлами. Полученную конфигурацию можно использовать и на домашнем компьютере, и на облачном сервере для отправки уведомлений от различных сервисов и так далее. В следующий раз я покажу, как настраивать Exim в других дистрибутивах, одним файлом.

Если вы знакомы с Ansible, можете сразу скачать скрипт и дополнительные файлы с моего гитхаба и перейти к разделу Настройка с помощью Ansible.

Настройка вручную

Для начала запустите dpkg-reconfigure exim4-config, выберите "отправка почты через smarthost; приём по SMTP или через fetchmail". Настройте этот smarthost, как описано в стандартном руководстве – он будет использоваться по умолчанию, если для конкретного пользователя не указан другой smarthost.

Так как теперь у нас несколько "умных" хостов, нужно решить, как мы будем определять, на какой из отправлять отдельно взятое письмо. Можно смотреть на обратный адрес в заголовке From: – если письмо от example@mail.ru, то отправляем его на Mail.ru – но это не очень хорошая идея. Почтовые программы (и Exim тоже) по умолчанию не доверяют тому, что пишет пользователь в заголовке From:.

Нам нужна аутентификация.

Мы заведем непосредственно на локальном сервере Exim по пользователю5 для каждой учетной записи на сервере провайдера. Этим пользователям удобно давать имена, совпадающие с адресами почты у провайдера (example@mail.ru), но можно давать и любые другие. Важно, чтобы пользователь в итоге прошел аутентификацию и Exim знал его идентификатор 6.

Аутентификация на локальном сервере Exim

Раскомментируйте в файле /etc/exim4/conf.d/auth/30_exim4-config_examples нужные способы аутентификации. Обычно это plain_server: и login_server:.

Exim поддерживает много способов аутентификации, и их настройка описана в документации. В конфигурации в Debian пользователи и хэши паролей записываются в файле /etc/exim4/passwd следующего формата:

AzureDiamond@mail.ru:$2b$12$8XQqds.oqY2aG0.a/UNOzeC04SFmIi1ugrmLSK.RCi73QFocO610C

а добавить их туда можно скриптом /usr/share/doc/exim4-base/examples/exim-adduser.

Шифрование TLS

Почти всегда лучше включить шифрование с помощью TLS. В конфигурации в
Debian оно настраивается в файле /etc/exim4/conf.d/main/03_exim4-config_tlsoptions. Обычно настройки по умолчанию работают, и нужно только положить в каталог /etc/exim4 файлы ключа и сертификата. Самоподписанный сертификат можно
сгенерировать скриптом /usr/share/doc/exim4-base/examples/exim-gencert. Однако учтите, что требовательные почтовые клиенты (например, Thunderbird) не будут работать с самоподписанным сертификатом. Лучше получить "настоящий" сертификат, например, от Let's Encrypt. Эту процедуру мы здесь описывать не будем, она многократно описывалась в других руководствах.

Аутентификация на внешних почтовых серверах

Крупные провайдеры электронной почты не будут принимать почту от никому не известных серверов. Точнее, принимать они будут, но вероятность попадания такой почты в спам будет велика, даже если вы кругом обвешаете свой сервер SPF, DKIM и DMARC. Нам нужна обычная учетная запись электронной почты с логином и паролем. Не забудьте, что провайдеры сейчас требуют заводить для почтовых программ отдельные пароли. В Gmail это называется "Менее защищенные приложения" и "Пароли приложений". В Mail.ru – "Пароли для внешних приложений". Эти пароли и логины мы укажем в файле /etc/exim4/passwd.smarthosts следующего формата:

# -*- mode: conf-unix; coding: utf-8 -*-
### логин_на_локальном_сервере:логин_на_сервере_провайдера:пароль_на_сервере_провайдера
# Пользователь авторизуется на локальном сервере под именем
# AzureDiamond, а на сервере Mail.ru логином должен быть адрес почты
# целиком
AzureDiamond:AzureDiamond@mail.ru:hunter2
# Для Gmail логином тоже служит адрес целиком
AzureDiamond@gmail.com:AzureDiamond@gmail.com:hunter2
# Для Яндекс Почты логином служит часть адреса до @
AzureDiamond@ya.ru:AzureDiamond:hunter2

Не забудьте установить права доступа на файл с паролями:

chown root:Debian-exim /etc/exim4/passwd.smarthosts && \
    chmod 640 /etc/exim4/passwd.smarthosts

Настройки подключения к серверам

Для каждого сервера мы создадим отдельный транспорт7, работающий по протоколу SMTP. Описания этих транспортов будут храниться в файле /etc/exim4/conf.d/transport/40_smarthosts. Его нужно создать и заполнить (скрипт для Ansible сделает это). В примере ниже даны примеры настроек для Mail.ru и Gmail. Обратите внимание, что для Mail.ru нужно указать port = 465 и protocol = smtps, а Gmail работает с port = 587. Про порты и протоколы можно почитать, например, здесь.

# -*- mode: conf-unix; coding: utf-8 -*-
mailru:
    # См. https://help.mail.ru/mail/mailer/popsmtp
    debug_print = "T:  mailru for $local_part@$domain"
    driver = smtp

    hosts = smtp.mail.ru

    hosts_override = true
    helo_data = localhost
    port = 465
    protocol = smtps
    hosts_require_auth = *
    hosts_require_tls = *
    tls_verify_hosts = *

gmail:
    # См. https://support.google.com/mail/answer/7126229
    debug_print = "T:  gmail for $local_part@$domain"
    driver = smtp

    hosts = smtp.gmail.com

    hosts_override = true
    helo_data = localhost
    port = 587
    hosts_require_auth = *
    hosts_require_tls = *
    tls_verify_hosts = *

Правила отправки почты

Создайте файл /etc/exim4/smarthosts. В этом файле в каждой строке будет описано правило отправки почты на серверы в зависимости от идентификатора пользователя.

Первое поле - шаблон для идентификатора пользователя, под которым он зарегистрирован на локальном сервере Exim. Обычно он указан в файле /etc/exim4/passwd, однако Exim поддерживает множество способов аутентификации, и у вас может быть настроен любой. Тут можно использовать шаблон, а можно указать отдельный идентификатор.

Второе поле - название транспорта в конфигурации Exim. Мы настроили их выше в /etc/exim4/conf.d/transport/40_smarthosts.

# -*- mode: conf-unix; coding: utf-8 -*-
# шаблон имени отправителя ($authenticated_id):название транспорта
*@gmail.com:gmail
*@mail.ru:mailru
*@list.ru:mailru
*@bk.ru:mailru
*@inbox.ru:mailru

Логика маршрутизации и аутентификации

Создайте файл /etc/exim4/conf.d/router/175_exim4-config_multismart следующего содержания:

# -*- mode: conf-unix; coding: utf-8 -*-
.ifdef DCconfig_smarthost DCconfig_satellite

SMARTHOST_TRANSPORT = ${extract{1}{:}{${lookup{$authenticated_id}nwildlsearch{CONFDIR/smarthosts}{$value}}}}

smarthost_multi:
    debug_print = "R: smarthost_multi for $local_part@$domain"
    driver = manualroute
    condition =  ${if eq {SMARTHOST_TRANSPORT}{}{no}{yes}}
    domains = !+local_domains
    route_list = "* $domain"
    transport = SMARTHOST_TRANSPORT
    ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
    host_find_failed = ignore
    same_domain_copy_routing = yes

.endif

В этом файле описан маршрутизатор, выбирающий транспорт в зависимости от идентификатора пользователя по правилам, описанным в /etc/exim4/smarthosts. Опция route_list не будет использоваться транспортом, так как в нем будет установлено hosts_override = true. SMARTHOST_TRANSPORT извлекает первое поле из строки в файле/etc/exim4/smarthosts, ключом при этом является $authenticated_id, то есть имя, под которым пользователь авторизовался, отправляя письмо на наш локальный сервер.

Теперь самая запутанная часть настройки. В Exim аутентификацию выполняют так называемые "аутентификаторы", и они делятся по типам. Например, традиционную аутентификацию с паролем и логином выполняет аутентификатор plaintext, и он должен сам где-то брать эти пароли для всех серверов, с которыми он будет связываться. В Debian
эти пароли лежат в /etc/exim4/passwd.client, и, увы, конфигурация допускает только один пароль/логин на сервер. Поэтому не получится настроить отправку для нескольких учетных записей на одном сервере (user1@mail.ru, user2@mail.ru…)

У нас пароли лежат, напоминаю, в /etc/exim4/passwd.smarthosts, а аутентификаторы описаны в /etc/exim4/conf.d/auth/30_exim4-config_examples. Чтобы научить аутентификатор искать пароли в /etc/exim4/passwd.smarthosts, примените к /etc/exim4/conf.d/auth/30_exim4-config_examples следующий патч:

--- /etc/exim4/conf.d/auth/30_exim4-config_examples
+++ 30_exim4-config_examples
@@ -210,13 +210,14 @@
   client_name = ${extract{1}{:}{${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$value}fail}}}
   client_secret = ${extract{2}{:}{${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$value}fail}}}

+PLINE=${lookup{$authenticated_id}nwildlsearch{CONFDIR/passwd.smarthosts}{$value}{}}
 # this returns the matching line from passwd.client and doubles all ^
-PASSWDLINE=${sg{\
-                ${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$value}fail}\
-	        }\
-	        {\\N[\\^]\\N}\
-	        {^^}\
-	    }
+PASSWDLINE=${if eq{PLINE}{}{${sg{\
+               ${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$value}fail}\
+               }\
+               {\\N[\\^]\\N}\
+               {^^}\
+           }}{${sg{PLINE}{\\N[\\^]\\N}{^^}}}}

 plain:
   driver = plaintext

Это можно сделать командой:

patch /etc/exim4/conf.d/auth/30_exim4-config_examples ./30_exim_config_examples.diff

Скрипт для Ansible сделает это сам.

Завершение настройки и проверка

Перегенерируйте конфигурацию Exim и перезапустите сервис.

/sbin/update-exim4.conf && systemctl restart exim4

Отправлять тестовые письма удобно с помощью Swaks. Пример:

swaks -tls -a \
      --to user@example.com \
      --from <ваш адрес> \
      --server localhost \
      --auth-user <ваш логин на *локальном* сервере> \
      --auth-password  <ваш пароль на *локальном* сервере>

Настройка с помощью Ansible

Впишите в файл inventory адрес настраиваемой машины и имя пользователя, от которого будет работать Ansible. Разумеется, этот пользователь должен иметь возможность становиться root.

Впишите в раздел vars файла exim-conf-debian.yaml данные для доступа к smarthost-серверу, который будет использоваться по умолчанию, если среди правил отправки не найдется подходящего. Образец:

vars:
  смартхост: smtp.mail.ru
  логин: AzureDiamond@mail.ru
  пароль: hunter2

Откройте файл 40_smarthosts.j2 и посмотрите, нет ли там готовых конфигураций для нужных вам провайдеров. Если нет, впишите свою конфигурацию.

Откройте файл smarthosts.j2 и посмотрите, нет ли там готовых правил для отправки почты. Если нет, впишите свои правила. Пример:

user1:mailru
*@inbox.ru:mailru

При желании добавьте локальных пользователей в файл passwd.j2. По умолчанию там будет только один пользователь с тем же логином и паролем, что используется для доступа к smarthost-серверу по умолчанию (см. выше). Пользователей можно будет добавить позже с помощью скрипта /usr/share/doc/exim4-base/examples/exim-adduser или вручную. См. man exim4-config_files, раздел /etc/exim4/passwd.

Впишите логины и пароли для отправки почты на SMTP-серверы нужных вам провайдеров в passwd.smarthosts.j2. Пример:

# Для Яндекс Почты логином служит часть адреса до @
AzureDiamond@ya.ru:AzureDiamond:hunter2

Запустите скрипт.

ansible-playbook exim-conf-debian.yaml -i inventory

Проверьте, как описано в разделе Завершение настройки и проверка.

Изучите сообщения об ошибках и доработайте напильником.

Примечания

1 exim: select smarthost according to sender address

2 [Pkg-exim4-users] selecting smarthost based on sender address

3 Exim4 and multiple gmail accounts

4 Как настроить Exim на несколько ящиков?

5 Не путайте пользователей локального сервера Exim с
пользователями системы. У одного пользователя системы может быть
несколько учетных записей электронной почты на внешних серверах, и
каждой из них будет соответствовать один пользователь локального
сервера Exim.

6 Этот идентификатор при работе будет
храниться в стандартной переменной $authenticated_id.

7 Транспортом в Exim называется механизм передачи сообщения в
место назначения - удаленный сервер, локальный файл и так далее.

Комментарии (0)