Инженер-программист
0,0
рейтинг
21 сентября 2012 в 06:24

Администрирование → OpenDKIM + Postfix = просто



В конце 2011 года разработчики проекта dkim-milter прекратили его поддержку и разработку. К счастью, на замену проекта dkim-milter пришел OpenDKIM, с помощью которого добавить DKIM-подпись в письма так же просто.

tl;dr: в наше время без DKIM-подписей ну никак нельзя
DKIM-подпись — это цифровая подпись, которая добавляется к заголовкам письма сервером отправителя, по которой сервер получателя может удостовериться, что отправитель письма соответствует полю From в заголовках письма. Если сервер получателя проверяет эту подпись, то по результатам проверки сервер может принять решение о том, как поступать с письмом: принять, отправлять в папку «Спам», отправить на дополнительную проверку или вовсе отказаться от приёма. Подписи DKIM проверяют и используют сами все ведущие почтовые службы, включая Яндекс и Mail.ru. Последняя открыто требует чтобы письма были подписаны с помощью DKIM.



Инструкция по настройке связки Postfix и OpenDKIM


Для этого нам потребуется сам Postfix и пакеты OpenDKIM. Установим все необходимые компоненты с помощью вашего пакетного менеджера:

aptitude install opendkim opendkim-tools

Теперь нам нужно получить ключи, которые мы будем использовать для подписи писем.

Ключи для подписи


Получим ключ для домена сервера и для селектора, равного имени сервера без домена, чтобы ничего не придумывать:

mkdir /etc/opendkim/
opendkim-genkey -D /etc/opendkim/ -d $(hostname -d) -s $(hostname)

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

Файлам ключей обязательно нужно дать доступ на чтение для группы, в которой работает OpenDKIM, а сам postfix добавить в ту же группу, чтобы тот мог подписывать письма подключаясь к демону OpenDKIM через его сокет:

chgrp opendkim /etc/opendkim/*
chmod g+r /etc/opendkim/*
gpasswd -a postfix opendkim


Где искать ключи?


В конфиг /etc/opendkim.conf допишем наши настройки:

tee -a /etc/opendkim.conf  <<EOF
Canonicalization relaxed/relaxed
SyslogSuccess yes
KeyTable file:/etc/opendkim/keytable
SigningTable file:/etc/opendkim/signingtable
X-Header yes
# на время отладки включим расширенное логгирование:
LogWhy yes
# если вы подписываете и на других серверах:
#ExternalIgnoreList file:/etc/opendkim/trusted
# список внутренних хостов, почта которых требует подписи:
#InternalHosts file:/etc/opendkim/internal
EOF

Подробное описание всех директив ищите в документации.

Какими ключами подписывать?


Список имеющихся ключей укажем в файле /etc/opendkim/keytable в формате "название домен:селектор:/путь/до/ключа". Если вы создавали ключи командой выше, то прописать ключ согласно FQDN сервера в этом файле можно так:

echo $(hostname -f | sed s/\\./._domainkey./) $(hostname -d):$(hostname):$(ls /etc/opendkim/*.private) | tee -a /etc/opendkim/keytable

Для mail.example.com в файле будет такая строчка:

mail._domainkey.example.com example.com:mail:/etc/opendkim/mail.private

Ключей в этом файле может быть сколько угодно, для какого угодно числа доменов. Также ключи могут храниться в БД — подробней в документации.

Чью почту подписывать?


Теперь объясним OpenDKIM почту каких доменов какими ключами подписывать в файле /etc/opendkim/signingtable в формате "домен название-ключа":

echo $(hostname -d) $(hostname -f | sed s/\\./._domainkey./) | tee -a /etc/opendkim/signingtable

Для хоста mail.example.com в файле будет example.com mail._domainkey.example.com. Если хочется подписывать вообще всю исходящую почту то можно указать * вместо домена.

В других файлах, указанных в директивах ExternalIgnoreList и InternalHosts, содержится просто список хостов и/или IP-адресов каждый на новой строке, подписи писем для которых будут либо проигнорированы, либо добавлены. Если за почту у вас отвечает единственный сервер, то с ними ничего не нужно делать.

Настроим Postfix


Наконец, попросим Postfix отправлять все письма на подпись:

postconf -e milter_default_action=accept
postconf -e milter_protocol=2
postconf -e smtpd_milters=unix:/var/run/opendkim/opendkim.sock
postconf -e non_smtpd_milters=unix:/var/run/opendkim/opendkim.sock


Если Postfix в chroot...


Если Postfix вы используете без chroot, то для настройки больше ничего не нужно делать. Иначе, что скорее всего, нужно объяснить OpenDKIM где ему следует создавать сокет и дать для всего подходящие права:

echo 'SOCKET="local:/var/spool/postfix/var/run/opendkim/opendkim.sock"' | tee -a /etc/default/opendkim
mkdir -p /var/spool/postfix/var/run/opendkim
chown opendkim:opendkim /var/spool/postfix/var/run/opendkim


Готово!


Перезапускаем Postfix и OpenDKIM штатными средствами, отправляем тестовое письмо куда-нибудь на Яндекс, и наслаждаемся успешным результатом проверки подписи:



Не забываем добавить TXT запись и проверить, что она на месте:

dig txt mail._domainkey.example.com


Ещё один способ проверить корректность подписи: отправить письмо на check-auth@verifier.port25.com.

Запретим письма без подписи


Если проверка прошла успешно, то стоит формально запретить другим серверам принимать письма с вашим доменом, но без подписи, добавив ADSP запись:

_adsp._domainkey IN TXT "dkim=all"


Конец


Дочитали до конца, но хотите большего? Гораздо более короткая инструкция по настройке OpenDKIM при условии одного домена и корректно настроенного hostname.
Алексей @alexkbs
карма
81,0
рейтинг 0,0
Инженер-программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

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

  • +1
    Не помешала бы пара абзацев о том, что такое DKIM и зачем он нужен. :)
    • +3
      Тема целей и значения DKIM неоднократно раскрыта здесь на хабре, да и даже если бы не была — найти одноименную статью в Википедии никакого труда не составляет. Если же для вас это проблема, то моя статья не для вас.
      • +9
        Перед тем как написать коммент, я сделал аналогичный комикс, и обзорной статьи не нашел. Только решения конкретных задач.

        Понимаете, когда посетитель Харба бежит глазами по списку статей, его мозг для каждой статьи отвечает на вопрос «Оно мне нужно?» Если ответ отрицательный, посетитель переходит к следующей статье. Если положительный, то открывает ее в новой вкладке.

        Вам ничего не стоит написать в самом начале статьи что-то вроде:
        DKIM — технология, позволяющая привязывать отправляемые сообщения к доменному имени при помощи цифровой подписи. Почтовые сервера вроде того же GMail относятся к таким письмам с бóльшим доверием и с меньшей вероятностью посчитает их спамом.

        И тысячам посетителей Хабра не придется играть в квест «разберись, о чем все-таки эта статья».
        • –3
          В прошлом комментарии я дал ссылку более чем обзорную статью по обсуждаемому вопросу. Любой из тысяч пользователей Хабра может найти эту статью в первых строках ответа в Google по запросу «DKIM». То, что вы не нашли её сами, и что не увидели в прошлом моём комментарии ссылку на эту статью, удивляет меня непрерывно.
          • +12
            План действий для человека, не знакомого с сабжем, по вашему предложению:
            1) Пробежать глазами тизер статьи и не понять, о чем статья.
            2) Открыть полный текст статьи, пробежать глазами и не найти ответа.
            3) Сделать поиск по Хабру.
            4) Пролистать пару десятков результатов, открыть полный текст нескольких из них, не найти внятного ответа ни в одной.
            5) Плюнуть на это дело, сделать поиск в Гугле/Википедии, прочитать (весьма мудрёный) ответ там.

            План по моему предложению:
            1) Пробежать глазами тизер статьи и сразу понять, о чем она.

            И все благодаря двум вводным предложениям в самом начале статьи. Меня «непрерывно удивляет», что вы отрицаете их очевидную полезность.

            PS Сама статья замечательная. Добавил в закладки, плюсанул в статью и в карму. Большое спасибо за ваш труд.
            • 0
              ИМХО тем, кто не знает, что такое DKIM, оно и не нужно.
              • +4
                Хех, вы оптимист. Сейчас область IT настолько разрослась, что один специалист, насколько бы крут он не был, чисто физически не в состоянии знать все. Даже по верхам. И есть много вещей, которые нужны — но о которых мало кто знает.
  • +2
    При наличии связки Postfix+Amavis смысла в дополнительном пакете нет. достаточно в amavis добавить
    $enable_dkim_verification = 1;
    $enable_dkim_signing = 1;
    dkim_key('domen.ru', 'key1', '/var/db/dkim/domen.ru.key.pem');
    @dkim_signature_options_bysender_maps = (
    { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } );
    $interface_policy{'10024'} = 'DKIM_ALWAYS';
    $policy_bank{'DKIM_ALWAYS'} = { originating => 1, };
    
    • 0
      У SpamAssassin тоже есть модуль для проверки и проставления подписи, но статья не об этом.
      • 0
        Так я про то, что последнее время нам все меньше попадают сервера без SpamAssasin или Amavis.
        • +1
          Рекомендую написать вам статью о настройке DKIM на сервервах с Amavis или SpamAssassin. От этого будет гораздо больше пользы чем наше с вами тут обсуждение у статьи на совершенно другую конкретную тему.
          • 0
            О, я скоро у себя «довнедрю» эту связку, и постараюсь написать :) Там правда без SpamAssassin.
    • 0
      Да, хорошая тема с Amavis. правда я не нашел как разными ключами с разных шлюзов подписывать. Пока только разные пути (порты) для разных шлюзов задаю.
  • 0
    Не советую запрещать принятие почты без подписи dkim, по крайней мере на первое время после настройки dkim подписи.

    А теперь собсвтенно почему:
    Я тоже когда-то настроил себе на сервере dkim чрез dkim-milter (dkim-filter) для postfix. Проверил — все работает, gmail в заголовках показывает dkim=pass. Радости было много, но как выяснилось не надолго.

    Через время (месяц) обнаруживаю, что некоторые письма не проходят проверку dkim и в заголовках того же gmail красуется
    dkim=neutral (body hash did not verify)

    Это значит что хеш подписи не сходится с текушим хешем тела письма. Эта ситуаци происходит когда, что-то изменило тело письма после совершения подписи по dkim. В моем случае после фильтра dkim-milter, что-то меняло тело письма.

    Ситуаций, когда что-то меняет тело может быть много, в инете достаточно много такий кейсов когда «избранные» письма не проходят dkim проверку.
    Мой же случай оказался в том, что тело некоторых писем состовлялось из файлов, которые были с EOL (End Of Line) в формате windows, т.е. \r\n и по всей видимости постфикс после дким фильтра менял формат EOL на Unix, т.е. — \n
    • 0
      ¯_(ツ)_/¯ С равнозначной вероятностью это может быть \r\n, а может и man-in-middle.
      • 0
        Сейчас уже даже гугл предупреждает всех если письмо было доставлено по незащищенному каналу (красный значек), настраивайте tls и mim уже вас не коснется, по крайней мере для писем который вы отсылаете.
  • +1
    Есть довольно средненькая по объхему рассылочка со своего сервера(Postfix,DKIM.SPF,PTR).
    И все бы хорошо, но яндекс через раз признает DKIM валидным.
    Что только не делал. В итоге написал в саппорт и онеи признали проблему на свой стороне.
    Так что если у кого Яндекс чудит — не удивляйтесь.
  • –1
    А еще в компаниях используются Exchange, Zimbra, exim, sendmail, postfix и свои центры выдачи эцп для писем.
    И как мне, имея корпоративный exchange и аутлук/OWA/the bat/thunderbird/kmail проверить это Ваше непонятно кем и как подписанное письмо?
    • +1
      DKIM не используется в качестве ЭЦП писем и не предназначен для этого, потому описанная вами проблема к письмам, подписанным DKIM, не относится. Кстати говоря, GMail и Mail.ru подписывают все исходящие письма с помощью DKIM.
  • +1
    Небольшая поправка, правда не знаю для всех ли дистрибутивов актуально, пробовал на Debian 6.
    По дефолту opendkim слушает на сокете, а не на 8891

    Посему, чтобы заставить его сулшать порт, необходимо в файл
    /etc/default/opendkim
    добавить строки
    SOCKET=«inet:8891@localhost»
    • 0
      Конечно, упоминание aptitude и тег "debian" прямо говорят, что инструкция для Debian-подобных ОС, но эта информация для обладателей CentOS 6: по дефолту OpenDKIM как раз слушает указанный порт, а не указанный в статье сокет.
      • 0
        В статье OpenDKIM слушает сокет потому что его явно об этом попросили. Сокет кошерней как-то.
        • 0
          В статье OpenDKIM просят явно слушать сокет только в случае запуска в chroot. "… Если Postfix вы используете без chroot, то для настройки больше ничего не нужно делать..." А насчёт "кошерности" согласен, именно поэтому сам настроил через сокет.
  • 0
    Скажите а для чего нужна эта запись «dig txt mail._domainkey.example.com» в DNS, Посмотрел несколько статей по теме, только в вашей ее встречаю. Что она делает не могли бы пояснить?
    • 0
      Вопрос отпал, глупость сморозил-с. :)
  • 0
    В моём случае ещё пришлось сделать такую правку, чтобы всё заработало:

    chown opendkim:opendkim /etc/opendkim/mail.private
    chmod 0400 /etc/opendkim/mail.private

    Для приватного ключа ужесточаем права, на то он и приватный, чтобы его не могли использовать посторонние
    • 0
      Это в новой версии появилось. Спасибо что напомнили, дополню инструкцию.
      • 0
        Раз такое дело, тогда обновить немного раздел «Если Postfix в chroot...»
        У меня входящая почта начала проверятся на DKIM только с настройкой:
        postconf -e smtpd_milters=unix:/var/spool/postfix/var/run/opendkim/opendkim.sock

        non_smtpd_milters оставляем без изменений, исходящая почта подписывается

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.