Настройка DKIM и SPF на Ubuntu 12.04 + Sendmail


DKIM — это цифровая подпись писем, отправляемых с вашего сервера. Она гарантирует, что письмо отправлено именно с него, и не было изменено.

Наличие DKIM на отправляемой корреспонденции крайне положительно сказывается на прохождении antispam тестов, поэтому лучше бы её настроить.

Краткий принцип работы заключается в том, что на сервере лежит закрытый ключ, которым подписываются исходящие письма. Удалённый почтовый сервер (Яндекс или Google) при получении письма видит в заголовках эту подпись и проверяет ее путем запроса открытого ключа из DNS домена.

Пример заголовка с DKIM:
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=modx-test.com; s=mail;
	t=1378025116; bh=E27pqP5aWa/XXOeVzzjMW+iw0W7wbbCe2B4toIRxP9M=;
	h=To:Subject:Date:From:Reply-To:From;
	b=GqprdvEYgq/Ff95fCDNzV4k1JLaMA9Pz5p5PUyv2bI0UVZ/S1xl6IyAZK4j3FwMCW
	 5cLe4IGcmnd+dNzNhe2bSj/kCIJg7ZyLM3mXAzEirGXdiqCc/LAZQOGR7udbMmm5YP
	 42pkMa2lI9FqKxAKq5BrtXbrWE+n+Mxc5dpQcGMw=
Если подпись, сгенерированная сервисом, используя содержимое письма и открытой подписи совпадает с той, что указана в заголовке, значит — письмо настоящее и его не модифицировали после отправки с родного сервера.
Если нет — это подделка и, скорее всего, спам.

Под катом пошаговое how-to с картинками, для серверов, настроенных по этой инструкции, как научить Sendmail работать с DKIM.

Настройка

Обновляем индекс пакетов и устанавливаем opendkim:
sudo apt-get update
sudo apt-get install opendkim

Приводим /etc/opendkim.conf к следующему виду:
Syslog                  yes
UMask                   002
Domain                  имявашегодомена.ru
KeyFile                 /etc/mail/dkim.key
Selector                mail
SubDomains              yes
OversignHeaders         From
Socket                  inet:8891@localhost

В параметре Domain можно указать несколько доменов, через пробел. Вся почта от них, и их поддоменов будет подписана DKIM.
Например
Domain		bezumkin.ru modx-test.com
подпишет все письма от modx23.modx-test.com, от bezumkin.ru, от tefile.modx-test.com и т.д.

Теперь нам нужно сформировать ключи (закрытый и открытый) на сервисе DKIMCore. Вводим имя своего домена и кликаем generate.

В результате получаем 2 ключа

Первый ключ, закрытый, нужно сохранить в /etc/mail/dkim.key. Обязательно задаём права для чтения только владельцем (root), иначе opendkim не запустится:
chmod 0600 /etc/mail/dkim.key

Этот закрытый ключ будет подписывать всю исходящую почту от указанных доменов в конфиге. Чтобы удалённый почтовый сервис мог проверить эту подпись, мы должны указать открытый ключ в DNS.

Для этого создаём новый домен mail._domainkey и добавляем в него только одну TXT запись:
v=DKIM1;k=rsa;t=s;p=здесь открытый ключ


Такие поддомены нужно создать для всех указанных доменов. Правильность указания можно проверять в консоли вот так:
dig mail._domainkey.modx-test.com TXT

Вот мой открытый ключ. Имейте в виду, что записи в DNS обновляются далеко не сразу.

Теперь осталось только заставить sendmail отдавать исходящие письма на подпись. Для этого добавляем в конец файла /etc/mail/sendmail.mc, строку:
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost')dnl
Конвертируем этот файл в конфиг
m4 sendmail.mc > sendmail.cf

И перезапускаем сервисы
service opendkim restart
service sendmail restart
Консольная команда netstat -nlp должна показывать, что sendmail и opendkim слушают свои порты, то есть — работают.


Проверяем подпись

Для проверки работы DKIM, нужно отправить письмо на сервис, который его проверяет (а это почти все публичные почтовики), например — на Яндекс.

Это можно сделать из консоли:
echo -e "To: вашемаил@yandex.ru\\nFrom: noreply@вашдомен.ru\\nSubject: Test\\nTest\\n" | sendmail -bm -t -v
Или прямо с сайта MODX, при помощи пакета QuickEmail.
[[!QuickEmail?
	&to=`вашемаил@yandex.ru`
	&debug=`1`
]]
  • Отправка:
  • Приём:
С сегодняшнего дня, все письма с bezumkin.ru и modx-test.com подписываются DKIM.

