Страница 1 из 3

HOWTO: Exim & DKIM

Добавлено: 2009-11-26 21:07:03
Laa
Привет.
Поднял у себя и решил поделиться опытом с массами. ;-)
Есть такая технология, как DKIM (DomainKeys Identified Mail), позволяет письма подписывать ключами. Сервер получателя письма в ДНС берет информацию о ключе и сам ключ. После сверки информации из ДНС с заголовками письма, которое пытается поступить, можно судить об отправителе -- доверять ему или нет. Спамеру практически не реально подобрать ключ для отправки на чужой сервер спама. Однако, спамеру гораздо более реальней проломить клиентский компьютер, который имеет доступ к почтовому серверу, использующему для отправки DKIM, и через этот сервер разослать спам. Спам и доставлен будет и подписан. :Yahoo!:

На сегодняшний день этот метод больше используется бесплатными почтовыми службами или крупными почтовыми серверами, которые частенько подставляют спамеры. Я не уверен вообще, что это кто-то будет использовать, но мало-ли, а вдруг? :-D У себя я еще не собрал достаточно статистики для понимания стоит ли использовать DKIM для анализа спама или не стоит. Через недельку-две думаю соберу статистику.

Но как самому подписывать свою почту при помощи DKIM я тут на примере freebsd 7.2 и exim расскажу.

Итак, я использую на сегодняшний день exim 4.70. (Уже есть 4.71, в котором подправлен небольшой баг в реализации DKIM). В более ранних версиях поддержка DKIM реализовывалась при помощи сторонних методов, а с этой версии DKIM поддерживается самим exim-ом.

Первым делом создаем ключ:

Код: Выделить всё

20:18:45 root@m $ openssl genrsa -out /usr/local/etc/exim/dkim/domain.org.key 1024
Generating RSA private key, 1024 bit long modulus
...++++++
.....................................................................++++++
e is 65537 (0x10001)
20:41:18 root@m $
Желательно, чтобы меньше глаз ключ видело и тем более меньше рук могли этот ключ изменить:

Код: Выделить всё

chown mailnull:wheel /usr/local/etc/exim/dkim/
chmod u=rx,go= /usr/local/etc/exim/dkim/
Теперь создаем публичный ключ, который будет предоставляться всем желающим для проверки исходящих писем (в дальнейшем этот ключ будет в ДНС записи TXT):

Код: Выделить всё

20:47:03 root@m $ openssl rsa -in /usr/local/etc/exim/dkim/domain.org.key -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYw9Ddhod6jZZkp0S0lf4I/j57
G8DnW5HDoKHDr0OwmbOhg0QOefHIpfrhBCrTK08dAvvvFnXs5/g1i9YU2ZDHE1uB
pSrtm33ZBAC9tUneqTM6J4PYAHKs1hOchoOZCYJBdZiNBFUtxT9Ma2Gldkgy5lhX
ZkS3pbIpEHYvI3PbewIDAQAB
-----END PUBLIC KEY-----
20:47:07 root@m $
Копируем ключ и вставляем в ДНС зоне нашего домена domain.org в поле:

Код: Выделить всё

...
dkim._domainkey         TXT     "k=rsa; p=MIGfMA0GCSqGSIb3D.........;"
....
Внимание: ключ должен располагаться одной строкой, без переносов и пробелов. Обновляем serial в зоне и обновляем зону. Проверяем, что получилось:

Код: Выделить всё

20:51:30 root@m $ host -t txt dkim._domainkey.domain.org.
Trying "dkim._domainkey.domain.org"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37561
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;dkim._domainkey.domain.org.  IN      TXT

;; ANSWER SECTION:
dkim._domainkey.domain.org. 86400 IN  TXT     "k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBi.....\;"
Ok! Все хорошо. В ДНС все получилось.
Первое слово, до _domainkey в ДНС-записи -- это будет наш dkim-selector. Его можно любой заюзать и пользоваться для разных случаев разными селекторами и тем самым юзать кучу ключей. Не знаю зачем это может понадобиться, но мало ли.

Теперь перейдем к настройке exim! В configure указываем следующее:

Код: Выделить всё

