[Карта]                [Начало]                [Sendmail-ссылки]                [Синтаксис]                [Типовые задачки]                  [Задачки по маршрутизации]                  [Задачки по маcкарадингу]                  [SendmailACL]                  [Spamooborona]                  [VadeRetro]                  [Regex]                  [Тонкости]                  [Недок.особен.]                  [Несущ.юзеры]                  [Прячемся!]                  [RFC1893.Цитаты]                  [ТП.Эмоции]                  [Антиспам&Разум]                  [Экзерсисы]                 


Спам-фильтр для sendmail.

01.10.2007г. Nota Bene! Данный фильтр уже не эффективен, оставляю его только потому, что здесь выложено много разных находок.
27.05.2008. Текущее состояние дел на этом фронте можно посмотреть здесь.

В данном документе представлены правила sendmail, использующие регулярные выражения
для определения наличия спама в письме по ключевым словам в обратном адресе, в теме письма и в ряде других заголовков. Блокировка спам-почты происходит на этапе smtp-диалога, то есть письмо на сервер не принимается. Это так называемая предпроверка.

Предлагается использовать этот способ фильтрации спама как дополнительный к SpamAssasin, Milter и другим почтовым фильтрам.
Данный фильтр не избавляет от спама полностью. Так как спамеры постоянно меняют свою тактику, то фильтр требует постоянной доработки: например, раньше фильтрация по темам сообщений была эффективной, теперь же темы спам-писем зачастую непредсказуемы и бессмысленны, поэтому я на своем сервере почту по теме сообщения уже не фильтрую. Также малоэффективной стала проверка и CheckMailer. В то же время за последнее время прокатилась волна спама собратным адресом, подделанным под рассылку от Городского Кота. Проверка на такого рода спам в этот фильтр не включена, но ее, а также проверку ip-адреса источника письма с локальным административным адресом, можно взять здесь.
Статистику по работе фильтра можно посмотреть здесь.

О ложных срабатываниях.
Хотя некоторые случаи ложного срабатывания учтены в WhiteList'ах для e-mail, Subject и relay-address, я настоятельно рекомендую внимательно просмотреть использованные в фильтре специальные преобразования - возможно для вашей почтовой системы они окажутся слишком строгими.
Особое внимание обратите на преобразования SPAM7, SPAM8, CH1, CH2, которые анализируют подзаголовки "Received:". Первые два отвергают почту с dialup'овских адресов, последние два анализируют доменные имена relay'ев.
Это наиболее результативные преобразования (см. статистику), но вместе с тем вероятность ложного срабатывания по ним велика, например, если ваш почтовик должен получать почту с серверов, имеющих динамические (dial-up-овские) адреса. В этом случае необходимо добавить в спец. преобразование NOSPAM01 соответствующее доменное имя или сетку, из которой раздаются динамические адреса.

Также рекомендую обратить внимание на еще одну весьма результативную проверку: набор правил check_eoh, позволяющий запретить локальную почту с нелокальных ip-адресов, отправляемую непосредственно через ваш почтовик. Если ваш клиент захочет отправить локальную почту непосредственно через ваш почтовик, находясь при этом за пределами вашей сети, то он сможет это сделать только в том случае, если его почтовый клиент настроен на smtp-авторизацию.

Вторая часть документа взята отсюда http://www.softerra.ru/freeos/19480/page1.html
Она включает в себя подборку правил Севы Глущенко .

Sendmail должен быть собран с поддержкой regex.
Для этого в файл /usr/src/sendmail-X.X.X/devttols/Site/site.config.m4 нужно добавить строку:
APPENDDEF('confMAPDEF','-DMAP_REGEX').
Если этого файла нет, то его нужно создать.
Затем нужно пересобрать sendmail и перезапустить его.
Если sendmail собран без поддержки REGEX, то при запуске sendmail будете получать сообщение:
554 5.0.0 /etc/mail/sendmail.cf: line NNN: readcf: map MAP_NAME: class regex not available
Команда "echo '$v' | /usr/sbin/sendmail -bt -d0 | grep MAP_REGEX" определит, собран ли sendmail с поддержкой regex.

Спам-фильтр представлен в двух вариантах:
вариант проверки почты всех пользователей и
вариант с поддержкой списка тех пользователей, чья почта должна фильтроваться.
(На самом деле то, что использую я на своем почтовике, уже давно и сильно отличается от выложенного здесь фильтра, будет время - обновлю. Как уже говорилось выше, практически любой спам-шаблон очень недолговечен. 06.12.2006. )
В обоих случаях необходимо внести некоторые исправления, соответствующие ip-адресу и почтовому доменному имени вашегопочтовика.

Спам-фильтр следует добавить в конец стандартного sendmail.mc (после определения MAILER), заменив пробелы между LHS и RHS табуляцией, пересобрать sendmail.cf и перезапустить sendmail.
Cпам-фильтр в формате uuencode (с сохраненными знаками табуляции) - здесь(вариант1) и здесь(вариант2) .
Комментарии к специальным преобразованиям - здесь. Обратите внимание на то, что приведенные на этой странице спец. преобразования относятся к самому первому варианту этой статьи и отличаются от спец. преобразований, использованных в последнем варианте.
Как проверить работу фильтра, не посылая письма, можно посмотреть здесь.

