Сергей Яремчук
Технология борьбы со спамом DKIM
Несмотря на обилие различных технологий борьбы со спамом, последний до сих пор составляет львиную долю почтового трафика. В 2005 году на рассмотрение IETF в качестве стандарта аутентификации отправителя был предложен еще один стандарт DomainKeys Identified Mail (DKIM), разработчики которого предлагают свой способ решения этой задачи.
Сегодняшние антиспам-решения проверяют сообщение на всем пути его следования, начиная с проверки легитимности пользователя на этапе отправки, заканчивая фильтрами, встроенными в почтовый клиент. Кроме достоинств каждый метод имеет и свои недостатки, часто мешающие его полноценному использованию. О различных решениях уже не раз говорилось на страницах журнала, потому заострять внимание на них не буду.
На дальнейшую обработку принятого к доставке SMTP-сервером спам-сообщения будут затрачены определенные ресурсы. Именно поэтому наибольший интерес всегда представляли технологии, позволяющие отсеивать нежелательные сообщения в самом начале пути. Предложено несколько методов – аутентификация пользователя перед отправкой сообщения, рекомендованная в RFC 2505, цветные списки [1, 2], а также подтверждение прав отправителя – SenderID (RFC 4407, поддерживается Microsoft) и SPF (RFC 4408, OpenSource) [3]. Казалось бы, каждая в отдельности могла бы решить проблему спама, но, как видно, в реальности это далеко не так. По информации, опубликованной в Kaspersky Security Bulletin 2007, доля спама в почтовом трафике в среднем составила 79% [5]. Отслеживать «белые» и «черные» адреса и домены непросто, к тому же нередки случаи занесения в balcklist нормальных адресов. Количество серверов, использующих технологии SPF и SenderID, составляет лишь каплю в море, поэтому они часто используются только с одной целью – «обелить» отправителя. Вместо блокировки адреса, не прошедшего проверку, ему просто начисляют штрафные балы.
Но если посмотреть на путь сообщения со стороны пользователей, то можно сделать вывод, что единый гарантированный метод определения отправителя – PGP-подпись, все остальное можно легко подделать. Это и явилось основой технологии DKIM, предложенной Yahoo, Cisco Systems, при партнерстве Sendmail и PGP, описанной в трех RFC4871 (DomainKeys Identified Mail (DKIM) Signatures), RFC4686 (Analysis of Threats Motivating DomainKeys Identified Mail (DKIM)), RFC5016 (Requirements for a DomainKeys Identified Mail (DKIM) Signing Practices Protocol).
Суть DKIM
В основу DKIM легли две разработки – технология DomainKeys от Yahoo и система Internet Identified Mail от Cisco. Принцип ее в двух словах очень прост. Каждое сообщение, циркулирующее в такой системе, снабжается цифровой подписью, которая не только удостоверяет отправителя, но и гарантирует, что подписанная часть не была изменена. Сам процесс обмена выглядит стандартно и напоминает работу с PGP. Владелец домена создает пару ключей – открытый и приватный. Приватный используется на SMTP-сервере для подписи сообщения, которая передается в заголовке DKIM-Signature и связана с доменом отправителя. Запись выглядит примерно так:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=gamma;
h=domainkey-signature:received:received:message-id:date:from:to
:subject:mime-version:content-type:content-transfer-encoding
:content-disposition;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=rgAlZu……20bvEc=
|
Всего RFC4871 определяет 11 возможных ключей.
Также один домен может иметь несколько сигнатур, которые определяются полем selector в записи DKIM-Signature. Возможность записи нескольких ключей позволяет: использовать разные ключи для подписи сообщений с субдоменов, локальной доставки, а также безболезненно производить смену ключей.
Открытый ключ добавляется в txt-поле DNS-записи и при поступлении письма запрашивается получателем, который проверяет, действительно ли подпись была сгенерирована для этого домена, указанного в адресе отправителя. В зависимости от результата сообщение может быть принято, отвергнуто или добавлены штрафные балы в антиспам-фильтр. Таким образом DKIM существенно отличается от PGP и S/MIME, которые являются средствами защиты, ориентированными больше на индивидуальное использование.
В DKIM используются только проверенные временем криптографические инструменты. В настоящее время для цифровой подписи спецификация определяет два алгоритма: RSA-SHA1 и RSA-SHA256, хотя в будущем возможна поддержка и других алгоритмов. Длину ключа рекомендуется выбирать в диапазоне 1024 до 2048 бит. Ключ длиной 512 байт не рекомендуется из-за меньшей устойчивости, а 4096-битовый не поместится в максимальный 512-байтовый DNS UDP-пакет. При выборе следует также учитывать, что большее значение ключа потребует большей вычислительной мощности на обработку каждого сообщения.
Новая технология совместима с существующей инфраструктурой и не требует коренной перестройки сервисов (кроме адаптации SMTP) и изменения протоколов, может быть введена постепенно. Подписанное сообщение полностью «автономно», работа DKIM не зависит от PKI или каких-либо служб, ключ берется напрямую из DNS-записи и не должен подтверждаться третьей стороной. Организация, использующая DKIM, полностью несет ответственность за работу своего сервера, подпись лишь означает то, что кто-то отвечает за конкретное сообщение.
Разработчики утверждают, что технология на данном этапе относится скорее к дополнительным. Наличие подписи в сообщении ни к чему не обязывает принимающую сторону, не обеспечивает защиту после проверки подписи и не может никак повлиять при повторной передаче сообщения, если отправитель и получатель изменились.
Поэтому RFC рекомендует сообщения с серверов, не поддерживающих DKIM, обрабатывать обычным образом. Учитывая малый процент внедрения, это вполне логично, а значит письма со спамом также смогут проходить эту проверку и без других технологий борьбы со спамом не обойтись. Никто не мешает спамеру создать свои DKIM-совместимые SMTP и DNS-серверы, которые можно будет использовать в рассылках или рассылать спам со взломаных компьютеров, являющихся с точки зрения DKIM легальными. Но такие ресурсы обычно быстро выявляются и блокируются при помощи других технологий, а использование своего DKIM потребует некоторой легализации и затрат, что очень невыгодно спамерам, желающим остаться незаметными. Таким образом, в настоящее время технологию DKIM можно отнести к вспомогательным и ее задача аналогична SPF и SenderID – «обелить» адрес отправителя. Хотя с увеличением поддерживающих эту технологию систем она может измениться
Когда подписывать и проверять?
Несмотря на внешнюю простоту DKIM, при развертывании реальной системы следует ответить на несколько вопросов, ответы на которые могут повлиять на работу всей системы. Например, на каком этапе и что подписывать в сообщении. Во избежание злоупотреблений DKIM-подпись должна обязательно включать данные из полей From, Sender, Subject, Date, To. При этом подпись удостоверяет только часть сообщения, доступную на момент подписания. Идеальный случай – письмо, отправляемое пользователем, подписанное полностью и отправленное по назначению. Но разные компоненты почтового сервера могут добавлять новые поля, например списки рассылки. Таким образом, «новое» письмо уже не может быть рассмотрено как правильное. Поэтому подпись следует добавлять на самом последнем этапе отправки сообщения, чем ближе выход, тем меньше вероятность появления неподписанных записей.
Еще один метод подписи, предложенный разработчиками, – указать длину действительного сообщения в заголовке. Все, что будет добавлено в пределах подписанной длины, будет вполне легальным. Это решает проблему с теми же списками рассылки, но у злоумышленника появляется возможность изменить тело сообщения. Поэтому разработчики стандарта не рекомендуют указывать длину заверенного сообщения. Хотя выходом из такой ситуации может быть наличие двух подписей. Первая заверяет ограниченную часть письма, вторая добавляется уже на самом последнем шаге и распространяется на все сообщение. Каждая такая подпись сама по себе автономна и обрабатывается последовательно. Но наличие двух подписей – это дополнительная нагрузка на сервер, как передающей, так и приемной сторонам. Поэтому наиболее оптимальным вариантом считается все-таки заверение всего письма на самом последнем этапе передачи.
Теперь рассмотрим прием подписанного сообщения. Так как ключи могут быть заменены, рекомендуется проверку производить как можно раньше. Оптимальным вариантом является проверка «на лету» в ходе SMTP-сессии после получения всего письма. Это позволяет не занимать локальную очередь сообщениями, не прошедшими проверку, упростив дальнейшую работу антиспам-фильтров. А передающая сторона будет знать результат приема уже в ходе сеанса. Но очень часто SMTP-серверы перегружены. Теперь если добавить к этому еще и проверку DKIM-подписи (запрос ключа на DNS, вычисление и сравнение результата), то время на всю операцию может увеличиться ровно настолько, что передающая сторона, не дождавшись ответа, закроет SMTP-сессию.
Повторная попытка может привести к аналогичному результату. Кроме этого проверка DKIM на этапе SMTP-сессии упрощает DDOS-атаку на сервер, ведь, чтобы загрузить систему, потребуется меньшее количество запросов.
Поэтому оптимальным выходом из ситуации является проверка в одной из очередей сервера или обработка письма антиспам-фильтрами.
Установка DKIM с Postfix
В настоящее время существуют два проекта, позволяющие реализовать DKIM. Первый [6] предлагает Perl-модуль Mail-DKIM, реализующий поддержку протокола DKIM и SMTP-прокси DKIMproxy. Последний состоит из двух частей, обеспечивающих подпись исходящих и проверку входящих (Before-Queue или After-Queue) сообщений (при помощи Mail-DKIM). Изначально DKIMproxy написан под Postfix, но должен работать с любым другим почтовым сервером. Второй проект – dkim-milter [7] предлагает milter-интерфейс, используемый в Sendmail и Postfix. Cостоит из модуля dkim-filter и библиотеки libdkim, реализующей поддержку DKIM и DomainKeys.
Для примера, настроим DKIM, использовав связку Posfix + dkim-filter на примере Ubuntu server 8.04. Установка указанных приложений из исходных текстов довольно проста, поэтому заострять внимание на этом не буду, тем более что поиск в репозитарии приводит к удаче.
$ sudo apt-cache search dkim
dkimproxy – an SMTP-proxy that signs and/or verifies emails, using the Mail::DKIM module
libmail-dkim-perl – cryptographically identify the sender
of email – perl library
libdkim0 – cryptographically identify the sender of email
dkim-filter – DomainKeys Identified Mail (DKIM) Milter implementation
libsmdkim-dev – DomainKeys Identified Mail (DKIM) library implementation
libsmdkim2 – DomainKeys Identified Mail (DKIM) library implementation
|
Кстати, команда:
$ sudo apt-cache search milter
показывает наличие и пакета dk-filter, реализующего поддержку DomainKeys. Учитывая, что технологию DomainKeys уже используют Google и Yahoo, к ней также стоит присмотреться.
Для упрощения будем считать, что Postfix уже установлен и настроен. Устанавливаем компоненты:
$ sudo apt-get install dkim-filter
При настройке dkim-filter получаем сообщение:
Starting DKIM Filter: dkim-filter: /etc/dkim-filter.conf: at least one selector and key required for signing mode
See /usr/share/doc/dkim-filter/README.Debian for help
Starting for DKIM verification only
|
показывающее, что демон пока настроен только на проверку подписи.
Следующим шагом необходимо сгеренировать пару ключей. Это можно сделать средствами OpenSSL:
$ openssl genrsa -out private.key 1024
$ openssl rsa -in private.key -pubout -out public.key
Но удобнее для этих целей использовать утилиту dkim-genkey, поставляемую вместе с dkim-filter:
$ dkim-genkey -d example.com -s example.com
Параметр -d позволяет указать домен, сообщения с которого будем подписывать, а -s – название файла ключа.
В результате работы в текущем каталоге появятся два файла: example.com.txt и example.com.private, в которых содержатся открытый и закрытый ключи. В качестве имени ключа лучше всего использовать название домена. Так будет меньше путаницы при работе с несколькими доменами, кроме прочего этого требуют и настройки dkim-filter.
Содержимое key.txt следует поместить в файл настройки зон DNS-сервера. После создания он выглядит так:
$ cat example.com.txt
example.com._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=MIGf......pQSA/wIDAQAB" ; ----- DKIM example.com for example.com |
Запись DKIM является поддоменом _domainkey, поэтому перед добавлением в TXT-поле результат работы dkim-genkey следует преобразовать к виду:
_domainkey.example.com IN TXT "v=DKIM1; g=*; k=rsa; p=MIGf......pQSA/wIDAQAB";
Кроме этой записи рекомендуется добавить DKIM Author Domain Signing Practices (ADSP). Это поле не описано в RFC4871, обсуждается в документе [9] и призвано уменьшить неразбериху на первых порах продвижения DKIM. Администратор домена публикует политику использования DKIM в DNS-записи. Примерно так:
_asp._domainkey.example.com IN TXT "dkim=OPEN"
Поле «dkim=OPEN/CLOSED/LOCKED» и определяет политику, то есть разрешена (по умолчанию) или запрещена отправка неподписанных сообщений в этом домене. Поле LOCKED указывает, что в этом домене сообщения всегда подписываются и в случае обнаружения неподписанного сообщения его нужно блокировать. Для удобства создания записи можно использовать веб-страницу ADSP Wizard (см. рис. 1) на Sendmail tools [8]. Правда, там указываются отличные от документа [9] значения поля dkim=unknown|all|strict, фигурировавшие в документах на первых порах.
Рисунок 1. Мастер создания ADSP-записи
Копируем закрытый ключ на свое место.
$ sudo mv -f key.private /etc/postfix
Конфигурационный файл демона DKIM называется /etc/dkim-filter.conf, по умолчанию в нем раскомментирован только один параметр. Поэтому перед запуском его необходимо отредактировать.
# Запись сообщений в syslog
Syslog yes
# Маска доступа для создаваемого сокета
# UMask 002
# Путь к UNIX-сокету или адрес TCP-сокета inet:port[@host]
# по умолчанию 127.0.0.1:8891
# Socket /var/run/dkim-milter/dkim.sock
# В случае проблем с доступом можно запускать dkim-milter от имени определенного пользователя
# UserID userid[:group]
Background yes
# Список доменов, перечисленный через запятую, возможно использование шаблона "*"
Domain example.com
# Как вариант указывается файл, в котором содержится список доменов по одному в строке
# Domain /etc/postfix/dkim-domain.conf
# Файл, содержащий закрытый ключ
KeyFile /etc/postfix/key.private
# Если есть, указываем и селектор
# Selector 01.01.2008
# Если ключей несколько, заносим их перечень в файл, при его установке параметр KeyFile игнорируется
# запись выглядит как отправитель:домен:полный путь к файлу закрытого ключа
# *example.com:example.com:/etc/postfix/key.private
# Если файл ключа не будет найден, проверяются файлы с окончанием ".pem" и ".private"
# KeyList /etc/postfix/dkim-keys.conf
# Перезапускать ли при ошибках
AutoRestart no
# Режим работы - s (signer, подпись) и v (verifier, проверка, по умолчанию)
Mode sv
# Подписывать ли сообщения, отправляемые из поддоменов, описанных в Domain
SubDomains yes
# Тайм-аут DNS
DNSTimeout 5
# По умолчанию для подписи используется алгоритм rsa-sha256
# SignatureAlgorithm rsa-sha256
# Отключаем ASPD
#UseASPDiscard no
# Всегда добавлять заголовок Authentication-Results
AlwaysAddARHeader yes
# Статистика
Statistics /var/log/dkim-filter/dkim-stats
# Проверка необходимых заголовков сообщения
RequiredHeaders yes
# Что делать с письмами с неверной подписью:
# accept (по умолчанию), discard, tempfail, reject.
# On-BadSignature reject
Это только основные параметры, некоторые другие позволяют указать специфические для MTA настройки, пользователей, чьи сообщения должны подписываться/проверяться, и так далее. Подробно они расписаны в «man dkim-filter.conf».
После настройки запускаем dkim-filter:
$ sudo /etc/init.d/dkim-filter start
Starting DKIM Filter
По умолчанию он будет прослушивать порт 8891 на localhost:
$ netstat -an | grep 88913
tcp 0 0 127.0.0.1:8891 0.0.0.0:* LISTEN |
Теперь необходимо настроить Postfix (поддерживает milter с версии 2.3.0), добавляем в /etc/postfix/main.cf следующие строки:
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
Если используется UNIX-сокет, то последние две строки заменяем на:
smtpd_milters = unix:/var/run/dkim-milter/dkim.sock
non_smtpd_milters = unix:/var/run/dkim-milter/dkim.sock
Перезапускаем Postfix:
$ sudo /etc/init.d/postfix restart
Для проверки работоспособности системы разработчики создали специальный адрес autorespond+dkim@dk.elandsys.com, отсылаем на него пустое сообщение и в ответ получаем информацию, работает или нет DKIM (см. рис. 2).
Рисунок 2. Ответ на тестовое сообщение
В настоящее время найти запись, свидетельствующую о поддержке SPF и даже DomainKeys, гораздо проще, чем DKIM.
$ host -t txt _domainkey.dk.elandsys.com
И подобный ответ можно считать удачей.
$ host -t txt mail._domainkey.markley.org
Учитывая, что технология еще окончательно не утверждена и находится в постоянном развитии, до массового внедрения еще, наверное, очень далеко. Также стоит отметить, что, по сути, они не могут решить проблему спама. Их внедрение лишь позволяет защититься от подделки адреса, предоставляя дополнительную информацию для принятия решения антиспам-фильтрами.
- Супрунов С. Greylisting: панацея от спама или «мыльный пузырь»? //Системный администратор, №7, 2006 г., – С. 12-15.
- Барабанов А. Борьба со спамом как фактор, снижающий надежность почтовой доставки. //Системный администратор, №8, 2007 г., – С. 6-13.
- Яремчук С. Sender Policy Framework как средство борьбы со спамом. //Системный администратор, №4, 2007 г., – С. 34-39.
- Сайты с информацией о DKIM – http://www.dkim.org, http://tools.ietf.org/wg/dkim.
- Kaspersky Security Bulletin 2007. Спам в 2007 году – http://www.viruslist.com/ru/analysis?pubid=204007593.
- RFC4871 – http://www.ietf.org/rfc/rfc4871.txt.
- Сайт проекта DKIMproxy – http://dkimproxy.sourceforge.net.
- Сайт проекта dkim-milter – http://sourceforge.net/projects/dkim-milter.
- Инструменты DKIM на сайте Sendmail – http://www.sendmail.org/dkim/tools.
- DKIM Author Domain Signing Practices (ADSP) – http://tools.ietf.org/html/draft-otis-dkim-adsp-04.