====== Фильтр спама для sendmail ======
Предлагаемая технология фильтрации спама
создавалась постепенно, исходя из практических потребностей.
Три года эксплуатации на почтовом узле cronyx.ru подтвердили
пригодность системы в реальных условиях нынешнего интернета.
По состоянию на май 2007 узел принимает в сутки
около 16500 сообщений. Из них:
* 2.4 % --- доставленные письма
* 97.6 % --- отражённый спам
Сквозь фильтр просачивается около 30 сообщений спама в сутки.
Эффективность фильтрации составляет около 99.8 %.
Наиболее активные спамеры:
* 31.7 % --- безымянные хосты (нет имени в DNS)
* 38.5 % --- анонимные хосты (имена вида 12.34.56.somewhere.net)
* 5.21 % --- .dip.t-dialin.net
* 2.08 % --- .rr.com
* 1.59 % --- .mtu-net.ru
* 1.44 % --- .tpnet.pl
* 1.30 % --- .comcast.net
* 1.05 % --- .ttnet.net.tr
* 1.02 % --- .wanadoo.fr
* 1.00 % --- .bezeqint.net
====== Конфигурация sendmail ======
В качестве почтового агента используется [[http://sendmail.org/ | sendmail]],
работающий в среде Unix (в данном случае ---
[[http://www.freebsd.org/ | FreeBSD]], но это непринципиально).
Для sendmail был разработан [[vakcf30 | конфигурационный файл]],
позволяющий настраивать параметры почтового узла, не пользуясь
традиционными сложнейшими пакетами макросов.
Файл конфигурации использует две внешних утилиты:
* mailscreener --- [[screener | противовирусный фильтр]], посредством антивирусов ClamAV и Касперского
* milter-regex --- антиспамный фильтр
====== Утилита фильтрации ======
Утилита фильтрации выполнена как дополнительный модуль
почтовой системы с интерфейсом Sendmail’s Content Management (Milter) API.
При разработке за основу взят
[[http://www.benzedrine.cx/milter-regex.html | milter-regex]], разработанный
Дэниэлом Хартмайером. По сравнению с оригинальной версией пришлось
сделать следующие доработки:
* Добавлена команда "continue", упрощающая составление выражений.
* Добавлены команды "*envrcpt" и "*header" как однократные версии обычных команд. Нужны для правильной работы "continue".
* Сделана возможность загрузки регулярных выражений из файла, вида "=(/etc/mail/hosts-black)".
* Введена возможность трассировки применения каждого регулярного выражения с записью в лог-файл.
* Лог-сообщения приведены к более ясному и логичному виду.
* Исправлены некоторые ошибки.
Тексты можно скачать здесь: {{milter-regex-2004-11-12.tgz}}.
В файле milter-regex.conf задаются действия, выполняемые при обработке
очередного письма. Полный его текст можно посмотреть
[[milter-regex | здесь]], с кратким описанием действий и команд.
====== Политика фильтрации ======
Фильтрация писем происходит в несколько этапов:
* Проверка имени хоста отправителя.
* Проверка адреса электронной почты получателя (на конверте).
* Проверка адреса электронной почты отправителя (на конверте).
* Проверка пути письма (заголовки Received).
* Проверка адреса электронной почты получателя (заголовок To).
==== Имя хоста отправителя ====
Команда "connect" имеет два параметра --- шаблоны для сравнения
с именем хоста и его IP-адресом.
- Разрешаем соединения от локального хоста (с IP-адресом 127.0.0.1)
- Разрешаем соединения от хостов из "белого списка" /etc/mail/hosts-white
- Запрещаем соединения от хостов с именем *.in-addr.arpa
- Запрещаем соединения от хостов с пустым именем и IP-адресом, отличающимся от 127.0.0.1
- Запрещаем соединения от хостов, не имеющих имени в DNS
- Запрещаем соединения от хостов с именем вида *.цифры.цифры*, обычно это анонимные пользователи больших сетей домашнего и корпоративного интернета
- Запрещаем соединения от хостов из "черного списка" /etc/mail/hosts-black
- Запрещаем сообщения, не имеющие поля Message-Id, если они не от хостов из "белого списка"
Такая методика позволяет на раннем этапе отсечь большую часть спама,
рассылаемого [[http://www.securitylab.ru/news/283856.php | сетями ботов]]
--- компьютеров, зомбированных специальными вирусами.
continue
connect `^localhost$`i `127\.0\.0\.1`
connect `=(/etc/mail/hosts-white)$`ie ``
reject "Your host name is invalid"
connect `\.in-addr\.arpa$`i ``
connect `\.`n `127\.0\.0\.1`n
tempfail "Your host IP address not resolving - check DNS, or send via SMTP server of your provider"
connect `\[.*]` ``
reject "Direct mail from your host is not permitted - send via SMTP server of your provider"
connect `[.-][[:digit:]]+[.-][[:digit:]]`ie ``
reject "Direct mail from your host is not permitted"
connect `=(/etc/mail/hosts-black)$`ie ``
reject "Invalid message format"
connect `=(/etc/mail/hosts-white)$`ien `` and \
not header `^Message-Id$`i `<.*>`
==== Адрес получателя ====
Часть потока спама рассылается по адресам, составленным из правильного имени
домена и произвольного имени пользователя, с надеждой
на случайное совпадение с реальным именем. Чтобы избавиться от таких
сообщений, делаем проверки:
- Безусловно разрешается доставка служебных писем по адресам postmaster@* и MAILER-DAEMON@*
- Для каждого из обслуживаемых доменов делается проверка соответствия имен пользователей по списку
reject "Adressee invalid"
envrcpt `<.*>`n
continue
*envrcpt ``ie
discard envrcpt `@cronyx\.ru>`i
continue # в домене www.cronyx.ru
*envrcpt ``i
*envrcpt ``i
discard envrcpt `@www\.cronyx\.ru>`i
continue # в домене vak.ru
*envrcpt ``i
discard envrcpt `@vak\.ru>`i
==== Адрес отправителя ====
Часть спама идет с некорректными обратными адресами, и это легко отследить.
Также спамеры пользуются для рассылки "почтовыми отражателями",
поэтому следует запретить bounce и подобные.
- Адрес отправителя должен быть заключен в угловые скобки
- В адресе отправителя запрещаются символ '?' и имена пользователя
* <>
* ""
* anonymous
* bounce
* bounces
* reklama
* заканчивающиеся точкой
- Безусловно разрешаются служебные имена типа MAILER-DAEMON@* и аналогичные
- Запрещаем почту от доменов вида bounce.*
- Запрещаем адреса из "черного списка" /etc/mail/emails-black
reject "Sender invalid"
envfrom `<.*>`in
envfrom `<<>@`
envfrom `<""@`
envfrom `?`
continue
envfrom ``i
envfrom ``i
discard
envfrom ``ie
envfrom `<=(/etc/mail/emails-black)>`ie
==== Путь письма ====
Один из основных объективных параметров сообщения - путь, отражаемый
в заголовках "Received". Часть таких заголовков спамер может подделать,
но не все. Создаем в файле /etc/mail/myrelays список почтовых
серверов, полям Received которых мы доверяем. Будем извлекать из
таких заголовков имя хоста - источника сообщения, и проверять его на
соответствие "черному списку". Хосты из "белого списка" разрешаем.
Хосты, не имеющие имени в DNS, запрещаем безусловно.
continue
*header `^Received$`i `localhost *( *localhost *)`i
# Пропускаем заголовок, если это не через знакомый сервер
*header `^Received$`i `by *=(/etc/mail/myrelays)[[:space:]]`ien
*header `^Received$`i `(localhost \[127\.0\.0\.1])`i
*header `^Received$`i `\( *=(/etc/mail/hosts-white) *\[`ie
*header `^Received$`i `\( *=(/etc/mail/hosts-white) *\)`ie
reject "Spam rejected"
*header `^Received$`i `\( *[[:alnum:]-]+ *\[`ie
*header `^Received$`i `\( *[[:alnum:].-]*=(/etc/mail/hosts-black) *\[`ie
tempfail "Your host IP address not resolving, check DNS"
*header `^Received$`i `( *[^)][^)]*) *( *\[.*] *)`i
*header `^Received$`i `( *\[.*])`i
*header `^Received$`i `(.*@ *\[.*])`i
==== Поле "To:" ====
Запрещаем письма-рассылки со скрытым списком получателей.
Процент таких писем небольшой, но настырный.
reject "Spam rejected"
*header `^To$`i `undisclosed-recipients`i
*header `^To$`i `unlisted-recipients`i
*header `^To$`i `^$`i
====== Составление черных списков ======
Для автоматического составления черных списков применяется следующая
техника. Каждый из пользователей имеет специальный ящик с именем,
скажем, "- Spam". Все письма, от которых он желает избавиться,
помещаются в этот ящик. Затем специальная утилита периодически
проходит по этим ящикам, извлекает имена хостов и адреса e-mail
и заносит их в черные списки.
Эта же утилита сравнивает черные списки с логом отраженных писем
за достаточно большой период (скажем, месяц) и удаляет
неиспользуемые имена и адреса.
Тексты такой утилиты можно взять здесь: {{mk_black.tgz}}