...
## DKIM:
DKIM_DOMAIN                     = ${lc:${domain:$h_from:}}
DKIM_FILE                       = /usr/local/etc/exim/dkim/${lc:${domain:$h_from:}}.key
DKIM_PRIVATE_KEY                = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
...
## чуть правим транспорт:
remote_smtp:
  driver                = smtp
  dkim_domain           = DKIM_DOMAIN
  dkim_selector         = dkim
  dkim_private_key      = DKIM_PRIVATE_KEY
...
Таким образом, при отправке письма, из адреса отправителя $h_from будет выкусываться домен. Скажем domain.org, В случае отсутствия ключа, для этого домена, значение переменной ключа будет равно нулю, то есть письмо не будет подписываться.

Перечитываем конфиг exim:

Код: Выделить всё

20:57:16 root@m $ /usr/local/etc/rc.d/exim reload
И отправляем тестовое письмо так, чтобы оно уходило при помощи транспорта remote_smtp (то есть на внешний адресок какой-то).
Заглядываем в заголовки этого письма и радуемся -- DKIM работает!!! :Yahoo!:

Код: Выделить всё

...
Received-SPF: pass (google.com: domain of laa@domain.org designates 194.z.y.x as permitted sender) client-ip=194.z.y.x;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of laa@domain.org designates 194.z.y.x as permitted sender) smtp.mail=laa@domain.org;
+dkim=pass header.i=@domain.org
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=domain.org; s=dkim;
        h=Content-Transfer-Encoding:Content-Type:MIME-Version:Date:Subject:To:From:Message-ID; bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=bfxwjczWz5OFi4LMTs4qpcOcl5p3RhKeC4iZp9KvOb6iI66ZxDSdYZSezJ5n3rdCHeQeTabF8NCTgUB65............YOlII=;
Received: from [89.x.x.x] (port=17497 helo=toshiba)
        by m.domain.org with esmtpa (Exim)
        (envelope-from <laa@domain.org>)
        id 1NDiOF-000ELJ-JT
        for domain.org.user-test@gmail.com; Thu, 26 Nov 2009 20:44:25 +0300
...
Ну вот и все. Может кому и пригодится. :Search:


Дальше хочу проверять входящую почту по этой технологии, постараюсь сообщить тут о результатах, возможно оно все будет бестолку.

p.s. ключ покусал для лучшего восприятия, длинные строки хуже читаются. :oops:

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-26 22:59:14
neyro
Спасибо за отличный мануал! Ждем дополнения с проверкой DKIM при получении письма.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-27 11:16:10
Morty
может стоит перенести эту хаутушку в полезные скрпиты/настройки для Exim ?

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-27 11:29:03
Laa
Хорошая идея :good: , только давайте тут ее обсудим, может я чего криво тут сделал, может что-то можно лучше сделать и через недельку перетащу туда.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-27 14:45:24
Morty
нада чтобы все себе DKIM ставили тогда будет толк
поэтому нада в заметки вынести :smile:

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-28 19:08:12
Alex Keda

Код: Выделить всё

hosting# grep TXT /etc/namedb/master/lissyara.su.db
lissyara.su.    14400   IN      TXT     "v=spf1 a mx ip4:77.221.149.162 ?all"
hosting#    
и как быть?
либо/либо?
тогда ф топку начинание - SPF уже достаточно популярен.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-11-28 20:35:31
neyro
А в чем собственно проблема ? Запись DKIM создается с префиксом, поэтому и SPF и DKIM работают вместе.
dkim._domainkey.lissyara.su. 14400 IN TXT "....."
SPF uses "example.com" TXT records, and now special SPF type records
(type 99) that not many people supprt.
DKIM uses "_policy._domainkey.example.com" TXT records and
"selector._domainkey.example.com" TXT records.

Different places means that they can both exist in the zone at the same
time, thus no problems.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-01 18:13:39
SergeySL

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-01 18:48:02
Laa
SergeySL писал(а):Чуть раньше тоже самое для Postfix и Amavisd-New :smile:
Тоже стоит тут сохранить. :good:
Размести в этой ветке. Я ее закреплю сверху на некоторое время.
Кстати, я когда искал информацию для exim, сталкивался с подобной докой, только на английском, похоже ты переводил готовое? ;-) Но тем не менее -- работа проделана большая. :good:

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-01 19:01:15
SergeySL
Естественно, по докам разработчиков.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-03 20:19:06
gmn
Всем привет.
Обновил Exim до 4.71 и снова начал экспериментировать в проверкой входящих на DKIM.

