Найти в Дзене

Postfix с SMTP аутентификацией Cyrus

Оглавление

Понадобилось сделать Postfix с SMTP аутентификацией. Раньше не настраивал, перерыл кучу статей. Очень сумбурно всё изложено, поэтому пришлось написать свой вариант. Если кто-то знает хорошую инструкцию по данному вопросу без лишней воды — пишите в комментариях.

Я хотел реализовать обычный рассыльщик писем без приёма почты. Никаких POP3 и IMAP, чистый SMTP. При этом не хотелось устанавливать какие-то лишние компоненты. Я уверен, что задачу можно было выполнить проще, кто подскажет — молодец.

Окружение

Операционная система

Используем операционную систему Ubuntu Server 20.04 LTS. Если кому-то нужна инструкция по установке, то вот ссылка:

Установка Ubuntu Server 20.04 LTS на виртуальную машину VMware ESXi 6.7

Итак, ОС установлена.

lsb_release -a
-2

Почта

Почтовый сервер Postfix.

Аутентификация SMTP

Для аутентификации использую Cyrus. Пользователей SMTP будем хранить в локальной базе sasldb (Cyrus SASL Berkeley DB database).

Домен

Я создам для тестирования отдельный домен третьего уровня testsender.internet-lab.ru, настрою DNS и буду слать письма с адреса info@testsender.internet-lab.ru. Пароль пользователя "888776". После выхода статьи пароль сменю :)

Настройка DNS

Добавим домен testsender.internet-lab.ru и настроим почту. Добавляем A запись домена. Я использую тот же IP, что у основного домена.

-3

Postfix будет представляться как postfix.testsender.internet-lab.ru, добавим A запись.

-4
-5

Настроим SPF и DMARC, чтобы письма можно было отправлять со своего IP адреса.

-6

Установка Postfix

Установим Postfix самым простым способом из репозитория без настроек.

apt-get update
apt-get install postfix

Общий тип почтовой настройки выбираем "Без настройки":

-7

OK.

dpkg -l | grep postfix
-8

Установлен postfix версии 3.4.10.

Настройка Postfix

Создаём главный файл настроек /etc/postfix/main.cf:

myorigin = postfix.testsender.internet-lab.ru
myhostname = postfix.testsender.internet-lab.ru
mydomain = testsender.internet-lab.ru

smtpd_banner = postfix.testsender.internet-lab.ru
biff = no

alias_maps = hash:/etc/postfix/aliases

mynetworks = 127.0.0.0/8 192.168.1.0/24 [::ffff:127.0.0.0]/104 [::1]/128
message_size_limit = 35840000
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

masquerade_classes = envelope_sender, header_sender

relay_domains = testsender.internet-lab.ru

maximal_queue_lifetime = 5d

compatibility_level = 2

Пока ничего особо не настроено, почтовик обслуживает один домен testsender.internet-lab.ru. Представляется как postfix.testsender.internet-lab.ru, 192.168.1.0/24 — моя локальная сеть, из которой я буду отправлять в postfix письма. После настройки SMTP аутентификации отправлять письма можно будет не только из этой сети.

Создаём файл /etc/postfix/aliases:

postmaster:root

Выполняем:

postalias /etc/postfix/aliases

Перезагружаем Postfix.

service postfix restart
-9

Проверка отправки письма

Из подсети 192.168.1.0/24 пытаемся отправить письмо с помощью telnet по 25 порту.

telnet 192.168.1.13 25
ehlo localhost
-10

Отправляем письмо без аутентификации.

-11

Письмо ушло в postfix. Смотрим логи postfix:

-12

status=sent, письмо отправлено. Уже хорошо, система заработала. Получатель, конечно, попытался далее переслать письмо мне на ящик в gmail, но не смог.

-13

Не понравилось ему, что нет заголовка "From". Но это уже другая история. Кстати, можно обойти проблему, отправив письмо с помощью VBS, накидал скрипт:

Set emailObj = CreateObject("CDO.Message")

emailObj.From = "Тест postfix <info@testsender.internet-lab.ru>"
emailObj.To = "info@internet-lab.ru"