В Сети есть перевод Плотникова А.С. "Sendmail Installation and Operation Guide (by Eric Allman)"для версии 8.11. На сайте www.sendmail.org этот документ находится здесь (v.8.12).
Во время работы над статьей мне встретилось много интересной информации по данной теме, особенно на comp.mail.sendmail. Потерять ее было бы жалко, поэтому привожу эту информацию на данной странице.

---------------
Из-за большой длины строк с регулярными выражениями пришлось разбить их на подгруппы.
На comp.mail.sendmail предлагается такое решение, когда строки получаются очень длинными:
define(`xic_a2000_nl', `node-[cd]-[0-9a-f]{4}\.a2000\.nl$')dnl
define(`xic_attbi_com', `(-[0-9]{1,3}){3}\.client[2]?\.attbi\.com$')dnl
define(`xic_wanadoo_fr', `(-[0-9]{1,3}){4}.*\.wanadoo\.fr$')dnl
Kxic regex xic_a2000_nl|xic_attbi_com|xic_wanadoo_fr
Или так:
define(`xic_host', `(pattern1|pattern2|pattern3)')dnl
define(`xic_domain', `(a2000|attbi|wanadoo)')dnl
define(`xic_tld', `(com|fr|nl)$')dnl
define(`xic_regex', `xic_host\.xic_domain\.xic_tld')dnl
Kxic regex xic_regex
Там же рекомендуется комбинации, на которых наиболее часто срабатывают regex-правила,
помещать в список первыми (для уменьшения нагрузки на CPU). То же самое касается и правил перезаписи.

---------------
Nota bene!
1. В regex-выражениях использованы [.] для обозначения точки ( man regex гласит:"... With the exeption this ... all other special characters,including "\", lose their special significance within a bracket expression...");
\$$ в качестве $ (см. /usr/src/sendmail_XXX/doc/op.me) и
\. в качестве пробела ( в силу опции в sendmail.cf):
# substitution for space (blank) characters
O BlankSub=.
Кстати, при внимательном прочтении "Sendmail Installation and Operation Guide" обнаружилось наличие специального флага для замещения знака пробела в спец. преобразованиях почти всех классов:
-Sspacesub The character to use to replace space characters after a successful map lookup (esp. useful for regex and syslog maps).
В случае использования этого флага специальное преобразование будет выглядеть так (блокируем словосочетание "special offer"):
Kmap regex -a@MATCH -Sa specialaoffer
Более того, флаг -S без последующего символа позволяет работать с пробелом вообще без каких-либо проблем и замещений:
Kmap regex -a@MATCH -S special offer
В документации об этом ни слова, но тем не менее это работает.

2.Встроенные в regex классы [[:space:]] и [[:blank:]] срабатывают только на этапе проверки
/map SPAM string[[:space:]]for[[:blank:]]check[[:space:]]
в тестовом режиме, но вызов специального преобразования из правила перезаписи ожидаемого результата не даст. Класс [[:digit:]] можно использовать без ограничений, класс [[:punct:]] - когда нужно определить в специальном образовании знаки пунктуации, кроме запятой и обратного слэша.

3. Следует иметь в виду, что sendmail обрамляет символы: @ ; : ( ) [ ] . : % ! ^ / [ ] + пробелами, а двойные, тройные и т.д. пробелы заменяет одним пробелом, поэтому, если необходимо заблокировать письма с темой "Re: Details", то в специальном преобразовании должно фигурировать "Re:Details", а не "Re:\.Details", причем данное преобразование заблокирует "Re:Details" с любым количеством пробелов вокруг двоеточия, а также без пробелов. Символ \ пробелами не обрамляется, а запятая вообще не учитывается, т.е. если спец. преобразование выглядит так:
КSpam_subj regex -a@MATCH te,st
то будут блокироваться письма с темой "test"

3A. С помощью regex невозможно заматчить смайлик :) в теме письма. В этом случае можно можно использовать два способа.
1.
LOCAL_RULESETS
HSubject:                $>Check_Subject
SCheck_Subject
R$* :) $*                $#error $: 553 Sorry, Your subject looks like SPAM
2.
LOCAL_CONFIG
F{Subj}/etc/mail/Subj
LOCAL_RULESETS
HSubject:                $>Check_Subject
SCheck_Subject
R$* $={Subj} $*                 $#error $: 553 Sorry, Your subject looks like SPAM
Файл Subj:
:)
Пересобираем sendmail.cf и перезапускаем sendmail.

4. При добавлении новых слов в список необходимо следить, чтобы последним в строке
не оказался символ "|", иначе будут блокироваться любые темы.

5. Как недавно выяснилось, sendmail не проверяет поле в Header, если оно пустое либо отсутствует, а посему невозможно заблокировать письма с пустым или отсутствующим полем "To:" и такая комбинация не срабатывает:
HTo:                 $>CheckTo
SCheckTo
R$@                 $#error $@ 5.7.1 $: "554 Unspecified Mailbox ID"

Это известный баг, упоминаемый в KNOWNBUGS:
* Header checks are not called if header value is too long or empty.
Выход все тот же - Milter. Либо Claus Assmann cоветует сначала определить макрос, если заголовок непустой, а затем в последней проверке check_eoh определить, пустой он или нет. Мой пример - здесь.
На www.opennet.ru было найдено такое решение этой проблемы:
SCheckFrom
R $+                 $@ OK
R $*                 $#error $: Illegal From Header
Но у меня это не заработало: как показывает syslog, пустые поля "To:" и "From:" исправно заполняются из "Mail from:" и "Rcpt to:".

6. Для отладки можно использовать спец. преобразование Ksyslog .
В этом случае правила перезаписи несколько видоизменяются, а в результате в /var/log/maillog записывается более подробная информация о проверямом объекте.
Например, если проверяется поле "To:", то его содержимое будет записываться в лог каждый раз при проходе письма, а не только при срабатывании блокирующего правила.
Ksyslog syslog
...
HTo: $>CheckTo
...
SCheckTo
R$*                 $: $(syslog To: $1 $)
Результатом будет запись поля "To:" в /var/log/maillog
При обработке спец. преобразования syslog lookup возвращает пустую строку (см. /usr/src/sendmail_XXX/doc/op.me ), поэтому, если необходимо не просто записать поле "To:" в лог, но и продолжить с ним работу, то следует добавить $1 до или после вызова спец. преобразования:
SCheckTo
R$*                 $: $1 $(syslog To: $1 $)
или
R$*                 $: $(syslog To: $1 $) $1
R$*Recipient$*                  $#error $@ 5.7.1 $: "554 Unspecified Mailbox ID"
R$*Undisclosed$*                  $#error $@ 5.7.1 $: "554 Unspecified Mailbox ID"


7. Часто спрашивают, как почту, "пойманную" каким-либо антиспам-правилом, перенаправить в какой-либо ящик для проверки.
С первого взгляда эта задача легко решаема, стоит только изменить правила, например, вместо:
SCheck_Subject
R$+                 $: $(ChSbVIRAvron $1 $)
R@CATCHED                 $#error $: 553 This message may contain Avron.VIRUS
написать:
SCheck_Subject
R$+                 $: $(ChSbVIRAvron $1 $)
R@CATCHED                 $#local $: postmaster
На самом же деле это правило не сработает, потому что "Sendmail installation and operation guide " (п. 5.1.2) гласит: "...Синтаксис $# должен быть использован только в наборе правил 0, или подпрограмме набора правил 0. Он приводит к немедленному завершению выполнения набора правил, и сигнализирует sendmail, что адрес полностью разрешен. Полный синтаксис таков: $#mailer $@host $:user ... "
А вообще почитайте подробнее про это здесь.

8. На данной странице рассмотрен вариант, когда спам-комбинации перечисляются в специальном преобразовании c участием класса regex.
Возможны 4 дополнительных варианта задания спам-комбинаций, только в этих случаях использовать регулярные выражения будет невозможно.

9. При проверке переменных из Header можно вместо $1 использовать переменную $&{currHeader}(op.me:"...Header value as quoted string..."), это поможет избежать проблем с пробелом - его не нужно будет замещать комбинацией " \." в спец. преобразовнии Kmap etc.
Вызов набора правил и сами правила перезаписи будут выглядеть так:
HSubject: $>Check_Subject
SCheck_Subject
R$*                  $: $(SPAM $&{currHeader} $)
R@CATCHED                 $#error $: 553 This message from $&f may contain spam.
Или так:
R$*                  $: $(SPAM $&{currHeader} $:<OK> $)
R<OK>                  $@ OK
R@CATCHED                 $#error $: 553 This message from $&f may contain spam.

Header трактуется как структурированный файл, то есть тексты в скобках (комментарии к правилам) удаляются. Для того, чтобы избежать этого и работать с полным заголовком, применяют другой вызов набора правил:
HSubject: $>+Check_Subject

Те заголовки, для которых не определены наборы правил (а по большому счету - все заголовки), могут быть обработаны следующим образом:
H*:             $>CheckHdr
или так:
H*:             $>+CheckHdr

---------------
Комментарии к использованным специальным преобразованиям.

LOCAL_CONFIG
# Формат специальных преобразований и синтаксис ссылок на них описан в параграфе 5.9
# "Пособия по установке и конфигурированию Sendmail" :
# "... 5.9. K - Определение Файла Ключей
# Специальные преобразования могут быть определены использованием строки:
# Kmapname mapclass arguments
# Где mapname - имя, под которым это преобразование используется в правилах перезаписи; mapclass
# - имя типа преобразования (эти имена вкомпилированы в sendmail); arguments интерпретируются в
# зависимости от класса; обычно, используется один аргумент, указывающий на файл, содержащий
# преобразование..."

#  Cинтаксис ссылок на преобразования описан там же:
# " ... На специальные преобразования ссылаются, используя синтаксис:
#     $( ключ преобразования $@ аргументы $: умолчание $)
# где и аргументы и умолчание могут быть опущены. $@ аргументы могут встречаться много раз.
# Указанный ключ и аргументы передаются в соответствующую преобразующую функцию. Если она
#  возвращает значение, то оно замещает ввод. Если она не возвращает значение и имеется
# определенное умолчание, умолчание заменяет ввод. Иначе ввод не изменяется... "


#WhiteList для e-mail (несмотря на наличие sale, shop, job, deal, love & shit эл. адреса, содержащие эти слова,
#не должны блокироваться):
KSPAM0 regex -a@MATCH tsalenko|alert|workshop|ideal|-job-|rashit|rollover

# BlackList для e-mail:
# Электронные адреса, в которых встречается больше 2 знаков подчеркивания:
KSPAM1 regex -a@MATCH ^([[:alnum:]]*)(_+)([[:alnum:]]*)(_+)([[:alnum:]]*)(_+)[[:alnum:]_]*$

# Стандартные спам-слова:
KSPAM2 regex -a@MATCH movie|woman|discount|astrolog|nomail|adres|addres|viagra|rassylk|anonymous|game|dollar|offer|deal|proces|bonus|casino|reclam|reklam|office|noemail|nouser|sms|prize|sale|job|market|money|cash|shop|xxx|sex|donna|girl|adult|fuck|honey|sweet|porno|playboy|love|lolita|penis|cock|kiss

# Цифровые электронные адреса:
KSPAM3 regex -a@MATCH ^[[:digit:]]+$

# Комбинированные адреса вида 12.23abc@mail.ru, 12-23dfg@mail.ru, 123-345_567@mail.ru:
KSPAM4 regex -a@MATCH ^([[:digit:]]+)([-+=._~]+)([[:digit:]]+)[[:alnum:]+=._~-]*$

#Доменная часть, в которой встречается 3 или более цифры, дефиса или знака подчеркивания (например, jackshck@66-50-94-20.prtc.net, kelvin@69.37.99.9.adsl.snet.net, head@p3EE251E8.dip.t-dialin.net, htmltmpl@d99-ps0-ros.alphalink.com.au )
KSPAM5 regex -a@MATCH .*[0-9_-].+[0-9_-].+[0-9_-].*

# WhiteList для поля Subject:
KChSb regex -a@CATCHED tsalenko|alert|workshop|ideal|-job-|rashit|rollover

# BlackList для поля Subject:
# Темы писем с Avron-вирусом :
KChSbVIRAvron regex -a@CATCHED IREX.+fields|FSAU.*2003|ACCELS|Avril|Redirection|Ocho|According|ecurity\.breach|for.+Incorrect.+MIME-header|senior|Specification.+requested|Crime|Junior.+Achievement|perduto|customers|Daos|IIS-Sec|estate|Admission

# Темы писем с Klez-вирусом :
KChSbVIRKlez regex -a@CATCHED mail(\.+)--|A.+IE.+6.+0.+patch|W32|Klez|\.Eden|removal.+tools

# Темы писем с Sobig.f-вирусом (тема "Re: That movie" будет поймана в спец. преобразовании KChSbSpam) :
KChSbVIRSobig regex -a@CATCHED screensaver|Your\.application|Re.+Approved|My\.details|Re.+Details|Your\.details|Thank\.you!
KChSbVIRSobig regex -a@CATCHED screensaver|Your\.application|Re:Approved|My\.details|Re:Details|Your\.details|Thank\.you!|(microsoft|critical|last|secur|current|network|internet|new|bug|error|abort).+(patch|pack|up|mess|announ|report|letter)|advice

# Темы писем с явным спам-Subjectом :
KChSbSpam regex -a@CATCHED \$$[[:digit:]]+|language.+center|toefl|game|\.xxx|woman|discount|dollar|casino|rassylk|reklam|reclam|prize|sale|cash|bonus|money|game|donna|girl|adult|fuck|honey|sweet|porno|cock|playboy|play.+boy|\.love|lolita|penis|movie|darling|passwd
KChSbSpam2 regex -a@CATCHED [[:digit:]]+%|\.ass\.|\.sex|titt|nude|DVD|.+vogue|\.elle|harper's.+bazaar|marie.+claire|astrolog|viagra|fetish|\.oral|shit|topless|orgy|\.suck\.|shop|lesbo|urgent\.assistance|mobil|kiss|\.sms\.|motors|business|english|drink

# Cпам от American Language Center.
# Письма от Outlook Express - тема в кодировке base-64 (koi-8) :
# Письма от TheBat! - тема в кодировке base-64 (win-1251) :
# здесь указаны ключевые комбинации символов, позволяющие выловить сочетание слов
#"деловой/разговорный/бизнес + английский" в обоих регистрах:
# win-1251:Дделовой|ДЕЛОВОЙ|Рразговорный|РАЗГОВОРНЫЙ|БИЗНЕС|Ббизнес
#koi-8:Дделовой|ДЕЛОВОЙ |РАЗГОВОРНЫЙ|Рразговорный|Ббизнес|БИЗНЕС
KChSbRuSpam1 regex -a@CATCHED Pr6Onx6ujp|zcPLyMnR|3j6\+jp8e|M3Dy8jJ0|DNw8vIydH|Dt4\+vo6fHq|zsfMycrTy|7ufs6erz|7n7Onq8\+v |7HzMnK08v|x8zJytPLy|Hu5\+zp6vP

# Netscape Messenger - кодировка Quoted Printable
#н г л и й с к| Н Г Л И Й С К
KChSbRuSpam2 regex -a@CATCHED =CE.*=C7.*=CC.*=C9.*=CA.*=D3.*=CB|=EE.*=E7.*=EC.*=E9.*=EA.*=F3.*=EB

# Остальные спам-слова в теме на русском языке:
# а н г л | м е р и к а н с к | с к и д к | п о д а р | р е к л а м |Научитесь понимать|курс рубл|руководите| с упер
# О Т Д Ы Х |аркетинг| ш т а м п
KChSbRuSpam3 regex -a@CATCHED [юЮ].*[мМ].*[цЦ].*[кК]|[лЛ].*[еЕ].*[пП].*[хХ].*[йЙ].*[юЮ].*[мМ].*[яЯ].*[йЙ]|[яЯ][йЙ][хХ][дД][йЙ]|[оО][нН][дД][юЮ][пП]|[пП][еЕ][йЙ][кК][юЮ][лЛ]|мЮСВХРЕЯЭ\.ОНМХЛЮРЭ|ЙСПЯ\.ПСАК|ПСЙНБНАХРЕ|[яЯ]СОЕП|[нН][рР][дД][шШ][уУ]|ЮПЙЕРХМЦ|[ьЬ].*[Рр].*[Юю].*[Лл].*[Оо]
#ю ридич|утешеств| т ренинг|истрибьют|тратеги| н алог|ухгалтер|ффективны|редлагаем|отрудничеств|отели
# знать|аш сайт| т ариф| п окуп| п рода|изнес|роизнош |азговор |есплат| к урорт | б а з а(ы)
KChSbRuSpam4 regex -a@CATCHED [чЧ]ПХДХВ|СРЕЬЕЯРБ|[рР]ПЕМХМЦ|ХЯРПХАЭЧР|РПЮРЕЦХ|\.[мМ]ЮКНЦ|СУЦЮКРЕП|ТТЕЙРХБМШ|ПЕДКЮЦЮЕЛ|НРПСДМХВЕЯРБ|НРЕКХ\.ГМЮРЭ|ЮЬ\.ЯЮИР|[Рр]ЮПХТ|[оО]НЙСО|[оО]ПНДЮ|ХГМЕЯ|П.*Н.*Х.*Г.*М.*Н.*Ь|Ю.*Г.*Ц.*Н.*Б.*Н.*П|ЕЯОКЮР|[уУ]ЙСЫНР|\.[аА][юЮ][гГ][юЮшШ]\.
KChSbRuSpam5 regex -a@CATCHED юридич|утешеств|[тТ]ренинг|истрибьют|тратегия|ухгалтер|ачальник|тариф|девушк|дисконт|английск|выставк|ярмарк|скидк|распродаж|реклам|цены|знакомств|секс|рассыл|фильм|рубл|отд[оы]х|каникул|[Cс]отрудничест|[Пп]редлагаем|[Ээ]ффективн
KChSbRuSpam6 regex -a@CATCHED покуп|продаж|изнес|мышлен|произнош|язык|есплатн|курорт|маркетинг|печат|визит|обучение

#Очень хотелось блокировать письма с вложениями с расширениями
#com|exe|bat|bas|vba|vbe|vbs|reg|inf|cmd|pif|sct|wsh|cpl|js|jse|lnk|chm|hlp|hta|mdb|scr|shs|vb|vbg|wsf
#Соответствующее специальное преобразование выглядело бы так:
#KChConType1 regex -a@CATCHED name=.+[.](com|exe|bat|bas|vba|vbe|vbs|reg|inf|cmd|pif|sct|wsh|cpl|js|jse|lnk|chm|hlp|hta|mdb|scr|shs|vb|vbg|wsf)
#Но, к сожалению, это оказалось невозможно, так как информация о вложениях
#содержится во внутренних (или по-другому, дополнительных) полях Content-Type, а также
# в необязательном поле Content-Disposition, которые sendmail проверять не умеет
#(информация об этом почерпнута из ответа на мой вопрос в новостной группе comp.mail.sendmail,
#для решения этой задачи будут кстати Milter, Mimedefang или готовый фильтр Sentinel,
#отвергающий подобные вложения.)
#Тем не менее привожу здесь пример проверки поля CheckContentType на тот случай, если
#кому-нибудь понадобится фильтровать почту по внешнему (т.е. основому) полю CheckContentType,
#в котором, как правило, содержится информация типа (RFC-1521):
#multipart/mixed; boundary="------..." или text/plain; charset=... и т.д.
#Фильтрование по внешнему полю отрабатывает нормально.
#Проверка по внешнему полю на "корейский спам":
KCharsetKorean regex -a@MATCH charset=.*(euc-kr|korean|ks.*c)
HContent-Type:                 $>CheckContentType
SCheckContentType
R$*                  $: $(CharsetKorean $1 $)
R@MATCH                  $#error $: 553 Korean not spoken here.
###
# HContent-Disposition:                 $>CheckContentDisposition
# SCheckContentDisposition
# Аналогично проверке CheckContentType.



Изменения.

21 августа 2003г.
1.Добавлена информация о невозможности проверки поля CheckTo на пустоту или его отсутствие.
2.Добавлена информация о Ksyslog, позволяющем просматривать в maillog некоторые поля (например, Subject) заголовка любого письма.

25 августа 2003г.
3.Добавлен фильтр тем писем, которые могут содержать Sobig.f
4. Добавлен раздел "Вопросы, оставшиеся без ответов."

24 октября 2003г.
1.Добавлена проверка доменной части электронной адреса на SPAM2 & SPAM5. По фильтру SPAM5 блокируется 1000-1500 сообщений в день.
2.Добавлены правила, позволяющие перенаправлять некую исходящую почту в локальный почтовый ящик.
3.Решена проблема с двоеточием в теме сообщения.
4.Добавлена информация о проблеме с проверкой пустого поля.
5.Добавлена проверка темы сообщения на Swen-вирус.
6.Исправлена информация о Ksyslog.
7. Спасибо Сергею Тараненко, в специальном преобразовании
KChSbRuSpam3 regex -a@CATCHED [юЮ].*[мМ].*[цЦ].*[кК]|[лЛ].*[еЕ].*[пП].*[хХ].*[йЙ].*[юЮ].*[мМ].*[яЯ].*[йЙ]|[яЯ][йЙ][хХ][дД][йЙ]|[оО][нН][дД][юЮ][пП]|[пП][еЕ][йЙ][кК][юЮ][лЛ]|мЮСВХРЕЯЭ\.ОНМХЛЮРЭ|ЙСПЯ\.ПСАК|ПСЙНБНАХРЕ|[яЯ]СОЕП|[нН][рР][дД][шШ][уУ]|ЮПЙЕРХМЦ|[ьЬ].*[Рр].*[Юю].*[Лл].*[Оо]
".*" заменены на ".?"

3 ноября 2003г.
1.Исправлены правила проверки на SPAM1-SPAM4.

11 ноября 2003г.
Добавлена информация об особенностях проверки переменных из Header.
Перенаправляем исходящую почту в заданный почтовый ящик.
Добавлена информация о дополнительных способах задания спам-комбинаций (с помощью классов D,C,F и специальных преобразований классов text, hash )

14 ноября 2003г.
Борьба с пробелом закончилась окончательной победой - да здравствует флаг -S !
Добавлена информация об использовании встроенных в regex классов: [[:space:]], [[:blank:]], [[:digit:]] и [[:punct:]].
Проверем переменные из заголовка с помощью переменной $&{currHeader}.

5 декабря 2003г.
Кажется, это последнее дополнение.
По просьбам трудящихся :)) добавлена проверка поля relay на наличие большого числа цифр, дефисов и знаков подчеркивания. Спасибо Сергею Легких: его предложение наконец-то сподвигло меня добавить проверку relay, эффективность которой превысила все ожидания.

16 января 2004г.
Добавлен "белый список" для тех клиентов, которые категоричеcки против фильтрации их почты.
Формат файла /etc/mail/regex/whitelist:
user1
user2
user3
Пока этот список реализован только для тех пор проверок, которые имеют отношение к заголовкам (Check_Subject, Check_Mailer, CheckTo, CheckFrom ...) Использовать "белый список" на этапах check_relay и check_mail невозможно, так как на этих этапах получатель еще не известен. Но кое-какие идеи были предложены на comp.mail.sendmail, так что, как дойдут руки, надеюсь, и эта возможность будет реализована.
Выглядят сотвествующие правила так:
F{WL}/etc/mail/regex/whitelist
HSubject: $>Check_Subject
SCheck_Subject
R$* $: $1 $| $&{u}
В зависимости от того, будем ли мы пропускать без проверки почту для юзеров, которые находятся в списке (1 вариант), либо, наоборот, не входят в заданный нами список, следует использовать либо первое либо второе из нижеследующих правил.
#R$* $| $={WL} $@ OK
R$* $| $~{WL} $@ OK
R$* $| $* $: $1
Вслучае использования второго варианта следует иметь в виду различие между определениями синтаксиса $= и $~ (см.п. 5.1.1):
" ... $=x Совпадение любой фразы класса x
$~x Совпадение любого слова не входящего в класс x ..."
В п.5.3 фраза определяется как последовательность символов, не содержащая сиволов пробела. То есть фразой может быть электронный адрес: user@domain.ru
Определение слова в документации не дается, но из различия определений синтаксисов $= и $~ можно сказать, что слово - это последовательность только букв и цифр. Например, user123 - это слово, а user123@dom.ru - это уже фраза. Понимание этого различия существенно, потому что невозможно произвести проверку $~{WL}, если элементами класса WL являются электронные адреса.
В этом случае в правило нужно добавить доменную часть:
R$* $| $~{WL} @dom.ru $@ OK


10 января 2004г..
При внимательном рассмотрении заголовков писем выяснилось, что многие спамеры рассылают спам из одной и той же сетки, но через многие релеи, причем почти каждый раз через разные. При этом инициатор рассылки оказывается в самом последнем из имеющихся в заголовке полей "Received:" и проверке ни через Local_check_mail, ни через Local_relay_check, ни через /etc/mail/access не подлежит. Так как sendmail всегда выясняет доменные имена ip-адресов из всех Received-заголовков, то повторяющиеся из раза в раз доменные имена в заголовках спам-писем всегда бросаются в глаза. Вот их, родимых, можно добавить в специальное преобразование ChHeader для последующей проверки в CheckReceived .
Да, аналогичную проверку делаем и в CheckFrom: как известно, в check_mail проверяется реальный адрес отправителя, а вот адрес, проверяемый CheckFrom может оказаться поддельным: если во время сеанса telnet на этапе DATA набрать:
From: ded_moroz@elki-palki.ru то именно этот адрес отправителя вы увидете в соответствующей строке письма, а не истиный адрес, указанный на этапе MAIL FROM: Исходя из вышеизложенного, не мешает сделать проверку на распространенные спам-домены и в CheckFrom. Или можно проверить переменную $&{currHeader} в CheckHeader.

12 января 2004г.
Ну и последнее на сегодня. Есть файл /etc/mail/access, в который можно вносить IP-адреса, домены и эл. адреса для блокировки. У меня же теперь в этом файле только домены и электронные адреса, а IP-адреса для удобства вынесены в отдельный файл /etc/mail/Denied_IP. Пришло несколько раз спам-письмо с одного и того же IP - в черную базу его, родимого, в базу, а затем запускам команду:
makemap hash Denied_IP < Denied_IP.
При этом перезагружать sendmail не нужно.

29 января 2004г.
Nota Bene 1! Как справиться с MyDoom средствами regex: на странице http://web.abnormal.com/~thogard/sendmail есть патч для regex, который позволяет фильтровать почту по телу письма. Можно использовать специальное преобразование:
Kbodyregex regex -aMyDoom-Virus-Detect TVqQAAMAAAAEAAAA|UEsDBAoAAAAAA
Эта комбинация символов блокирует на этапе smtp-диалога исполняемые файлы и zip-архивы_base64_encoded.
Замечания по поводу использования этой комбинации, а также дополнительные комбинации можно посмотреть здесь .
В regex.mc, выложенном на данной странице, это специальное преобразование не включено.

Март-апрель 2004г.
Как известно, любой человек может присоединиться к smtp-порту вашего почтовика и послать письмо для вашего локального пользователя.
Этим способом рассылки писем часто пользуются спамеры. В таких письмах присутствует один-единственный заголовок "Received:", заполненный вашим почтовиком, через который и произведена рассылка. Этот единственный подзаголовок содержит ip-адрес хоста, с которого произошла рассылка, и он не подлежит проверке через
HReceived:            $>+CheckReceived,
потому что в HReceived: проверяются только промежуточные релеи, т.е. все релеи, начиная с самого первого и заканчивая предпоследним(первый подзаголовок Received: в заголовке письма - это на самом деле подзаголовок, заполненный последним в цепочке релеев почтовым сервером, а последний в заголовке письма "Received:" заполнен самым первым релем). Этот идущий первым Received: подлежит проверке только в check_relay (на предмет ip-адреса источника). А в данном случае анализ адреса релея ничего не даст..
Естественно, возникает вопрос, как такую почту блокировать?
Вооружившись RFC-1123: " ... Every receiver-SMTP (not just one that "accepts a message for relaying or for final delivery" [SMTP:1]) MUST insert a "Received:" line at the beginning of a message... " добавляем набор правил check_eoh, который и осуществляет необходимые нам действия. Блокировка происходит при просмотре заголовков "Received:" если заголовок единственный, и при этом IP не из моей сети, и не было smtp-авторизации, то отлуп.
Как определить, что "Received:" в заголовке письма - единственный? Нужно запомнить текущее состояние "Received:" в наборе правил CheckReceived в переменной {ReceivedCheck}, а в наборе правил check_eoh проверить состояние этой переменной: если она пустая, значит в заголовке письма присутствует единственный подзаголовок "Received:", и такую почту нужно заблокировать, а если переменная непустая, то пропустить письмо.

Сразу выясняется , что масса почтовиков не составляют себе труда вставлять собственные "Received:"-строки, чтов итоге ведет к ложным срабатываниям моего фильтра. Некоторые случаи игнорирования вставки собственных "Received:"-строк:
1) когда на другой стороне стоит Exchange Server, который получает почту от своих локальных клиентов по LDAP, то Exchange отправляет почту, как будто бы он простой почтовый клиент;
2) под ложные срабатывания подпало и большое количество почтовых рассылок, в частности от ambar.mail.ru, и на comp.mail.sendmail мне подсказали, что, возможно, программа-рассыльщик формирует сообщения соответствующим образом и непосредственно помещает их в почтовую очередь, как бы минуя процесс отправки сообщения на локальный почтовик: в таком случае сообщение не "получено" постовиком от почтового клиента , а уже присутствует в почтовой очереди, готовое к отправке. Единственное полезное наблюдение, которое мне удалось сделать при ложных срабатываниях, это то, что правая часть "Message-Id" не моя.
Исходя из вышеизложенного, добавляем в check_eoh еще одну проверку: если к тому, что IP-адрес не из моей сети, smtp-авторизации не было, а тем не менее правая часть "Message-Id" - моя (спец. преобразование ChMId), то такую почту относим к разряду спама.

