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. В конфигурации должны отразится два аспекта:
- проверка DKIM подписей входящих писем
- подписывание исходящих писем
Для первого понадобится включить соответствующий 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