Подключение DKIM к Postfix
DomainKeys Identified Mail (DKIM) — метод E-mail аутентификации, разработанный для обнаружения подделывания сообщений, пересылаемых по email. Метод дает возможность получателю проверить, что письмо действительно было отправлено с заявленного домена. DKIM упрощает борьбу с поддельными адресами отправителей, которые часто используются в фишинговых письмах и в почтовом спаме.
Установка OpenDKIM
Обновляем список пакетов сервера:
sudo apt update
Обновляем пакеты сервера:
sudo apt upgrade
Установите OpenDKIM и его зависимости:
sudo apt-get install opendkim opendkim-tools
Управление OpenDKIM
Запустить службу OpenDKIM:
sudo systemctl start opendkim
Остановить службу OpenDKIM:
sudo systemctl stop opendkim
Перезапустить службу OpenDKIM:
sudo systemctl restart opendkim
Статус службу OpenDKIM:
sudo systemctl status opendkim
Настройки OpenDKIM
Изменим файл конфигурации добавив строки ниже в конец файла:
sudo nano /etc/opendkim.conf
# автоматический перезапуск при ошибках
AutoRestart Yes
# максимальная скорость перезапуска, если перезапуски начинают происходить быстрее, чем эта скорость, OpenDKIM прекращает работу. 10/1h - разрешено не более 10 перезапусков в час
AutoRestartRate 10/1h
# дает все права доступа группе пользователей, определенной UserID и позволяет другим пользователям читать и выполнять файлы, в этом случае это позволит создавать и изменять файл PID
UMask 002
# параметр включает подробное ведение журнала с помощью вызовов syslog
Syslog yes
# параметр включает подробное ведение журнала с помощью вызовов syslog
SyslogSuccess Yes
LogWhy Yes
# определяет методы канонизации, используемые при подписании сообщения, этот simple метод практически не допускает изменений, в то время как relaxed допускает незначительные изменения, такие как замена пробелов
Canonicalization relaxed/simple
# указывает внешние хосты, которые могут отправлять почту через сервер в качестве одного из подписывающих доменов без учетных данных
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
# определяет список внутренних хостов, чья почта не должна проверяться, а вместо этого должна быть подписана
InternalHosts refile:/etc/opendkim/TrustedHosts
# сопоставляет имена ключей с ключами подписи
KeyTable refile:/etc/opendkim/KeyTable
# список подписей, применяемых к сообщению, на основе адреса, найденного в From:header заголовка
SigningTable refile:/etc/opendkim/SigningTable
# объявляет режимы работы, в этом случае OpenDKIM выступает в роли подписывающего (s) и верификатора (v)
Mode sv
# путь к файлу Pid, который содержит идентификационный номер процесса
PidFile /var/run/opendkim/opendkim.pid
# выбирает алгоритм подписи, который будет использоваться при создании подписей
SignatureAlgorithm rsa-sha256
# процессOpenDKIM запускается под этим пользователем и группой
UserID opendkim:opendkim
# OpenDKIM будет прослушивать указанный здесь сокет, Posfix будет отправлять сообщения в OpenDKIM для подписи и проверки через этот сокет
Socket inet:12301@localhost
При желании вы можете выбрать собственный номер порта для файла Socket. Эта конфигурация позволяет подписывать сообщения для одного или нескольких доменов. Чтобы узнать о других параметрах, перейдите сюда.
Подключаем OpenDKIM к Postfix, открываем конфигурационный файл OpenDKIM:
sudo nano /etc/default/opendkim
Добавляем сокет:
SOCKET="inet:12301@localhost"
Настройки PostFix для использования OpenDKIM, открываем конфигурационный файл PostFix:
sudo nano /etc/postfix/main.cf
Добавляем параметры:
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301
Создаем структуру для доверенных хостов:
sudo mkdir /etc/opendkim
Создаем структуру для ключей:
sudo mkdir /etc/opendkim/keys
sudo mkdir /etc/opendkim/keys/название_домена.com
Файл подключается в opendkim.conf
переменными ExternalIgnoreList
и InternalHostsсообщения
, исходящие письма с этих доменов и IP-адресов, будут доверенными и подписанными. Указываем доверенные хосты:
sudo nano /etc/opendkim/TrustedHosts
Добавьте следующие строки во вновь созданный файл, подставив только свой домен:
127.0.0.1
localhost
192.168.0.1/24
*.название_домена.com
Файл TrustedHosts
определяет список внутренних InternalHosts
и внешних ExternalIgnoreList
хостов, с которых всю почту надо подписывать, а не проверять.Поскольку в нашем основном файле конфигурации TrustedHosts
используются регулярные выражения *.название_домена.com
, сообщения поступающие с поддоменов название_домена.com
, также будут доверенными.
Создаем таблицу ключей:
sudo nano /etc/opendkim/KeyTable
Таблица ключей содержит селектор — домен — закрытый ключ
, в качестве селектора можно использовать любую буквенно-цифровую строку, в данном примере используется mail:
mail._domainkey.название_домена.com название_домена.com:mail:/etc/opendkim/keys/название_домена.com/mail.private
Создайте таблицу подписи:
sudo nano /etc/opendkim/SigningTable
В файле задается соответствия отправителей и селектора:
*@название_домена.com mail._domainkey.название_домена.com
Генерация ключей
Переходим в каталог ключей:
cd /etc/opendkim/keys/название_домена.com
Генерируем ключи:
sudo opendkim-genkey -s mail -d название_домена.com
-s
указывает селектор и -d
домен, эта команда создаст два файла, mail.private
является акрытым ключом и mail.txt
содержит открытый ключ.
Изменим владельца закрытого ключа:
sudo chown opendkim:opendkim mail.private
Перезапустите Postfix:
sudo systemctl restart postfix
Перезапустите OpenDKIM:
sudo systemctl restart opendkim
Базовые понятия DKIM
В основе DKIM лежит ассиметричный алгоритм шифрования RSA 2. Сообщения подписываются закрытым ключом, который хранится у отправляющего (подписывающего) сервера, а открытый публикуется в TXT-записи на серверах DNS. Для извлечения открытого ключа из публичной записи необходимо «собрать» доменное имя. Оно состоит из вашего домена, обязательной части технологии DKIM — _domainkey — и имени селектора
Как только доменное имя получено, извлекается TXT-запись, запись содержит не только саму подпись, но и несколько пар ключ=значение, которые используются как инструкции для проверки. Вот что они означают:
v=
версия DKIM. Всегда имеет значение 1a=
алгоритм, используемый для генерации подписиc=
тип канонизации заголовка/тела сообщения. Перед подписью сообщение необходимо привести его к стандартному (канонизированному), чтобы не возникло проблем при проверке на принимающей стороне, ведь промежуточные серверы могут незначительно модифицировать сообщение. Это достаточно важный параметр, стоит обратить на него особое вниманиеd=
домен, который будет просматриваться на предмет наличия публичного ключаs=
селектор. Позволяет взять публичный ключ из нужной TXT-записи, если их вдруг несколько (а такое вполне может быть, если подписывающих серверов больше одного)t=
отметка времени создания подписиbh=
хэш канонизированного тела сообщенияh=
подписанные поля заголовков (список заголовков может варьироваться. Наличие тех или иных заголовков в подписи может защитить вас от некоторых потенциальных уязвимостей DKIM)b=
собственно, сама подпись
Можно использовать онлайн инструмент для поиска и проверки записи DKIM TXT и определения длины открытого ключа
Проверка
Для проверки, напишем и отправим письмо, проверим логи и заголовки письма. Логи находятся в файле /var/log/mail.log
а ошибки в /var/log/mail.err
.
В логах ищем строку DKIM—Signature field added
, это значит, что письмо отправленно подписаное:
Проверяем заголовки в пришедшем письме:
Директива dkim=pass
говорит о том что письмо прошло проверку:
Директива dkim=neutral
говорит о том что письмо не прошло проверку:
Добавление открытого ключа в записи DNS домена
Смотрим ключ:
sudo nano /etc/opendkim/keys/название_домена.com/mail.txt
Скопируйте ключ и добавьте запись TXT в DNS вашего домена:
Name: mail._domainkey.название_домена.com.
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAobBk3ZbSt0XZiO0qcNsxrSR8lxehCqm6a0NMyk4FULgiD5dwMGBC9TwF7eqxyUICfjHqAsITwZvRDVUXaJkCJ1eRzsYzKJSM/6lo7tZC+XF62z+lMANLb/2LKOTkBsnjFdZC2yT3XkzUnBQYx54VmGkWmvsjWVMHYUFEtlgSxufIjmfBtpNzowD0PjiENSuFWE3r/4n1ncZFwqTGvJ8Ev9kTC89jvIgEGWI0I0uZOR16V4qrnY5UUoieD5p58qN+iO5sx/BVi0lUBv8b+R3qTvhYKqSV/85776SBs3w4A3ofcMNMmTTj/rpZ6gwNCnroNpD7Nv9NqkA2R4O952FP5wIDAQAB