7.04.2008. Сегодня на sendmail-конфе обнаружила ответ на вопрос "Почему ME не вставляет собственные заголовки Received:"
" ... How is Exchange and GroupWise not RFC compliant
when they are running internal protocols (X.400 for Exchange) that (to
the best of my knowledge) do not have the equivalent of Received:
headers.
In other words, how are they breaking RFC by not adding
something they do not have.
When messages originate internally and go
out to the world, the first header you will see is the first receiving
SMTP server, the one that got it from Exchange / GroupWise. Likewise
the last Received: header you will see on an inbound message is the edge
SMTP gateway. Thus these systems have no way to expose internal structure..."


Март-апрель 2004г.
Не все так просто оказалось с "белыми списками".
1. Сразу возникли проблемы с теми, кто внесен в файл /etc/aliases.
При проверке на принадлежность пользователя "белому списку" используется макрос <$u>. В документации он определен довольно скромно: пользователь-получатель. Однако исследование его с помощью syslog показало интересные факты:
во-первых, этот макрос определен только для локальных пользователей, при этом он выглядит как < user > , а для удаленных пользователей макрос <$u> выглядит как <>. Если послать письмо адресатам user1@remotedomain1.ru; localuser@localdomain.ru, user2@remotedomain2.ru, то макрос <$u> будет выглядеть как < localuser >. Если письмо послано нескольким локальным пользователям, то макрос <$u> будет содержать в себе имя только последнего в списке пользователя.
Во-вторых, для пользователей, прописанных в /etc/aliases, он выглядит так же, как и для удаленных юзеров: <>.
Если использовать правило:
R$* $| < > $@ OK ,
то будет пропускаться без проверки на спам исходящая почта (что хорошо), а также почта для любого "заалиасенного" пользователя, вне зависимости от того, включен этот пользователь в "белый список" или нет.
Если же это правило не включать в набор правил, тогда всегда будет проверяться исходящая почта и почта для всех "заалиасенных" юзеров.
2. Вторая проблема связана со списками рассылок: если в поле "To:" указано несколько получателей, причем один или несколько из них не внесены в "белый список", то спам фильтр сработает для всех пользователей.
Ясно, что почта, посланная 3 различным пользователям одной командой, не может быть обработана трижды.

