108.53
Rating
Plesk
Plesk – панель управления хостингом
27 June 2016

Yandex «Почта для домена» как почтовый шлюз для ваших серверов

Plesk corporate blog
Tutorial

Каждый раз поднимая новый сервер в облаках, вы получаете случайный IP-адрес. Не все понимают, что IP-адрес может попасть к вам с "историей". Часто приходится тратить время на удаление IP из публичных черных списков. В моём случае в последний раз это была очень неторопливая переписка с mail.ru, которая ни к чему не привела. После этого, создав новый сервер, я задумался: как же сделать так, чтобы не огребать проблем с такими IP-адресами?


Введение


Несмотря на то, что серверы у меня могут быть как постоянные так и "на поиграться", почту на всех них я не обслуживаю, но очень хочу получать сервисные письма от своих скриптов и системных служб.


Очевидное решение — сделать свой "порядочный" почтовый шлюз и все остальные серверы настраивать на пересылку почты через этот шлюз. Минусы такого решения очевидны:


  • Отдельный сервер стоит денег, даже если это дешевая VPSка
  • IP-адрес надо постоянно отслеживать в черных списках
  • Настройка почтового шлюза требует времени, которое зависит от ваших скиллов

Из-за вышеперечисленных причин я пошёл искать другое решение, и, что характерно, нашёл.


Решение


Я обнаружил возможность схалявить, воспользовавшись сервисом "Почта для Домена" от Yandex. На тот момент у меня было поднято 3 сервера и в DNS были следующие А-записи:


Хост Тип Значение
example.com A 123.123.123.120
server1.example.com A 123.123.123.121
server2.example.com A 123.123.123.122
server3.example.com A 123.123.123.123

Я зарегистрировал свой технический домен в "Почте для Домена" и создал аккаунт: root@example.com. Попробовал отправить письма с одного из своих серверов, используя этот SMTP-аккаунт и получил следующую ошибку:


553 5.7.1 Sender address rejected: not owned by auth user.
envelope from address root@server1.example.com not accepted by the server

Yandex не разрешает подставлять какие попало данные в envelope-from. Но как же быть, если хочется понимать, с какого сервера пришло то или иное письмо, без дополнительных ухищрений?


Чтобы соблюсти правила Yandex'a, нужно выполнить следующие шаги на стороне их сервиса:


  1. Зарегистрировать основной домен и его поддомены в pdd.yandex.ru. Проще всего пройти подтверждение домена через добавление CNAME-записи:


    Хост Тип Значение
    example.com CNAME verification-code
    server1.example.com CNAME verification-code
    server2.example.com CNAME verification-code
    server3.example.com CNAME verification-code

  2. Так же для каждого домена создаем MX-запись:


    Хост Тип Приоритет Значение
    example.com MX 10 mx.yandex.ru
    server1.example.com MX 10 mx.yandex.ru
    server2.example.com MX 10 mx.yandex.ru
    server3.example.com MX 10 mx.yandex.ru

  3. В настройках основного домена указать поддомены как алиасы этого домена.



  4. Создаём почтовый аккаунт root@example.com, если он ещё не создан



  5. Обязательно нужно зайти в аккаунт через веб-интерфейc и активировать его, иначе получите ошибку:
    535 5.7.8 Error: authentication failed: Please accept EULA first. https://mail.yandex.ru/for/example.com