Код: Выделить всё

acl_smtp_dkim = check_dkim

check_dkim:
warn logwrite = test1: gmail dkim pass
    sender_domains = gmail.com
    dkim_signers = gmail.com
    dkim_status = pass

warn logwrite = test2: gmail dkim fail
    sender_domains = gmail.com
    dkim_signers = gmail.com
    dkim_status = fail

warn logwrite = test3: gmail dkim none
    sender_domains = gmail.com
    dkim_signers = gmail.com
    dkim_status = none

accept
Взят пример из документации ...

И что я вижу в логе:

Код: Выделить всё

2009-12-03 19:09:20 1NGFB9-0003QN-QB test1: gmail dkim pass
2009-12-03 19:09:20 1NGFB9-0003QN-QB test2: gmail dkim fail
2009-12-03 19:09:20 1NGFB9-0003QN-QB test3: gmail dkim none
Одно и то же письмо одновременно и pass, и fail, и none ?!
Хотя, скорее всего, "pass".

Код: Выделить всё

2009-12-03 19:09:20 1NGFB9-0003QN-QB DKIM: d=gmail.com s=gamma c=relaxed/relaxed a=rsa-sha256 [verification succeeded]
2009-12-03 19:09:20 1NGFB9-0003QN-QB <= ***@gmail.com H=mail-bw0-f216.google.com [209.85.218.216] P=esmtp ...
Или ошибка в написании условий? Но они взяты из spec.txt ...
http://www.exim.org/exim-html-current/d ... /ch54.html
dkim_signers

ACL condition that checks a colon-separated list of domains or identities for a match against the domain or identity that the ACL is currently verifying (reflected by $dkim_cur_signer). This is typically used to restrict an ACL verb to a group of domains or identities, like:

# Warn when message apparently from GMail has no signature at all
warn log_message = GMail sender without DKIM signature
sender_domains = gmail.com
dkim_signers = gmail.com
dkim_status = none

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-04 11:16:26
neyro
???? Бред какой то :smile:
Вы же сами написали 3 условия..все правильно работает.
dkim_status = pass
dkim_status = fail
dkim_status = none

2009-12-03 19:09:20 1NGFB9-0003QN-QB test1: gmail dkim pass
2009-12-03 19:09:20 1NGFB9-0003QN-QB test2: gmail dkim fail
2009-12-03 19:09:20 1NGFB9-0003QN-QB test3: gmail dkim none

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-04 11:47:34
gmn
neyro писал(а):???? Бред какой то :smile:
Вы же сами написали 3 условия..все правильно работает.
dkim_status = pass
dkim_status = fail
dkim_status = none

2009-12-03 19:09:20 1NGFB9-0003QN-QB test1: gmail dkim pass
2009-12-03 19:09:20 1NGFB9-0003QN-QB test2: gmail dkim fail
2009-12-03 19:09:20 1NGFB9-0003QN-QB test3: gmail dkim none
Ну как же правильно?
Условия приведены выше.
Вот лог по письму:

Код: Выделить всё

2009-12-03 19:09:20 1NGFB9-0003QN-QB DKIM: d=gmail.com s=gamma c=relaxed/relaxed a=rsa-sha256 [verification succeeded]
2009-12-03 19:09:20 1NGFB9-0003QN-QB test1: gmail dkim pass
2009-12-03 19:09:20 1NGFB9-0003QN-QB test2: gmail dkim fail
2009-12-03 19:09:20 1NGFB9-0003QN-QB test3: gmail dkim none
2009-12-03 19:09:20 1NGFB9-0003QN-QB <= ***@gmail.com H=mail-bw0-f216.google.com [209.85.218.216] P=esmtp
В первой строчке написано, что "verification succeeded", т.е. под "pass" должно попадать.
Но под "fail" или "none" не должно же попадать?

Переписал условия по другому.

Код: Выделить всё

warn
    sender_domains = gmail.com
    dkim_signers = gmail.com
    dkim_status = pass
    logwrite = test1: gmail dkim pass