Настройка SPF

Есть еще одна технология, попроще — это SPF.

Она позволяет указать в DNS, какие серверы могут отправлять посту от имени вашего домена. Делается это так же записью TXT, но уже не поддомену, а самому основному домену, или записи @ (если есть):
v=spf1 ip4:151.236.219.215 ip6:2a01:7e00::f03c:91ff:feae:4fa1 a ~all
Здесь указаны 2 ip адреса (версий 4 и 6), которые могут отправлять письма от моего домента. ~all разрешает мягкую проверку. То есть, даже если тест SPF не проходит, то письма будут приняты удалённым сервисом, но он обратит на них повышенное внимание.

Сочетание настроенных SPF и DKIM сводит вероятность попадания писем от вашего сервера в спам практически к нулю.
Смотреть результаты тестов нужно в заголовках принятого письма.

Вот, что говорит Яндекс:
Authentication-Results: mxfront4m.mail.yandex.net; spf=pass (mxfront4m.mail.yandex.net: domain of modx-test.com designates 151.236.219.215 as permitted sender) smtp.mail=info@modx-test.com; dkim=pass header.i=@modx-test.com
А вот — Google:
Received-SPF: pass (google.com: domain of noreply@bezumkin.ru designates 2a01:7e00::f03c:91ff:feae:4fa1 as permitted sender) client-ip=2a01:7e00::f03c:91ff:feae:4fa1;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of noreply@bezumkin.ru designates 2a01:7e00::f03c:91ff:feae:4fa1 as permitted sender) smtp.mail=noreply@bezumkin.ru;
       dkim=pass header.i=@bezumkin.ru
Обратите внимание, мой сервер на Linode общается с Google через ipv6. Но независимо от способа соединения, вы должны видеть spf=pass и dkim=pass.

Обновлено 30.06.2016