emailObj.Subject = "Test postfix"
emailObj.TextBody = "Test body postfix"

Set emailConfig = emailObj.Configuration

emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "192.168.1.13"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 0
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = false

emailConfig.Fields.Update

emailObj.Send

If err.number = 0 then Msgbox "Done"

Отправляю скриптом:

-14

Письма дошло, можно двигаться дальше.

Аутентификация

Для начала настроим пользователей для аутентификации. Для администрирования пользователей базы sasldb понадобится пакет sasl2-bin.

Ещё нужны модули libsasl2-2 и libsasl2-modules, но они уже есть:

dpkg -l | grep sasl
-15

Установим sasl2-bin:

apt-get install sasl2-bin
-16

Редактируем файл /etc/default/saslauthd.

Включаем saslauthd:

START=yes

Механизм аутентификации sasldb:

MECHANISMS="sasldb"
-17

Для postfix указываем опцию:

OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"
-18

Перезагружаем saslauthd:

service saslauthd restart

Вместе с пакетом sasl2-bin устанавливаются утилиты для работы с пользователями sasldb: saslpasswd2, sasldblistusers2, testsaslauthd.

Создаём пользователя info@testsender.internet-lab.ru с паролем 888776:

saslpasswd2 -c -u testsender.internet-lab.ru info
-19

Посмотреть список пользователей в базе:

sasldblistusers2
-20

Видим что в базе один пользователь info@testsender.internet-lab.ru, пароль не отображается.

Утилита testsaslauthd позволяет проверить аутентификацию:

testsaslauthd -u info -r testsender.internet-lab.ru -p 888776

Результат:

connect() : No such file or directory
-21

Упс, что-то не работает. На самом деле всё просто, мы в опциях /etc/default/saslauthd сменили директорию /var/run/saslauthd на /var/spool/postfix/var/run/saslauthd, утилита работает с /var/run/saslauthd. Исправим проблему, правильнее всего монтировать директорию в нужное место, добавляем в /etc/fstab:

/var/run/saslauthd /var/spool/postfix/var/run/saslauthd none rw,bind 0 0
-22

Перезагружаем сервер:

reboot

После перезагрузки проверяем аутентификацию:

testsaslauthd -u info -r testsender.internet-lab.ru -p 888776

Результат:

0: OK "Success."
-23

Мы добились успешной аутентификации созданного нами пользователя.

Аутентификация в Postfix

Сама база пользователей sasldb находится в /etc/sasldb2.

cd /etc
ll | grep sasl
-24

Для того, чтобы Postfix мог читать из базы, пользователю postfix нужно дать права на файл sasldb2. Файл sasldb2 принадлежит группе sasl. Добавим пользователя postfix в группу sasl:

usermod -a -G sasl postfix

Находим директорию /etc/postfax/sasl:

-25

Создаём в директории /etc/postfax/sasl файл smtpd.conf:

pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
-26

Выполняем:

postconf -a
-27

И видим, что Postfix по умолчанию поставляется с поддержкой cyrus и dovecot. Я выбрал cyrus. Ставим пакет cyrus-common:

apt-get install cyrus-common
-28

Спрашивают про какие-то буферы. Говорю Yes.

Настраиваем аутентификацию в Postfix. Модифицируем файл настроек /etc/postfix/main.c. Добавляем:

smtpd_sasl_type = cyrus
smtpd_sasl_path = smtpd
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtp_tls_security_level = may

Получилось:

myorigin = postfix.testsender.internet-lab.ru
myhostname = postfix.testsender.internet-lab.ru
mydomain = testsender.internet-lab.ru

smtpd_banner = postfix.testsender.internet-lab.ru
biff = no

alias_maps = hash:/etc/postfix/aliases

mynetworks = 127.0.0.0/8 192.168.1.0/24 [::ffff:127.0.0.0]/104 [::1]/128
message_size_limit = 35840000
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

masquerade_classes = envelope_sender, header_sender

relay_domains = testsender.internet-lab.ru

maximal_queue_lifetime = 5d

compatibility_level = 2

smtpd_sasl_type = cyrus
smtpd_sasl_path = smtpd
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtp_tls_security_level = may

Перезагружаю сервисы:

service postfix restart
service saslauthd restart

Проверка отправки письма с аутентификацией

Из подсети 192.168.1.0/24 пытаемся отправить письмо с помощью telnet по 25 порту.

telnet 192.168.1.13 25
ehlo localhost
-29

Строка AUTH PLAIN LOGIN символизирует наличие возможности аутентификации.

Отправляем письмо с аутентификацией. Для этого нам понадобится перевести логин и пароль в формат Base64. Можно найти онлайн декодер.

  • Логин "info@testsender.internet-lab.ru" в Base64 — "aW5mb0B0ZXN0c2VuZGVyLmludGVybmV0LWxhYi5ydQ==".
  • Пароль "888776" в Base64 — "ODg4Nzc2".

Отправляем письмо:

-30

Сообщение 235 2.7.0 Authentication successful говорит о том, что аутентификация успешна.

Отправляем также VBS скриптом:

Set emailObj = CreateObject("CDO.Message")

emailObj.From = "Тест postfix SASL<info@testsender.internet-lab.ru>"
emailObj.To = "info@internet-lab.ru"

emailObj.Subject = "Test postfix"
emailObj.TextBody = "Test body postfix"

Set emailConfig = emailObj.Configuration

emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "192.168.1.13"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "info@testsender.internet-lab.ru"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "888776"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = false

emailConfig.Fields.Update

emailObj.Send

If err.number = 0 then Msgbox "Done"
-31

Письмо доставлено.

Настройка DKIM

Правим главный файл настроек /etc/postfix/main.cf, добавляем:

milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Ставим opendkim:

apt-get install opendkim opendkim-tools

Создаём каталог для ключей и сгенерируем ключ (пока для одного домена):

mkdir /etc/opendkim
opendkim-genkey -D /etc/opendkim/
--domain testsender.internet-lab.ru --selector testsenderpostfix

Где testsenderpostfix — придуманный селектор, можно любой придумать.

Появится два файла /etc/opendkim/testsenderpostfix.private и /etc/opendkim/testsenderpostfix.txt с секретным и публичным ключами. Публичный ключ нужно добавить в соответствующую TXT запись вашего домена:

testsenderpostfix._domainkey.testsender IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApjvmaLNcAnyLmBxUw1b7EGPQ5BdZbbsM+HQ0qIsjdkcidYjJR/z39xw0gRbFC7+WMfj6zrutTBb5PJwRmb9zIM4nhs4KvxPVSMSA1mkmVDdjKqF7MJ3dUhRmpXcgVH0Mh4zzIeZQO1skg13HPBcGrPqVF3LebZ2v4PenfWxm/CJrBxJD++MLi0IdPvxu4/OQl+ZgZCuasN7iNj"
"fK4MGsYxzAmYgZhSP2qVGNdKWnrmuKLV6/wijqfEA677KunkFJxqtssBfijCYE61/+5RTUxWGNdaoPxzWhO8H00HOfxc374dOE9SKpSKqr21Xj8O20GL+Q6mzl7LTOkHkut6e1dQIDAQAB" )

Настраиваем /etc/opendkim.conf:

Syslog No
Mode sv
SOCKET="inet:8891@localhost"
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

Создаём файл /etc/opendkim/KeyTable:

testsenderpostfix._domainkey.testsender.internet-lab.ru testsender.internet-lab.ru:testsenderpostfix:/etc/opendkim/testsenderpostfix.private

Создаём файл /etc/opendkim/SigningTable:

*@testsender.internet-lab.ru testsenderpostfix._domainkey.testsender.internet-lab.ru

Задаем группу владельца opendkim для созданных ключей и файлов:

chown :opendkim /etc/opendkim/*

Устанавливаем права на секретный ключ:

chmod 640 /etc/opendkim/testsenderpostfix.private

Перезапускаем postfix и opendkim:

service opendkim restart
service postfix restart

Осталось только проверить и отправить письмо.

-32

Источник:
https://internet-lab.ru/postfix_smtp_auth_cyrus

Если вам понравилась статья, то ставьте 👍🏻 каналу.
Пишите комментарии, задавайте вопросы, подписывайтесь.