В данном случае пришлось пойти на такую хитрость: был введен дополнительный макрос D{Spam_Check}1, которому изначально присвоено значение 1.
Также было добавлено новое спец. преобразование
KCheckRcpt1 regex -n -a@NOLIST1 ^<(adm|postmaster|webmaster|hostmaster|etc)@(.*mydomain.ru|\[k\.l\.m\.n\]|\[127\.0\.0\.1\]|localhost|localhost.localdomain)>$
Это список всех юзеров, пожелавших быть защищенными от спама.
А в Local_check_rcpt были добавлены след. правила:
SLocal_check_rcpt
# empty address?
R< > $#error $@ nouser $: "553 User address required"
R$@ $#error $@ nouser $: "553 User address required"
R$+ $: $(CheckRcpt1 $1 $:$1 $) $| $1
R@NOLIST1 $| $+ $: $(storage {Spam_Check} $@ $&{Null_Check} $) $1
R$+ $| $+ $: $2
... То есть, если пользователь не входит в число тех, чья почта фильтруется, то для него макрос{Spam_Check}принимает значение, равное 0, в противном случае значение макроса не менется.
Если имеет место рассылка, то набор правил SLocal_check_rcpt сработает для каждого из локальных клиентов рассылки.
И если хотя бы один из юзеров, упомянутых в поле "To:" , не включен в список CheckRcpt1, то макрос {Spam_Check}принимает значение, равное 0, и почта для всех пользователей не будет проверяться фильтром.
Впоследствии, при проверке различных заголовков, сначала проверяется значение макроса {Spam_Check}: если оно равно 0, то работа набора правил завершается, в противном случае происходит проверка заголовка соотвествующим фильтром:
HSubject: $>Check_Subject
SCheck_Subject
R$* $: $1 $| <$&{Spam_Check}>
R$* $| <0> $@ OK
R$* $| $* $: $1
#R$* $: $(syslog <$&{Spam_Check}> $) $1
R$+ $: $(ChSbSpam $1 $)
R@CATCHED $#error $: 553 Sorry, Your subject looks like SPam. If not, please contact the postmaster@yourdomain.ru with no subject.
...
И еще о макросе $&u. Есть у него одна особенность: если в RCPT TO: определен один пользователь (и он не был переписан, например, вследствие действия /etc/mail/aliases), то именно он будет показан в заголовке, а если пользователей-получателей несколько, либо единственный пользователь-получатель был переписан, то макрос $&u в заголовке просто опускается.
И второе: значение этого макроса определяется только на этапе локальной доставки.

8 апреля 2005г.
Исправлены все ссылки на comp.mail.sendmail (сайт изменил свой доменный адрес).
Добавлена информация о проверке пустого поля в заголовке.
На данной странице не представлены новые спам-проверки, например, проверка на ip-адрес источника, если письмо пришло с локального административного адреса, и проверка на ip-адрес источника рассылки с Городского кота (gluck@subscribe.ru, namma12345@subscribe.ru). Вы можете добавить их самостоятельно.


14. Обратная связь
Страница создана 10 мая 2003г.
Последнее обновление: 8 февраля 2008г.