Судя по всему, настройка для нескольких доменов уже не работает. Для этого нужно делать так — dev.kafol.net/2013/01/dkim-spf-sendmail-for-multiple-domains.html
01 сентября 2013, 13:04    Василий Наумкин   G+  
5    13190 0

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

  1. Александр Наумов 01 сентября 2013, 21:31 # 0
    Супер!!! У меня постоянно на Gmail письма попадают в спам, надеюсь что данное решение поможет.
    1. Василий Наумкин 01 сентября 2013, 21:54 # 0
      Больше решений, вроде как, и нет.

      Если ты не рассылаешь спам, у тебя статический белый ip и настроены SPF и DKIM — то все будет хорошо.
      1. Алексей Карташов 05 сентября 2013, 22:49 # 0
        Интересно, а массовая рассылка чего-либо (новости, акции) СВОИМ подписчикам (не из какой-нибудь купленной базы) считается спамом? Ну т.е. обратят ли почтовики повышенное внимание к почтовой активности нашего сервера?
        1. Василий Наумкин 05 сентября 2013, 23:01 # 0
          Если не будет жалоб — нет, не обратят.
    2. Алексей 22 ноября 2013, 10:44 # 0
      Если не секрет, то как заставить сервер на линоде работать с новым IP протоколом версии ipv6?
      1. Василий Наумкин 22 ноября 2013, 11:24 # 0
        Да он вроде и так с ним работает, автоматически.
      2. Виталий Киреев 16 декабря 2013, 06:11 # 0
        По SPF на Линоде: не дает создать поддомен с именем «@». Яндекс говорит: «В этом случае укажите в качестве имени записи имя вашего домена с точкой на конце».
        1. Алексей Карташов 19 июля 2014, 18:44 # 0
          Вась, немного не понятно…
          Например
          Domain		bezumkin.ru.modx-test.com
          подпишет все письма от modx23.modx-test.com, от bezumkin.ru, от tefile.modx.pro и т.д.
          Прям так и писать без пробелов?
          И по какому принципу определяются поддомены, которые будут подписаны? Смутило то, что под вышеописанную строку подпадает домен tefile.modx.pro — ведь в этой инструкции нет ни поддомена tefile, ни modx, ни pro.
          1. Алексей Карташов 19 июля 2014, 19:11 # 0
            И вообще, как я понял, чтобы добавить несколько доменов для подписей dkim, надо делать по-другому.
            Вот что удалось нагуглить: edoceo.com/howto/opendkim

            Т.е. на моей vps-ке лежит много сайтов. Я хочу, чтобы каждый домен подписывался dkim'ом.
            Тогда в директиве KeyFile вместо файла ключа для одного домена надо указать путь к txt, в котором будет примерно следующее:
            # $sender-pattern:$signing-domain:$keypath
            *@domainA.com:domainA.com:/etc/opendkim/domainA.com.key
            *@domainB.com:domainB.com:/etc/opendkim/domainB.com.key
            *@domainC.com:domainC.com:/etc/opendkim/domainC.com.key
            Т.е. каждый необходимый для подписи домен нужно заносить сюда ручками и для каждого такого домена генерировать свой ключ (и в dns записях, соответственно, для каждого домена будет своя уникальная запись с открытым ключом). И тогда директива Domain уже не нужна (ибо список доменов лежит в отдельном файле).
            Я правильно понял данную магию?)

            Но непонятна цель файла с Trusted Hosts из статьи по ссылке выше.

            Вась, развей мои сомнения!
            1. Василий Наумкин 19 июля 2014, 19:12 # 0
              Да фиг знает, я все одним ключом подписываю.

              Поэксперементируй и расскажи, что найдешь интересного.
              1. Алексей Карташов 19 июля 2014, 19:21 # 0
                Просто вот только сейчас до меня дошло, почему ни одно письмо со всех остальных доменов не подписывались. Ибо в dns каждого домена я, как и ты, тупо пихал один и тот же открытый ключ xD
                Счас поэкспериментирую.

                p.s. rm -r /* в руках дилента — ссущее зло. поэтому заново всё настраиваю)
                1. dimka3210 13 декабря 2014, 12:45 # 0
                  Как успехи? Получилось настроить несколько доменов?
            2. Василий Наумкин 19 июля 2014, 19:11 # 0
              Опечатка, через пробел нужно.
              tefile.modx.pro — это от автозамены modx-test.com на modx.pro =)

              Всё поправил.
            3. Михаил 21 октября 2014, 12:46 # 0
              Отличная статья, сподвигнула настроить на сервере почтовик. Только я использовал Postfix. Если кому интересно могу выложить ман по настройке.
              У меня вопрос. Как принимать письма? Вот ушло письмо, оно с адреса noreply@domen.ru. А как принимать ответы на письма?
              1. Василий Наумкин 21 октября 2014, 15:56 # 0
                Принимать письма лучше сторонним почтовым сервисом, типа Яндекс Почта для Доменов.

                Делать свой почтовик очень сложно и бессмысленно.
                1. Михаил 21 октября 2014, 15:58 # 0
                  А если они просто захотят ответить, тут надо в поле ответа записывать рабочий адрес? Я верно понимаю?
                2. dimka3210 13 декабря 2014, 04:54 # 0
                  Выложи пожалуйста для postfix
                  1. Михаил 13 декабря 2014, 05:19 # 0
                    1. dimka3210 13 декабря 2014, 11:53 # 0
                      Спасибо. Все взлетело. Теперь нужно разобраться если несколько доменов.
                3. Сергей 21 августа 2015, 10:49 # 0
                  Немного непонятно про Селектор. На сервисе DKIMCore вам был сгенерирован селектор bezumkin. Но вы в своих настройках использовали — mail. То есть, селектор можно погодя какой угодно придумать (ну, и соответственно прописать его на DNS-сервере)?

                  И еще, там на скриншоте даже перед селектором есть какие-то цифры. Я так понимаю, их тоже можно опустить в настройке DNS-сервера?
                  1. Алексей Юмашин 02 декабря 2015, 22:05 # 0
                    Василий, подскажи плиз, в каком направлении копать, сделал хостинг по твоей инструкции под Линод (За что тебе огромное человеческое спасибо!!), тут тоже все под копирку, тока конечно под свои домен меняю, настраивал dkim и вот запара

                    вызываю sudo service opendkim restart

                    получаю
                    Restarting OpenDKIM: No /usr/sbin/opendkim found running; none killed.
                    opendkim: /etc/opendkim.conf: /etc/mail is writeable and owned by uid 106 which is not the executing uid (108) or the superuser
                    opendkim.

                    что не так, направь пожалуйста
                    1. Алексей Юмашин 03 декабря 2015, 07:02 # 0
                      Похоже что то с chmod не верно выставляет, даже точнее не проходит на проверку, но как я не пробовал, ни чего не смог добиться
                      1. Пётр Молчанов 03 декабря 2015, 11:57 # 0
                        было такое, придется колдовать с правами и пользователем. гугл очень помог, гугли по названию ошибки и читай забугорные форумы
                        З.Ы.: у себя проблему решил, но как конкретно не помню, но точно манипулировал правами и пользователем
                    Вы должны авторизоваться, чтобы оставлять комментарии.