DKIM на примере mta exim4

DKIM


Многие уже знакомы с dkim, но как показывает статистика, пока что мало кто использует этот механизм.
Кратко: Вместо традиционного IP-адреса, для определения отправителя сообщения DKIM добавляет в него цифровую подпись, связанную с именем домена организации. Подпись автоматически проверяется на стороне получателя, после чего, для определения репутации отправителя.
На данный момент DKIM уже используют большинство крупных mail-сервисов, такие как Gmail, Яндекс, Yahoo и не только. В данном топике я хотел бы поделится собственным опытом внедрения DKIM.

Подготовка


Нам понадобится TXT запись вида default._domainkey.domain в которой будет содержатся public key, который будет использоваться для проверки подписи в письме. Сгенерировать ключи довольно просто. Для этого можно установить dkim-milter и выполнить:
$ dkim-genkey -d domain -t -r

который сгенерирует два файла (ключ -t для тествого режима):
  • default.txt — public key для TXT записи
  • default.private — private key, которым будет пользоваться mta для подписывания сообщений.

Если хочется самому управлять процессом генерации, можно сделать это вручную c помощью openssl
$ openssl genrsa -out domain-dkim.pem 768
$ openssl rsa -in domain-dkim.pem -out domain-public.pem -pubout -outform PEM

После создания TXT записи можно приступать к настройке MTA.

EXIM


DKIM поддерживается exim4 начиная с версии 4.70, которую в Debian например можно установить из backports. В конфигурации должны отразится два аспекта:
  1. проверка DKIM подписей входящих писем
  2. подписывание исходящих писем

Для первого понадобится включить соответствующий acl
acl_smtp_dkim = acl_smtp_dkim
Этот acl будет вызываться для каждой DKIM подписи в письме после приема тела письма (ведь DKIM хранится в headers).
Пример acl_smtp_dkim (поскольку я сам пока что только обкатываю DKIM применяю warn вместо deny):
acl_smtp_dkim:

warn dkim_status = fail
logwrite = DKIM test failed: $dkim_verify_reason
add_header = X-DKIM-FAIL: DKIM test failed: (address=$sender_address domain=$dkim_cur_signer), signature is bad.

warn dkim_status = invalid
add_header = :at_start:Authentication-Results: $dkim_cur_signer ($dkim_verify_status); $dkim_verify_reason
logwrite = DKIM test passed (address=$sender_address domain=$dkim_cur_signer), but signature is invalid.

accept dkim_status = pass
add_header = :at_start:Authentication-Results: dkim=$dkim_verify_status, header.i=@$dkim_cur_signer
logwrite = DKIM test passed (address=$sender_address domain=$dkim_cur_signer), good signature.

accept

Так же зарянее зная что письма от PayPal или GMail обязательно будут иметь DKIM подпись можно сделать deny правило для списка доменов с условием dkim_status = !pass. Либо можно метить тэгом SPAM.

2) Для подписывания сообщений достаточно добавить переменные:
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_FILE = /etc/exim4/${lc:${domain:$h_from:}}-dkim.pem
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}


и не забывать добавить в smtp транспорт:
dkim_domain = DKIM_DOMAIN
dkim_selector = default
dkim_private_key = DKIM_PRIVATE_KEY


таким образом при отправке сообщения, из headers будет выниматься домен отправителя, и, в случае если по пути /etc/exim4/domain-dkim.pem будет находится private key (не забудьте про доступ на чтение пользователя exim), письмо будет подписано. Такая конфигурация замечательно работает и на MTA, обслуживающих множество доменов.

Тестирование


Протестировать довольно просто — есть несколько тестовых адресов, на которые можно выслать письмо для проверки. Самое элементарное — отправить письмо на Gmail — в подробных сведениях о письме будет информация о подписи, так же можно заглянуть в тело письма и увидеть DKIM подпись и ее статуст проверки.

Инфо


DKIM in wikipedia
DKIM docs
Exim4: Support for DKIM
Tags:
dkim, exim, spam

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.