SPF и DomainKeys для «чайников»

В заголовках писем от CMS моего сайта я вижу такую строку

Authentication-Results: mxfront10h.mail.yandex.net; spf=softfail (mxfront10h.mail.yandex.net: transitioning domain of noteskeeper.ru does not designate 46.254.17.128 as permitted sender) smtp.mail=www-data@noteskeeper.ru

Казалось бы, правильный IP-адрес и домен, а принимающий сервер пишет, что не дозволенный отправитель. Я начал разбираться с этим вопросом и открыл для себя SPF (Sender Policy Framework), DomainKeys и DKIM (DomainKeys Identified Mail).

Оказалось, что можно обозначить определенные IP адреса разрешенными для отправки почты конкретного домена. А потом ещё и стравить цифровую подпись, удостоверяющую, что письмо действительно было отправлено с указанного сервера.

SPF

Особенностью моей ситуации было то, что вся почта обслуживается сервисом Яндекс.Почта для домена. Но и сам хост также может отправлять письма.

У меня уже была указана spf-запись, которая приводится в инструкции по настройке «Почты для домена». Мне нужно было как-то добавить IP адрес хоста в разрешенные отправители почты. Это на деле оказалось не так уж сложно:

@ IN TXT "v=spf1 a include:_spf.yandex.ru -all"

Эта конструкция предписывает считать хост, обозначенный записью A домена, как разрешенный и далее получить ещё дополнительные правила у Яндекса.

Синтаксис и масса других примеров описаны в документации к проекту Sender Policy Framework.

dkfilter

Я решил пойти дальше и настроить цифровую подпись всех писем, которые отсылаются с моего хоста. После недолгих поисков я нашел отличное решение для своей VPS под управлением Ubuntu — dkfilter. Не буду пересказывать принцип настройки этого фильтра. Автор достаточно подробно и точно описал, что нужно сделать.

От себя добавлю несколько изменений, которые мне потребовалось внести.

Конфигурация фильтра

Мне потребовалось руками указать домен noteskeeper.ru, так как скрипт фильтра не мог его правильно определить. Подозреваю, что это последствия какой-то ошибки конфигурирования системы. Пока я остановился на этом варианте.

Ещё я указал метод генерации подписи simple вместо nofws. Если я правильно понял, то это только влияет на то, как будет преобразован текст письма с заголовками прежде, чем будет вычислена сигнатура.

DNS-запись

В инструкции указано, что открытый ключ домена нужно вводить в формате

selector1._domainkey IN TXT "k=rsa; p=MHwwDQYJK ... OprwIDAQAB; t=y"

Из RFC 4870 я узнал, что вместо селектора selector1 может быть любая строка. Главное, чтобы такой же селектор был указан в конфигурации dkfilter.

Потом выяснилось, что тег t=y обозначает режим тестирования. Когда тестирование будет закончено, этот тег стоит убрать из записи.

sendmail

Чтобы посылать тестовые сообщения я использовал sendmail. Они, к сожалению, шли в обход фильтра. В FAQ приведены настройки, которые нужно добавить в конфигурацию postfix.

Валидируем подпись домена

Гугл доверяет почте, отправленной с хоста noteskeeper.ru

Received-SPF: pass (google.com: domain of mista_k@noteskeeper.ru designates 46.254.17.128 as permitted sender) client-ip=46.254.17.128;
DomainKey-Status: good
Authentication-Results: mx.google.com; spf=pass (google.com: domain of mista_k@noteskeeper.ru designates 46.254.17.128 as permitted sender) smtp.mail=mista_k@noteskeeper.ru; domainkeys=pass header.From=mista_k@noteskeeper.ru
Received: from noteskeeper.localdomain (localhost.localdomain [127.0.0.1])
    by noteskeeper.localdomain (Postfix) with ESMTP id 997CD2A78003
    for <mistakster@gmail.com>; Mon,  9 Apr 2012 12:57:55 +0400 (MSK)
DomainKey-Signature: a=rsa-sha1; h=Received:To:Subject:Message-Id:Date:From
    b=dQHTHUU8sQCij/EDk+sv5aR8SJRuI51BBgM7LCxfihd1xNm33zUbvGo6/Csk
    spYLkwaAGGINjETWGwe0qaCZJ7AEkyZYbmNcLG2xewRGZCXyIjiygZIVyqqE
    L63lhDnwEzkG5aYyxPOQciVwmWuBExBTwNFKX0Q7p8s4eWUmyIM=;
    c=simple; d=noteskeeper.ru; q=dns; s=email

Подпись успешно проверена.