Дальше требуется работа на нашей стороне — настраиваем сервера:


  1. Устанавливаем msmtp — миниатюрный SMTP-клиент, который предоставляет свою реализацию sendmail
  2. Настраиваем его:


    defaults
    
    syslog LOG_MAIL
    
    tls_certcheck off
    tls on
    
    auto_from on
    # server hostname
    maildomain server1.example.com
    
    account default
    
    host smtp.yandex.ru
    port 25
    
    auth on
    user root@example.com
    password 123qwe

  3. Отправляем тестовое письмо с отладкой:
    echo -e "test message" | /usr/bin/msmtp --debug -t -i sugdyzhekov@plesk.com

    и смотрим результат:

    loaded system configuration file /etc/msmtprc
    ignoring user configuration file /root/.msmtprc: No such file or directory
    falling back to default account
    using account default from /etc/msmtprc
    host = smtp.yandex.ru
    port = 25
    proxy host = (not set)
    proxy port = 0
    timeout = off
    protocol = smtp
    domain = localhost
    auth = choose
    user = root@example.com
    password = *
    ntlmdomain = (not set)
    tls = on
    tls_starttls = on
    tls_trust_file = (not set)
    tls_crl_file = (not set)
    tls_fingerprint = (not set)
    tls_key_file = (not set)
    tls_cert_file = (not set)
    tls_certcheck = off
    tls_min_dh_prime_bits = (not set)
    tls_priorities = (not set)
    auto_from = on
    maildomain = server1.example.com
    from = root@server1.example.com
    add_missing_from_header = on
    add_missing_date_header = on
    remove_bcc_headers = on
    dsn_notify = (not set)
    dsn_return = (not set)
    logfile = (not set)
    syslog = LOG_MAIL
    aliases = (not set)
    reading recipients from the command line and the mail
    <-- 220 smtp3h.mail.yandex.net ESMTP (Want to use Yandex.Mail for your domain? Visit http://pdd.yandex.ru)
    --> EHLO localhost
    <-- 250-smtp3h.mail.yandex.net
    <-- 250-8BITMIME
    <-- 250-PIPELINING
    <-- 250-SIZE 42991616
    <-- 250-STARTTLS
    <-- 250-AUTH LOGIN PLAIN XOAUTH2
    <-- 250-DSN
    <-- 250 ENHANCEDSTATUSCODES
    --> STARTTLS
    <-- 220 Go ahead
    TLS certificate information:
    Owner:
        Common Name: smtp.yandex.ru
        Organization: Yandex LLC
        Organizational unit: ITO
        Locality: Moscow
        State or Province: Russian Federation
        Country: RU
    Issuer:
        Common Name: Yandex CA
        Organization: Yandex LLC
        Organizational unit: Yandex Certification Authority
        Country: RU
    Validity:
        Activation time: Mon 12 Oct 2015 03:41:24 PM MSK
        Expiration time: Wed 11 Oct 2017 03:41:24 PM MSK
    Fingerprints:
        SHA1: B7:0E:62:55:E1:3A:C0:F3:08:12:35:B2:9D:4B:25:D0:B8:C1:C6:39
        MD5:  BC:15:CE:B6:D4:FF:0D:95:4F:E5:1A:A7:3A:DF:DA:65
    --> EHLO localhost
    <-- 250-smtp3h.mail.yandex.net
    <-- 250-8BITMIME
    <-- 250-PIPELINING
    <-- 250-SIZE 42991616
    <-- 250-AUTH LOGIN PLAIN XOAUTH2
    <-- 250-DSN
    <-- 250 ENHANCEDSTATUSCODES
    --> AUTH PLAIN AhJvb3ARY29uzMlntS5ydQBXYw5VcMMlazk=
    <-- 235 2.7.0 Authentication successful.
    --> MAIL FROM:<root@server1.example.com>
    --> RCPT TO:<sugdyzhekov@plesk.com>
    --> DATA
    <-- 250 2.1.0 <root@server1.example.com> ok
    <-- 250 2.1.5 <sugdyzhekov@plesk.com> recipient ok
    <-- 354 Enter mail, end with "." on a line by itself
    --> From: root@server1.example.com
    --> Date: Mon, 06 Jun 2016 16:17:00 +0300
    --> test message
    --> .
    <-- 250 2.0.0 Ok: queued on smtp3h.mail.yandex.net as 1465219021-86hlZkGCpZ-H0J8ORE2
    --> QUIT
    <-- 221 2.0.0 Closing connection.

    Отлично, успех! Письмо ушло, правда, найдем мы его в спаме, так как оно почему-то пустое. Давайте проверим более привычным и "человеческим" способом:

    echo "test message" | mailx -s 'test subject' sugdyzhekov@plesk.com

    Вот, теперь в ящике нормальное письмо. Здорово!



    DKIM & SPF


    А еще можно для каждого домена прописать записи DKIM и SPF. Если вы, как я, используете свой DNS-хостинг, то просто скопируйте соответствующие значения из “DNS редактора” в интерфейсе Яндекса. Внимание: для каждого домена и алиаса свой ключ!


    Хост Тип Значение
    mail._domainkey.example.com TXT v=DKIM1; k=rsa; t=s; p=MIGf...
    mail._domainkey.server1.example.com TXT v=DKIM1; k=rsa; t=s; p=MIGf...
    mail._domainkey.server2.example.com TXT v=DKIM1; k=rsa; t=s; p=MIGf...
    mail._domainkey.server3.example.com TXT v=DKIM1; k=rsa; t=s; p=MIGf...

    Отсылаем с сервера письмо и смотрим в заголовки:


    DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mail; t=1467009762;
        bh=Pb6s/Xlf4...
    Authentication-Results: smtp14.mail.yandex.net; dkim=pass header.i=@example.com

    Лепота!


    В случае если отправка почты для домена будет происходить только через сервера Яндекс и с заранее известных IP-адресов, то можно смело прописать SPF-записи в соответствии с документацией https://yandex.ru/support/pdd/troubleshooting/dns.xml#step2


    Хост Тип Значение
    example.com TXT v=spf1 redirect=_spf.yandex.net
    server1.example.com TXT v=spf1 redirect=_spf.yandex.net
    server2.example.com TXT v=spf1 redirect=_spf.yandex.net
    server3.example.com TXT v=spf1 redirect=_spf.yandex.net

    Нюансы


    Скорее всего, вы молодцы, и ваше приложение работает не из под root'а. Попытка послать письмо из-под обычного пользователя опять приведёт к знакомой ошибке в логе msmtp:


    Jun  6 14:21:24 server1 msmtp: host=smtp.yandex.ru tls=on auth=on user=root@example.com from=app@server1.example.com recipients=sugdyzhekov@plesk.com smtpstatus=553 smtpmsg='553 5.7.1 Sender address rejected: not owned by auth user.' errormsg='envelope from address user@server1.example.com not accepted by the server' exitcode=EX_DATAERR

    Можно решить эту проблему по-разному. Например, можно явно указывать пользователя, отключив опцию auto_from off в msmtp. Но я уже решил, что меня это не устраивает.


    Правильное решение — добавить пользователя как алиас для нашего основного адреса:



    Локальный релей


    Если вам требуется локальный SMTP-релей, то данная конфигурация вам тоже подходит. Нужно просто заменить msmtp на postfix или exim, настроенные на использование серверов Яндекса в качестве smart host'a (гуглить можно, например, по ключевым словам exim smarthost).


    Резюме


    Теперь любой сервер, который я поднимаю для своих задачек, сразу же получает настроенный канал отправки почты. В DNS и pdd.yandex.ru я заранее прописал несколько поддоменов про запас. Так как сервера я разворачиваю через SaltStack, то конфигурацию msmtp мои сервера получают автоматически.


    Что я получил в итоге:


    1. Самое главное — нет заморочек с черными списками и IP-адресами серверов, так как письма уходят через сервера Яндекса
    2. DKIM/SPF "из коробки" — письма не попадают в спам
    3. msmtp простой SMTP-клиент, которому даже в памяти сервера висеть не нужно — запускается по необходимости
    4. msmtp — простейшая настройка в отличие от "взрослых" postfix, exim
    5. можно не беспокоиться о PTR-записях для ваших IP-адресов с точки зрения почтовой системы.

    Надеюсь эта инструкция кому-нибудь пригодится. Буду рад узнать из комментариев, кто и как решает подобную проблему.

Tags:yandex pddyandex почтаdnsdkim
Hubs: Plesk corporate blog
+9
58k 88
Comments 21
Middle Developer PHP/JS (SolusIO)
from 90,000 to 150,000 ₽PleskНовосибирскRemote job
Top of the last 24 hours
Information
Founded

1 January 2016

Location

Швейцария

Employees

201–500 employees

Registered

22 December 2015