Теперь в логе одна запись по письму - или pass или fail.
Но пример ведь был взят из документации.

Для входящих думал подключить DKIM для начала, чтобы отсеять письма, которые якобы от gmail.com, но не подписанные (google все письма подписывает). Но засада ...
Насколько я помню из ранее прочитанного, то при пересылке письма ключи DKIM в загловках сохраняется и в чем преимущество DKIM по сравнению с той же технологией SPF, которая с пересылками не совместима (не учитывая SRS).

И вот сегодня "отловил" письмо, отправленное с gmail.com, принятое другой службой, и перенаправленное мне.
Письмо попало под "fail", хотя оно отправлено было изначально с gmail.com и имеет в заголовках ключи DKIM (т.е. гугль письмо подписал).

И пока, что успел проверить, по моему мнению DKIM можно использовать разве что в случае "pass", чтобы "отбеливать" подписанные письма.
С "fail" пока не все понятно.

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-07 12:29:38
SergeySL
Добавил статью по DKIM верификации средствами Amavisd-new и SpamAssassin.
Возможно, кому-нибудь пригодится...

Re: HOWTO: Exim & DKIM

Добавлено: 2009-12-31 22:17:32
kyeha
К gmn:
logwrite = <text>
This modifier writes a message to a log file as soon as it is encountered when processing an ACL. (Compare log_message, which, except in the case of warn and discard, is used only if the ACL statement denies access.) The logwrite modifier can be used to log special incidents in ACLs. For example:

Re: HOWTO: Exim & DKIM

Добавлено: 2010-01-31 12:05:35
Bionicman
Если кому надо, в дополнение к манулу топикстартера об отправке dkim-подписанных сообщений, ниже приведен рабочий кусок конфига для проверки входящих dkim-подписанных писем:

Код: Выделить всё

# Добавляем в список ACL для обработки:
acl_smtp_dkim = acl_check_dkim

# ...

# Можно разместить в начале, где задаются переменные для DKIM-отправки
# Это значит, чьи подписи мы будем точно проверять
DKIM_KNOWN_SIGNERS = paypal.com : gmail.com
dkim_verify_signers = $dkim_signers : KNOWN_DKIM_SIGNERS

# ...

# Создаем сам ACL в секции "begin acl"

# ...

# DKIM check
acl_check_dkim:

        accept  hosts           = +relay_from_hosts

        accept  authenticated   = *

        # Message without sign
        accept  dkim_status     = none
                condition       = ${if eq {$acl_c_dkim_hdr}{1} {no}{yes}}
        set     acl_c_dkim_hdr  = 1
                add_header      = :at_start:X-DKIM: Exim 4.71 on <имя_хоста> (no dkim signature)

        # Message with sign, begin
        warn    condition       = ${if eq {$acl_c_dkim_hdr}{1} {no}{yes}}
        set     acl_c_dkim_hdr  = 1
                add_header      = :at_start:X-DKIM: Exim 4.71 on <имя_хоста>

        # Message with sign, bad signature
        deny    dkim_status     = fail
                message         = Rejected: $dkim_verify_reason
                logwrite        = X-Auth: DKIM test failed: (address=$sender_address domain=$dkim_cur_signer), signature is bad.

        # Message with sign, invalid signature
        accept  dkim_status     = invalid
                add_header      = :at_start:Authentication-Results: <имя_хоста> $dkim_cur_signer ($dkim_verify_status); $dkim_verify_reason
                logwrite        = X-Auth: DKIM test passed (address=$sender_address domain=$dkim_cur_signer), but signature is invalid.

        # Message with sign, good signature
        accept  dkim_status     = pass
                add_header      = :at_start:Authentication-Results: <имя_хоста>; dkim=$dkim_verify_status, header.i=@$dkim_cur_signer
                logwrite        = X-Auth: DKIM test passed (address=$sender_address domain=$dkim_cur_signer), good signature.

        accept


Re: HOWTO: Exim & DKIM

Добавлено: 2010-01-31 12:10:46
Bionicman
Кто юзает roundcube, советую поставить плагин dkimstatus - он показывает иконку в RC по результатам проверки подписи.

Кто-нибудь поднимал DomainKeys в exim?

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-03 10:53:30
Laa
Bionicman, молодец! Коечто бы я не так сделал, но в целом умница! :good:

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-03 12:21:21
Bionicman
Laa писал(а):Bionicman, молодец! Коечто бы я не так сделал, но в целом умница! :good:
Давайте разбираться что именно. Я экзим еще не до конца понимаю, так как работаю с ним всего месяц

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-03 12:42:58
Laa
ok.
выдавать deny -- не хорошо. Ведь вполне нормальное письмо, отправленное с dkim-mta в рассылку будет изменено рассылкой, ну типа появится в хидере Subject в кавычках название рассылки, или добавятся хидеры и тд. Естественно, такое письмо не пройдет проверку dkim. Но это не означает, что это письмо нужно отбивать, верно?

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-03 15:53:51
neyro
Я бы накидывал при несовпадении (т.е. дким запись есть но не совпадает) ~ 20-30 спам баллов, при пороге в 60. Больше толку от этого дкима 0.

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-04 0:15:40
Bionicman
Laa писал(а):ok.
выдавать deny -- не хорошо. Ведь вполне нормальное письмо, отправленное с dkim-mta в рассылку будет изменено рассылкой, ну типа появится в хидере Subject в кавычках название рассылки, или добавятся хидеры и тд. Естественно, такое письмо не пройдет проверку dkim. Но это не означает, что это письмо нужно отбивать, верно?
Насколько я понял из доки экзима, заголовки дким не подписывает, а подписывает само сообщение. Иначе как он подпишет сам себя же (свой же хэш :smile: ). Кстати, если подпись есть, но хэш не совпадает, статус у проверки не fail, а invalid, а такие письма он пропускает.
neyro писал(а):Я бы накидывал при несовпадении (т.е. дким запись есть но не совпадает) ~ 20-30 спам баллов, при пороге в 60. Больше толку от этого дкима 0.
Смысл есть в том случае, если почтовый клиент умеет читать результаты аунтификации в заголовках и при варнингах выдеат при прочтении, что сообщение имеет инвалидную подпись. Что собственно и делает плугин к круглокубу, о котором я писал выше.

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-04 18:59:15
Laa
Bionicman писал(а):
Laa писал(а):ok.
выдавать deny -- не хорошо. Ведь вполне нормальное письмо, отправленное с dkim-mta в рассылку будет изменено рассылкой, ну типа появится в хидере Subject в кавычках название рассылки, или добавятся хидеры и тд. Естественно, такое письмо не пройдет проверку dkim. Но это не означает, что это письмо нужно отбивать, верно?
Насколько я понял из доки экзима, заголовки дким не подписывает, а подписывает само сообщение. Иначе как он подпишет сам себя же (свой же хэш :smile: ). Кстати, если подпись есть, но хэш не совпадает, статус у проверки не fail, а invalid, а такие письма он пропускает.
Он подписывает заголовки h=From:Subject:To:Message-Id:Date; заголовок DKIM-Signature он не подписывает.

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-04 21:41:28
Bionicman
Laa писал(а):
Bionicman писал(а):
Laa писал(а):ok.
выдавать deny -- не хорошо. Ведь вполне нормальное письмо, отправленное с dkim-mta в рассылку будет изменено рассылкой, ну типа появится в хидере Subject в кавычках название рассылки, или добавятся хидеры и тд. Естественно, такое письмо не пройдет проверку dkim. Но это не означает, что это письмо нужно отбивать, верно?
Насколько я понял из доки экзима, заголовки дким не подписывает, а подписывает само сообщение. Иначе как он подпишет сам себя же (свой же хэш :smile: ). Кстати, если подпись есть, но хэш не совпадает, статус у проверки не fail, а invalid, а такие письма он пропускает.
Он подписывает заголовки h=From:Subject:To:Message-Id:Date; заголовок DKIM-Signature он не подписывает.
Ну, собственно да, прямо в секции DKIM есть список того, что он подписывает.

Re: HOWTO: Exim & DKIM

Добавлено: 2010-02-04 22:13:42
Bionicman
Кстати, интересно, опция DomainKeys в экзиме насколько рабочая? Пока она заявлена как экспериментальная. Насколько я понял, это прямой аналог DKIM.