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


Типовые задачки по sendmail. Часть третья. ([Часть первая]    [Часть вторая]    [Рейтинг])


  • 21. Проверяем $&{client_name} в Local_check_relay.
  • 22. "Лето-2008". Блокируем письма с порно-ссылками.
  • 23. Блокируем письмо, если адрес отправителя начинается с символa |
  • 24. Назначаем каждому срабатыванию по базам dnsbl определенный вес, суммируем все веса, по результатам блокируем или складываем в отдельный ящик.
  • 25. Вам нужна почта с адресов dnevnik@liveinternet.ru ?
  • 26. Блокируем спам, предназначенный тезкам (в полях From: & Cc: несколько одноименных получателей разных доменов).
  • 27. Накладываем дополнительные ограничения на smtp-авторизацию.
  • 28. Как отказаться от проверок в остальных рулсетах, если сработал #error в одном из предыдущих рулсетов (быстрый выход из _всех_ правил).
  • 29. Запрещаем внешнюю почту, подписанную нашим доменом.
  • 30. Вынуждаем локальных клиентов пользоваться только TheBat!
  • 31. Подмена адреса отправителя в транзитной почте.
  • 32. Блокировка почты при нахождении одного и того же шаблона в двух разных Received.
  • 33. Выборочный dnsbl.
  • 34. Как добавить свой заголовок при попадании IP в dnsbl.
  • 35. Оч. мудреная проверка в dnsbl или скрещиваем пп. 33 и 34.
  • 36. Как задать в /etc/mail/access какое угодно число сетей класса С всего двумя строчками.
  • 37. Dnsbl-сервис на основе доменных имен
  • 38. Как запретить определенному пользователю отправлять вложения.
  • 39. Двойные-тройные буквы "j" & "y" .
  • 40. Undelivered Mail Returned to Sender. Соберем для Вас по сети интернет базу данных потенциальных клиентов для Вашего Бизнеса.
  • 41.
  • 42.
  • YY. Оптимизация правил или что бы такого сделать плохого ...
  • ZZ. Что бы еще такого сделать плохого ...




  • 21. Проверяем $&{client_name} в Local_check_relay.
    19.06.2008.
    Как водится, искала инфу совсем по другому вопросу, а наткнулась вот на это: http://www.linux.org.ru/view-message.jsp?msgid=1883116
    Автор - Ej_Pulsar

    #cat _dsl_senders.m4
    -----------cut here---------------------------------------------------------------------------- ---------- 
    divert(-1) 
    divert(0) 
    LOCAL_CONFIG 
    Knondsl1 regex -a@MATCH (^|[0-9.-])(mail|mailrelay|mta|mx|relay|smtp)[0-9.-] 
    Knondsl2 regex -a@MATCH \.(msu\.ru|hotmail\.com|rax\.ru|ip\.net\.ua|secureserver\.net)$ 
    Knondsl3 regex -a@MATCH (243-127-207-82\.ip\.ukrtel\.net)$ 

    Kdsl1 regex -a@MATCH ([0-9].*){5,} 
    Kdsl2 regex -a@MATCH (^|[0-9.-])([axv]dsl|as|bgp|broadband|cable|[ck]lient|dhcp|dial|dialin|dialup|di aler|dip|dsl|dslam|dup|dyn|dynamic|host|ip|isdn|modem|nas|node|pool|ppp|pppo[ae] |sirius.*ukrtel.*|user|users|vpn)[0-9.-] 
    Kdsl3 regex -a@MATCH [0-9a-f]{8,} 
    Kdsl4 regex -a@MATCH (^|\.)[0-9]*[.-] 
    Kdsl5 regex -a@MATCH (-.*){3,} 
    Kdsl6 regex -a@MATCH \.(blueyonder\.co\.uk|orange\.fr|mr\.outblaze\.com|ipt\.aol\.com|free\.fr|volia\ .net|internetdsl\.tpnet\.pl|rr\.com|pppool\.de|adelphia\.net|osnanet\.de|dedicad o\.com\.uy)$ 

    LOCAL_RULESETS 
    SLocal_check_relay 
    R$*                        $: $: < $&{client_resolve} > 
    R<TEMP>                        $: $#error $@ 4.7.1 "450 Relaying temporarily denied. IP name lookup failed for " $&{client_addr} ", To solve this problem please write postmaster@zz.ru" 
    R<FAIL>                        $: $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed for " $&{client_addr} ", To solve this problem please write postmaster@zz.ru" 
    R<FORGED>                        $: $#error $@ 5.7.1 $: "550 Relaying denied. IP name forged (PTR and A records mismatch) for " $&{client_addr} ", To solve this problem please write postmaster@zz.ru" 
    R$*                        $: $: $(nondsl1 $&{client_name} $) 
    R@MATCH                           $@ OK 
    R$*                        $: $: $(nondsl2 $&{client_name} $) 
    R@MATCH             $@ OK 
    R$*                           $: $(nondsl3 $&{client_name} $) 
    R@MATCH                           $@ OK 
    R$*                           $: $(dsl1 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (1), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    R$*                           $: $(dsl2 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (2), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    R$*                           $: $(dsl3 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (3), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    R$*                           $: $(dsl4 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (4), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    R$*                           $: $(dsl5 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (5), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    R$*                           $: $(dsl6 $&{client_name} $) 
    R@MATCH                           $#error $@ 5.7.1 $: "554 DSL or DialUp sender " $&{client_name} " [" $&{client_addr} "] (6), please use Provider SMTP. To solve this problem please write postmaster@zz.ru" 
    -----------cut here---------------------------------------------------------------------------- ---------- 


    22. "Лето-2008". Блокируем письма с порно-ссылками.

    Не знаю, как у вас, а наш почтовый домен засыпали письмами, содержащими порно-рассказы и порно-ссылки. Причем в последнее время в этих росcказнях все чаще упоминаются столь почитаемые простым народом Ксения Анатольевна Собчак и Тимур Ильдарович Юнусов.

    Наш VadeRetro исправно помечает эти сообщения спам-меткой, но мне не по себе от того, что почтенная академическая публика вынуждена лицезреть это безобразие (ведь спам-папки большинство все равно проверяет на предмет ложного срабатывания), поэтому попытаюсь что-то сделать.

    После анализа множества таких писем выявлены характерные поля, они выделены жирным шрифтом.

    Return-Path: <lowndsd@hsd.utc.com>
    Received: from mail.kaf.fo ([59.172.14.48])
             by mail.anrb.ru (8.14.2/8.14.2) with ESMTP id m6J2FIiU003670
             for <adm@anrb.ru>; Sat, 19 Jul 2008 08:15:24 +0600
    Subject: [VR:SPAM:: ]=?windows-1251?B?8e7h9+DqIPLz8iDy7ublIOXx8vw=?=
    Date: 19 Jul 2008 08:48:46 +0700
    MIME-Version: 1.0
    Content-Type: text/plain;
             charset="windows-1251"
    Content-Transfer-Encoding: 8bit
    X-Priority: 3
    X-MimeOLE: Produced By Microsoft Exchange V6.5
    X-SpamTest-Version: SMTP-Filter Version 3.0.0 [0274], KAS30/Release
    X-SpamTest-Info: Not protected
    X-Spam: Not detected
    X-Antivirus: Dr.Web (R) for Unix mail servers drweb plugin ver.4.44.2.0805030
    X-Antivirus-Code: 0x100000
    X-Drweb-SpamState: yes
    X-Drweb-SpamState-Num: 1
    X-Drweb-SpamScore: 200
    X-Drweb-SpamVersion: Vade Retro 01.272.11 AV+AS
    Message-Id: <200807190215.m6J2FIiU003670@mail.anrb.ru>
    Received: from [192.168.41.17] ([192.168.41.17]) by 59.172.14.48 with Microsoft SMTPSVC(6.0.3790.1830)
    19 Jul 2008 08:48:46 +0700
    From: =?windows-1251?B?zeDy4Pjl7fzq4A==?= <lowndsd@hsd.utc.com>
    To: adm@anrb.ru

    Вот с полями X-SpamTest-Version & Received и будет работать мой фильтр.

    LOCAL_CONFIG
    # Макрос for CheckSpamTest & CheckReceived
    D{ST}0

    KChRec1 regex -a@MATCH from(\[192.168.+){2}by.+with.Microsoft.SMTPSVC\(6.0.3790.1830\)
    KSpamTest regex -a@MATCH SMTP-Filter.Version.3.0.0\[0274\]\,KAS30/Release

    LOCAL_RULESETS

    HReceived:                           $>+CheckReceived
    SCheckReceived
    # Дублируем входные данные (содержимое всех полей Received)
    R$*                           $: $1 $| $1         
    # Проверяем Received на наличие запретных данных
    R$* $| $*                  $: $(ChRec1 $1 $) $| $2
    # В случае совпадения сохраням в макросе ST значение 1
    R@MATCH $| $*                  $: $(storage {ST} $@ 1 $) @MATCH $| $1
    # И выводим в лог содержимое Received для контроля
    R@MATCH $| $*                  $: $(syslog syslog:Rec0: $1 $) $1

    HX-SpamTest-Version:                           $>CheckSpamTest
    SCheckSpamTest
    # Входные данные - содержимое поля X-SpamTest-Version. Добавляем значение макроса ST.
    R$*                           $: <$&{ST}> $1
    # Если в Received содержались запретные данные, то проверяем поле
    # X-SpamTest-Version: на наличие SMTP-Filter.Version.3.0.0[0274],KAS30/Release
    R<1> $*                           $: $(SpamTest $1 $) $1
    # Да - выводим исходные данные в лог
    R@MATCH $*                  $: $(syslog syslog:CST0: <$&{ST}>-$1 $) @MATCH
    # И блокируем сообщение
    R@MATCH                           $#error $: "554 Sorry, probably spam message."

    В среднем от 1000 до 5500 блокировок в день. Хотя кое-кто меня не понял, и потребовал вернуть все на место ...
    P.S. 13.11.2008. Для интереса попробуйте сделать
    egrep "SMTP-Filter Version 3.0.0 \[0274\], KAS30/Release" /var/spool/mail/*
    P.S. 25.12.2008. Уже неделя, как неактуально.

    23. Блокируем письмо, если адрес отправителя начинается с символa |

    Вообще-то решение полностью аналогично пункту 13.
    Проверка действует с 24.06.2008. Имеем от 6 тысяч до 16 тысяч срабатываний в день.
    LOCAL_CONFIG
    KSPA3 regex -a@MATCH ^\|
    LOCAL_RULESETS
    SLocal_check_mail
    R$*                                    $: $>3 $1
    R$+<@$+>                            $: $(SPA3 $1 $: $)
    R@MATCH                            $#error $: 554 Sorry, Your e-mail address looks like SPAM. If not, please contact the postmaster@domain.ru via another e-mail address.

    Но мне случайно встретилось объяснение того, откуда взялся такой спам:
    "...Это у них бага такая, они про нее пока не знают, где-то емейлы поперли, а там они были разделены |, вот это и попало в их базу А так как фромы они берут из своей же базы, то имеем что имеем... посему пока по этому признаку срубается очень весомое количество спама. А так как базы они не чистят, то наварное оно будет долго маячить..."
    А еще там же очень понравилось это высказывание: "... Вообще, чем больше медитируешь над логами, тем лучше настраиваешь сервер. Это для любого почтового сервера справедливо..."
    P.S. 25.12.2008. Неактуально.


    24. Назначаем каждому срабатыванию по базам dnsbl определенный вес, суммируем все значения, по результатам блокируем или складываем в отдельный ящик
    02.10.2008.
    24.1. Решение.
    24.2.Логи.
    24.3.Замечания.

    24.1. Решение.
    Убираем из sendmail.mc все строки вида
    FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}')

    Добавляем в sendmail.mc

    LOCAL_CONFIG
    Ksyslog syslog
    Kstorage macro
    Kcomp arith

    # map for DNS based blacklist lookups
    Kdnsbl dns -R A -T<TMP>
    # Начальный спам-вес письма
    D{Weight}0
    # Пороговый спам-вес письма
    D{Max_Weight}4

    LOCAL_RULESETS

    SLocal_check_relay
    R$*                  $: <$&{client_addr}>
    # For some cases
    R<>                  $@ OK
    # Strip angle brackets
    R<$+>                   $: $1
    # Local originated mail
    R127.0.0.1                  $@ OK
    # Is this user send the mail from local net ($=R or RELAY in access or from CONNECT:nets)?
    # Checking for local net
    R$=R                            $@ OK
    R$-.$-.$-.$-                   $: $(access $1.$2.$3.$4 $:$1.$2.$3 $)
    RRELAY                           $@ OK
    R$-.$-.$-                  $: $(access $1.$2.$3 $:$1.$2 $)
    RRELAY                           $@ OK
    R$-.$-                           $: $(access $1.$2 $)
    RRELAY                           $@ OK

    # Ip-adddress will be modified after previous access-check so
    # let us return original ip with CONNECT: tag in the work space:
    R$*                                    $: CONNECT:$&{client_addr}
    # Checking for tag CONNECT:
    RCONNECT:$-.$-.$-.$-                   $: $(access CONNECT:$1.$2.$3.$4 $:CONNECT:$1.$2.$3 $)
    ROK                                    $@ OK
    RCONNECT:$-.$-.$-                   $: $(access CONNECT:$1.$2.$3 $:CONNECT:$1.$2 $)
    ROK                                    $@ OK
    RCONNECT:$-.$-                           $: $(access CONNECT:$1.$2 $)
    ROK                                    $@ OK

    После предыдущих манипуляций IP адрес будет видоизменен, поэтому вернем его в рабочую область в первозданном виде:
    R$*                  $: <$&{client_addr}>
    # DNS based IP address spam list bl.spamcop.net
    # Делаем запрос в dnsbl:
    R<$-.$-.$-.$->                  $: <$(dnsbl $4.$3.$2.$1.bl.spamcop.net. $: OK $)>
    R$*                           $: $(syslog syslog:21:spamcop: $1 $) $1
    # IP не числится в черной базе - продолжаем
    R<OK>                           $: CONTINUE
    # Во время обращения к черной базе произошел сбой - пропускаем
    R<$+<TMP>>                  $: CONTINUE
    # Любой другой результат говорит нам о том, что IP в черную базу.
    # Поэтому увеличиваем спам-вес письма на 3
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 3 $)>
    # Сохраняем результат суммирования в макросе
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:22:spamcop: $1 $) $1
    # Сравниваем полученный спам-вес с пороговым значением
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:23:spamcop: $1 $) $1
    # Если первый больше или равен второму - запрещаем письмо
    RFALSE                           $#error $@ 5.7.1 $: Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}
    # Нет - продолжаем
    R$*                           $: $(syslog syslog:24: $1 $) $1

    # В результате предудущих операций Ip-адрес потеряется,
    # поэтому возвращаем его в рабочую область
    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list cbl.abuseat.org
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.cbl.abuseat.org. $: OK $)>
    R$+                           $: $(syslog syslog:31:abuseat: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 2 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:32:abuseat: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:33:abuseat: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see cbl.abuseat.org
    R$*                           $: $(syslog syslog:34: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list zen.spamhaus.org
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.zen.spamhaus.org. $: OK $)>
    R$+                           $: $(syslog syslog:41:spamhaus: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 2 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:42:spamhaus: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:43:spamhaus: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see zen.spamhaus.org
    R$*                           $: $(syslog syslog:44: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list dul.ru
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.dul.ru. $: OK $)>
    R$+                           $: $(syslog syslog:51:dul: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 1 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:52:dul: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:53:dul: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Use mail relays of your ISP.
    R$*                           $: $(syslog syslog:54: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list sorbs.ru
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.dnsbl.sorbs.net. $: OK $)>
    R$+                           $: $(syslog syslog:61:sorbs: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 1 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:62:sorbs: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:63:sorbs: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see dnsbl.sorbs.net
    R$*                           $: $(syslog syslog:64: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list dnsbl.njabl.org
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.dnsbl.njabl.org. $: OK $)>
    R$+                           $: $(syslog syslog:71:njabl: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 1 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:72:njabl: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:73:njabl: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see dnsbl.njabl.org
    R$*                           $: $(syslog syslog:74: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list list.dsbl.org
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.list.dsbl.org. $: OK $)>
    R$+                           $: $(syslog syslog:81:dsbl: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 3 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:82:dsbl: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:83:dsbl: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Spam blocked (list) - see http://www.dsbl.org/
    R$*                           $: $(syslog syslog:84: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list multihop.dsbl.org
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.multihop.dsbl.org. $: OK $)>
    R$+                           $: $(syslog syslog:91:mh.dsbl: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 1 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:92:mh.dsbl: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:93:mh.dsbl: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Spam blocked (multihop) - see http://www.dsbl.org/
    R$*                           $: $(syslog syslog:94: $1 $) $1

    R$*                                    $: $&{client_addr}
    # DNS based IP address spam list mail-abuse.ru
    R$-.$-.$-.$-                  $: <$(dnsbl $4.$3.$2.$1.blackholes.mail-abuse.org. $: OK $)>
    R$+                           $: $(syslog syslog:101:mail-abuse: $1 $) $1
    R<OK>                           $: CONTINUE
    R<$+<TMP>>                  $: CONTINUE
    R<$+>                           $: <$(arith + $@ $&{Weight} $@ 1 $)>
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:102:mail-abuse: $1 $) $1
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:103:mail-abuse: $1 $) $1
    RFALSE                           $#error $@ 5.7.1 $: Mail from " $&{client_addr} "rejected, see http://mail-abuse.org/cgi-bin/lookup?" $&{client_addr}'.

    # Если спам-вес письма так и не набрал максимальное значение,
    # возвращаемся в точку вызова (check_relay), напоследок выдав последнее
    # значение из рабочей области и итоговый спам-вес письма
    R$*                           $: $(syslog syslog:END: $1-$&{Weight} $) $1


    24.2. Логи.
    -----------------
    # Пороговый спам-вес письма
    D{Max_Weight}4
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:00:gw.pilot.nid.ru\23379.133.87.211.-.0
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:21:spamcop:<127.0.0.2>
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:22:spamcop:<3>
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:23:spamcop:TRUE
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:24:TRUE
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:31:abuseat:<127.0.0.2>
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:32:abuseat:<5>
    Oct 2 14:16:08 apache sendmail[24989]: m928G8d1024989: syslog:33:abuseat:FALSE
    Oct 2 14:16:08 apache sendmail[24989]: ruleset=check_relay, arg1=gw.pilot.nid.ru, arg2=127.0.0.2, relay=gw.pilot.nid.ru [79.133.87.211], reject=553 5.3.0 Mail from 79.133.87.211 rejected - see cbl.abuseat.org
    -------
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:00:[124.106.138.138]\233124.106.138.138.-.0
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:21:spamcop:<OK>
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:22:spamcop:CONTINUE
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:23:spamcop:CONTINUE
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:24:CONTINUE
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:31:abuseat:<127.0.0.2>
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:32:abuseat:<2>
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:33:abuseat:TRUE
    Oct 2 14:20:38 apache sendmail[25692]: m928KcBE025692: syslog:34:TRUE
    Oct 2 14:20:39 apache sendmail[25692]: m928KcBE025692: syslog:41:spamhaus:<127.0.0.11>
    Oct 2 14:20:39 apache sendmail[25692]: m928KcBE025692: syslog:42:spamhaus:<4>
    Oct 2 14:20:39 apache sendmail[25692]: m928KcBE025692: syslog:43:spamhaus:FALSE
    Oct 2 14:20:39 apache sendmail[25692]: ruleset=check_relay, arg1=[124.106.138.138], arg2=127.0.0.11, relay=[124.106.138.138], reject=553 5.3.0 Mail from 124.106.138.138 rejected - see zen.spamhaus.org
    -------

    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:00:ppp85-141-123-152.pppoe.mtu-net.ru\23385.141.123.152.-.0
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:21:spamcop:<OK>
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:22:spamcop:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:23:spamcop:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:24:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:31:abuseat:<OK>
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:32:abuseat:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:33:abuseat:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:34:CONTINUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:41:spamhaus:<127.0.0.11>
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:42:spamhaus:<2>
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:43:spamhaus:TRUE
    Oct 2 14:24:11 apache sendmail[26221]: m928OBw9026221: syslog:44:TRUE
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:51:dul:<127.0.0.3>
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:52:dul:<3>
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:53:dul:TRUE
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:54:TRUE
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:61:sorbs:<127.0.0.10>
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:62:sorbs:<4>
    Oct 2 14:24:12 apache sendmail[26221]: m928OBw9026221: syslog:63:sorbs:FALSE
    Oct 2 14:24:12 apache sendmail[26221]: ruleset=check_relay, arg1=ppp85-141-123-152.pppoe.mtu-net.ru, arg2=127.0.0.10, relay=ppp85-141-123-152.pppoe.mtu-net.ru [85.141.123.152], reject=553 5.3.0 Mail from 85.141.123.152 rejected - see dnsbl.sorbs.net
    -------

    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:00:[89.20.20.159]\23389.20.20.159.-.0
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:21:spamcop:<OK>
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:22:spamcop:CONTINUE
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:23:spamcop:CONTINUE
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:24:CONTINUE
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:31:abuseat:<OK>
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:32:abuseat:CONTINUE
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:33:abuseat:CONTINUE
    Oct 2 14:33:14 apache sendmail[27325]: m928XE71027325: syslog:34:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:41:spamhaus:<127.0.0.11>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:42:spamhaus:<2>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:43:spamhaus:TRUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:44:TRUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:51:dul:<OK>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:52:dul:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:53:dul:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:54:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:61:sorbs:<OK>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:62:sorbs:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:63:sorbs:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:64:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:71:njabl:<OK>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:72:njabl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:73:njabl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:74:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:81:dsbl:<OK>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:82:dsbl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:83:dsbl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:84:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:91:mh.dsbl:<OK>
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:92:mh.dsbl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:93:mh.dsbl:CONTINUE
    Oct 2 14:33:15 apache sendmail[27325]: m928XE71027325: syslog:94:CONTINUE
    Oct 2 14:33:16 apache sendmail[27325]: m928XE71027325: syslog:101:mail-abuse:<OK>
    Oct 2 14:33:16 apache sendmail[27325]: m928XE71027325: syslog:102:mail-abuse:CONTINUE
    Oct 2 14:33:16 apache sendmail[27325]: m928XE71027325: syslog:103:mail-abuse:CONTINUE
    Oct 2 14:33:16 apache sendmail[27325]: m928XE71027325: syslog:END:CONTINUE.-.2
    Oct 2 14:33:26 apache sendmail[27325]: m928XE71027325: from=<tapaswen_mei@total.com>, size=10073, class=0, nrcpts=1, msgid=<000601c9246c$05dd2f78$b05baa82@tkvgy>, proto=ESMTP, daemon=MTA, relay=[89.20.20.159]
    Oct 2 14:33:27 apache sendmail[27337]: m928XE71027325: to=<paradise@anrb.ru>, delay=00:00:08, xdelay=00:00:01, mailer=smtp, pri=130073, relay=mail.anrb.ru. [212.193.134.2], dsn=2.0.0, stat=Sent (m928vIUU007265 Message accepted for delivery)
    -------

    # Пороговый спам-вес письма
    D{Max_Weight}9
    /var/log/maillog:
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:00:[190.48.198.190]\233190.48.198.190.-.0
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:21:spamcop:<127.0.0.2>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:22:spamcop:<3>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:23:spamcop:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:24:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:31:abuseat:<127.0.0.2>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:32:abuseat:<5>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:33:abuseat:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:34:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:41:spamhaus:<127.0.0.11>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:42:spamhaus:<7>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:43:spamhaus:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:44:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:51:dul:<OK>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:52:dul:CONTINUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:53:dul:CONTINUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:54:CONTINUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:61:sorbs:<127.0.0.10>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:62:sorbs:<8>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:63:sorbs:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:64:TRUE
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:71:njabl:<127.0.0.9>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:72:njabl:<9>
    Oct 2 14:02:15 apache sendmail[19134]: m9282FLq019134: syslog:73:njabl:FALSE
    Oct 2 14:02:15 apache sendmail[19134]: ruleset=check_relay, arg1=[190.48.198.190], arg2=127.0.0.9, relay=[190.48.198.190], reject=553 5.3.0 Mail from 190.48.198.190 rejected - see dnsbl.njabl.org
    -------

    24.3. Замечания.
    1. Данное решение тестировалось 2 дня на транзитном релее. Ежедневно на нем средствами sendmail.mc блокируется 80-120 тыс. соединений. На основной почтовик отсылается всего 500-800 сообщений, редко - около 1000.
    2. В стандартом режиме я использую 6 dnsbl:
    FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}')
    FEATURE(`dnsbl',`list.dsbl.org', `Spam blocked (list) - see http://www.dsbl.org/')
    FEATURE(dnsbl, `cbl.abuseat.org', `"550 Mail from " $&{client_addr} " rejected - see cbl.abuseat.org"')
    FEATURE(dnsbl, `zen.spamhaus.org', `"550 Mail from " $&{client_addr} " rejected - see zen.spamhaus.org"')
    FEATURE(dnsbl, `dnsbl.sorbs.net', `"550 Mail from " $&{client_addr} " rejected - see dnsbl.sorbs.net"')
    FEATURE(dnsbl, `dnsbl.njabl.org', `"550 Mail from " $&{client_addr} " rejected - see dnsbl.njabl.org"')
    В данный рулсет включено 9 dnsbl искл-но для эксперимента.
    Базы расположены в порядке убывания количества срабатываний по моей статистике.
    Спам-вес каждому срабатыванию назначен также исходя из статистики ложных срабатываний.
    Незнакомым мне базам назначен вес 1.
    3. Если задуматься, то количество дополнительных запросов к dnsbl впечатляет и и напрягает. Тут нужно думать.
    4. В идеале мне бы хотелось вместо этого рулсета иметь такую же возможность через все тот же
    FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}')
    То есть хотелось бы обойтись все теми же 6 строками FEATURE, только немного измененными.
    В новом варианте эта фича должна включать в себя еще один аргумент - спам-вес именно этого срабатывания:
    FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}', `3')
    Тогда мои навороты через Local_check_relay будут не нужны. Над этим я думаю, хотя, конечно же, редактировать напрямую оригинальные m4-файлы - дурной тон.
    5. Учитывая "тяжеловесность" данного Local_check_relay по кол-ву проделываемой работы, можно отложить эту проверку до, скажем, check_eoh c тем, чтобы предыдущие спам-проверки позволили блокировать письмо раньше, чем дойдет очередь до "черных" баз. Но это будет иметь смысл только в том случае, если первые проверки по количеству срабатываний не уступают dnsbl-check. А это как раз не мой случай: 90% блокировок - check_relay'ного происхождения:

    Time    relay   mail    rcpt   From Subj To  ID  Received Head eoh  Total 

    04:13   115170   5735   1758   81   1   0   0   205   0   232   *123182*   25Sep
    04:12   119317   5592   1308   44   0   0   0   149   0   88   *126498*   26Sep
    04:12   97087   4608   1937   68   3   0   0   486   0   114   *104303*   27Sep
    04:12   31100   2033   3305   135   13   0   0   6   0   134   36726   28Sep
    04:12   36133   1701   372   24   2   0   0   0   0   33   38265   29Sep
    04:12   94009   3627   1381   54   6   0   0   318   0   70   99465   30Sep
    04:12   81060   3223   1100   48   1   0   0   403   0   96   85931   01Oct
    04:12   71181   3363   2273   80   2   0   0   314   0   166   77379   02Oct

    6. Однако, если все же использовать эту проверку в check_eoh, то ее можно дополнить проверкой макросов $&{nrcpts}(количество реальных получателей письма) и $&{nbadrcpts}(количество несуществующих получателей письм)
    R$*                           $: $(arith l $@ $&{nrcpts} $@ 3 $)
    RFALSE                           $: FALSE <$(arith + $@ $&{Weight} $@ 1 $)>
    RFALSE<$*>                  $: $(storage {Weight} $@ $1 $) $1
    R$*                           $: $(syslog syslog:02: $&{nrcpts}-$&{Weight} $) $1

    R$*                           $: $(arith l $@ $&{nbadrcpts} $@ 2 $)
    RFALSE                           $: FALSE <$(arith + $@ $&{Weight} $@ 1 $)>
    RFALSE<$*>                  $: $(storage {Weight} $@ $1 $) $1
    R$*                           $: $(syslog syslog:03: $&{nbadrcpts}-$&{Weight} $) $1

    Не знаю, как для вас, а для меня письмо с подозрительного релея да еще отправленное более чем 2 живым получателям да еще паре-тройке несуществующих получателей - однозначный спам. Я уже делаю такую похожую проверку, правда, подозрительность релея определяется по наличию в $&{client_name} следующих шаблонов:
    KSPAM7 regex -a@MATCH [0-9]+[._-]+[0-9]+[._-]+[0-9]+.+\[.+\]
    KSPAM8 regex -a@MATCH ppp|customer|dhcp|dial|cable|modem|adsl|dynamic|[.]dyn[.]
    Письмо блокируется, если кол-во получателей такого письма больше 2.
    По этому признаку происходит 500-2000 блокировок, причем кол-во неполученных писем колеблется от 4000 до 15000.
    В случае с определением количества несуществующих пользователей, ежедневно происходит от 1000 до 5000 блокировок, причем кол-во неполученных писем колеблется от 10000 до 16000.
    7. Необходимо также добавить проверку $&{client} на принадлежность классу w, на RELAY & CONNECT в access, чтобы не проверять локальные адреса и адреса-исключения.
    Этот блок готов и будет выложен.
    14/10/2008. Сделано.
    8.Мне не нравится, что в отлупе содержится ссылка на последний сработавший dnsbl. А хотелось бы, чтобы в ответе сервера указывались 2-3 сработавших dnsbl. Чтобы отправитель понял, в какую плохую историю он попал. Думаю над этим.
    9. Вариант не блокировки, а перекладывания dnsbl-почты в отдельной ящик, дописывается. Основа - здесь.
    10. Комментарии, замечания и предложения именно по этой теме можно направлять прямо постмастеру этого домена.
    NB! Результат мне очень интересен!
    11.10.10.2008. Однако "DSBL is GONE and highly unlikely to return. Please remove it from your mail server configuration."
    Информация от 09/29/2008.
    В мае 2008 на главное странице было опубликовано такое сообщение:
    Database lost - list empty
    Thu, 06/05/2008 - 21:34 — riel
    It looks like the database can not be recovered from the old hard disks - both disks in the RAID1 array are totally broken.
    Очень жаль :(
    12.12.10.2008. Думаю, что имеет смысл изменить последовательность проверок в случае со spamcop-базой и ей подобным. Так как количество проверок в этой базе, имеющих с положительный результат (127.0.0.X), традиционно велико, то будет правильнее сначала проверить результат именно на 127.0.0.X, а затем уже на остальные возможные ответы.
    SLocal_check_relay
    Подаем на вход
    R$*               $: $&{client_addr}
    # For some cases
    R<>              $@ OK

    # DNS based IP address spam list bl.spamcop.net
    # Делаем запрос в dnsbl:
    R$-.$-.$-.$-                  $: $(dnsbl $4.$3.$2.$1.bl.spamcop.net. $: OK $)
    R$*                           $: $(syslog syslog:21:spamcop: $1 $) $1
    # Если IP-АДРЕС ЧИСЛИТСЯ В SPAMCOP-Базе, т.е возвращено значение 127.0.0.X, то
    # увеличиваем спам-вес письма на 3, при этом обрамляем результат угловыми скобками (мы ведь должны как-то отделить те случаи, когда проверка в dnsbl вернула результаты OK (IP отсутствует в базе) и TMP (временная ошибка))
    R127.0.0.$+                           $: <$(arith + $@ $&{Weight} $@ 3 $)>
    # Сохраняем результат суммирования в макросе
    R<$*>                           $: $(storage {Weight} $@ $1 $) <$1>
    R$*                           $: $(syslog syslog:22:spamcop: $1 $) $1
    # Сравниваем полученный спам-вес с пороговым значением
    R<$*>                           $: $(arith l $@ $&{Weight} $@ $&{Max_Weight} $)
    R$*                           $: $(syslog syslog:23:spamcop: $1 $) $1
    # Если первый больше или равен второму - запрещаем письмо
    RFALSE                           $#error $@ 5.7.1 $: Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}
    # Нет - продолжаем
    R$*                           $: $(syslog syslog:24: $1 $) $1
    Последующие 2 правила относятся к тем случаям, когда IP оказался "чистым" или когда в процессе проверки произошел сбой.
    Так как они замыкают текущий блок, после которого мы должны снова вернуть в рабочую область (т.е подать на вход) IP адрес для очередной проверки, и так как они всего лишь говорят, что мы должны продолжить проверять IP, то вообще нет никакой необходимости их исполнять. За счет этого такой вариант проверки IP в наиболее наполненной черной базе короче на 2 правила и, следовательно, рациональнее.
    Еще раз повторю: теперь эти два правила не нужны :
    # IP не числится в черной базе - продолжаем
    ROK                           $: CONTINUE
    # Во время обращения к черной базе произошел сбой - пропускаем
    R$+<TMP>                  $: CONTINUE
    13. 14.10.2008.
    Это решение можно дополнить следующими возможностями:
    - на этапе Local_check_mail: обработка списка исключений для e-mail адресов отправителей (т.е. если отправитель указан в некоем файле, то письмо сразу пропускать);
    - на этапе Local_check_rcpt: обработка списка получателей, чью почту (не)следует проверять на принадлежность IP релея к dnsbl.
    - и еще можно добавить много-много чего интересного, было бы желание ...


    25. Вам нужна почта с адресов dnevnik@liveinternet.ru ?
    06.10.2008.
    Конечно, ничто мне не мешает запретить эту почту в /etc/mail/access. Но при анализе заголовков таких писем обнаружилось поле Message-ID одного и того же формата (письмо предназначалось пользователю paradise@anrb.ru):
    paradise-Message-ID: < 1227059261.899=21=paradise$anrb.ru@host107.rax.ru >
    И мне захотелось этим воспользоваться просто для эксперимента.

    LOCAL_CONFIG
    KLiveInt regex -a@MATCH [0-9]{10}.[0-9]{3}=[0-9]{2}=.+anrb.ru@host[0-9]{3}.rax.ru
    LOCAL_RULESETS
    SCheckMessageID
    R< $+ >                     $: $(LiveInt $1 $)
    R@MATCH                     $#error $: "554 Message from liveinternet.ru is rejected.

    Заголовок такого письма (VadeRetro не посчитал, что это спам)

    From dnevnik@liveinternet.ru Mon Oct 6 11:55:38 2008
    Return-Path: < dnevnik@liveinternet.ru >
    Received: from ppp91-78-93-13.pppoe.mtu-net.ru (ppp91-78-93-13.pppoe.mtu-net.ru [91.78.93.13])
                 by mail.anrb.ru (8.14.2/8.14.2) with ESMTP id m965tVBL008012
                 for < paradise@anrb.ru >; Mon, 6 Oct 2008 11:55:36 +0600
    Message-ID: < 1227059261.899=21=paradise$anrb.ru@host107.rax.ru >
    To: < paradise@anrb.ru >
    From: =?iso-8859-1?B?5dfBIOHLyc3V28vJzsE=?= < dnevnik@liveinternet.ru >
    Subject:
    Date: Mon, 06 Oct 2008 03:58:28 +0000
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
                 boundary="----=_NextPart_000_0002_01C92776.054A88CC"
    X-Drweb-SpamState: no
    X-Drweb-SpamState-Num: 0
    X-Drweb-SpamScore: 10
    X-Drweb-SpamVersion: Vade Retro 01.274.16 AV+AS
    X-Antivirus: Dr.Web (R) for Unix mail servers drweb plugin ver.4.44.2.0805030
    X-Antivirus-Code: 0x100000
    P.S.25.12.2008. Неактуально.


    26. Блокируем спам, предназначенный тезкам (в полях From: & Cc: несколько одноименных получателей разных доменов)
    14.10.2008.
    Часть заголовка такого письма:
    From: "Maureen TAGGART"
    To: diana@altumtvix.ru, diana@alotechnic.ru, diana@alpha-omega.mega.ru, diana@ametruist.ru
    CC: diana@antibiology.ru, diana@an__rb.ru, diana@amoitaly.ru, diana@anacadmium.ru,
                 < diana@ancaeshe.spb.ru >, < diana@anneta-lisetta-julietta.ru >, < diana@amor-amir-amur.ru >
    (я малость похулиганила с первоначальными названиями доменов, чтобы не засвечивать адреса ни в чем не повинных Диан)
    MIME-Version: 1.0
    Content-Type: text/plain; charset=KOI8-R
    Content-Transfer-Encoding: base64
    Content-Disposition: inline
    X-Spam-Ystatus: hits= 3.00
    X-Spam-Flag: NO

    X-Spam-Yversion: Spamooborona-2.1.0

    Как видите, Спамооборона не посчитала это письмо спамом, хотя там было написано такое !!!

    LOCAL_CONFIG
    KTezka regex -a@MATCH (diana@a.+[.].+){2,}
    LOCAL_RULESETS
    HTo:             $>CheckTo
    HCc:             $>CheckTo
    SCheckTo
    R$+            $: $(Tezka $1 $)
    R@MATCH            $#error $: "Sorry, this message looks like spam. If not please contact to postmaster@somedomain.ru."

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


    27. Накладываем дополнительные ограничения на smtp-авторизацию.

    25.10.2008. Будете надо мной смеятся, и, наверное, правильно сделаете: недавно через мой сервер прокачали спам. Прилично так прокачали. Был подобран пароль к одному из ящиков. Попытки перебора я видела, но то ли не придала этому большого значения, то ли просто сразу не проверила логи на предмет того, кто подбирает пароль (может сам юзер забыл пароль), а потом элементарно об этом забыла ...
    В общем, ружье, висевшее на стене в первом акте (многочисленные неудачные попытки авторизации), как и полагается, выстрелило в четвертом - мой сервер попал на пару дней в spamcop ...
    Почти 2 недели прошло в тяжких раздумьях о том, как этому противостоять.
    Для начала взялась за скрипт, обнаруживающий попытки перебора и определяющий IP адрес с предположительным дальнейшим блокированием. Но тут, оказалось, не все просто - точно IP определить не всегда удается. Поэтому, пока работа над скриптом продолжается, мне захотелось сделать самое простое, что в моих силах - заблокировать подозрительные попытки отправки сообщений посредством smtp-авторизации.

    LOCAL_CONFIG
    F{Smtp_Auth}/etc/mail/smtp_auth_users
    LOCAL_RULESETS
    HSubject:               $>Check_Subject
    SCheck_Subject
    R$*               $: $(storage {Subject} $@ $1 $) $1

    Scheck_eoh
    ### Auth check is begining ...
    #R$*               $: $(syslog syslog:Subject:auth:0 $1 $) $1
    1.R$*               $: < $&{auth_authen} >
    #R$*               $: $(syslog syslog:Subject:auth:1 $1 $) $1
    # Do not check for mail legitimacy if it is not smtp-authenticated mail
    2.R< >               $: CONTINUE
    3.R< $+ >               $: < $1 >< $&{client_addr} >
    #R$*               $: $(syslog syslog:Subject:auth:2 $1 $) $1
    # Do not check if it is smtp-authenticated mail from local nets
    4.R< $+ >< $=R $* >               $@ OK
    5.R< $+ >< $+ >               $: < $1 >< $&{client_name} >
    R$*               $: $(syslog syslog:Subject:auth:3 $1 $) $1
    # Block if it is smtp-authenticated mail from very suspicious net (Hello, my dear user! What are you guys doing over there?)
    6.R< $+ >< $* hinet.net >               $#error $: 554 $&f2 " Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.asianet.$+>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.earthlink.$+>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.steephost.$+>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.ttnet.net.tr>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.verizon.$+>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.pacbell.$+>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.ress.rr.com>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.chello.net>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>
    R<$+><$+.mtu-net.ru>                           $#error $: 554 $&f 2" Who are you? My users can not be in this net " <$&{client_name}>

    #Do not check if it is smtp-authenticated mail from registered users
    7.R< $+ >< $+ >               $: < $&{auth_authen} >
    #R$*               $: $(syslog syslog:Subject:auth:4 $1 $) $1
    8.R<$={Smtp_Auth}>               $@ OK
    9.R< $={Smtp_Auth}@anrb.ru >               $@ OK

    10.R< $+ >               $: < $1 >< $&{Subject} >
    R$*               $: $(syslog syslog:Subject:auth:5 $1 $) $1
    11.R< $+ >< SECRET WORD $* >               $@ OK
    12.R< $+ >< $* >               $#error $: 554 $&f" Smtp-authorization is restricted. Please see for details http://www.anrb.ru/ic/abonent.html\#6.1"
    13.R< $+ >< >               $#error $: 554 $&f "2. Smtp-authorization is restricted. Please see for details http://www.anrb.ru/ic/abonent.html\#6.1"
    #R$*               $: $(syslog syslog:Subject:auth:6 $1 $) $1
    # Clear the macro {Subject} for the next message
    14.R$*               $: $(storage {Subject} $) $1
    ### Auth check has been done.

    Пояснения.
    Я использую метод shadow для smtp-авторизации. На самом деле ею пользуются от силы 15 процентов юзеров. Значит, нет никакой необходимости разрешать smtp-авторизацию всем. Ограничив число пользователей smtp-auth, я тем самым ограничу возможность рассылки спама через мой почтовик вследствие подбора пароля. Конечно, можно было изменить метод на userdb и внести в базу только тех, кому авторизация действительно необходима. Но представив сколько времени это займет, я предпочла пойти другим путем: юзеру, использовавшему smtp-авторизацию, сделать несколько проверок дополнительных параметров в рулсете check_eoh.
    Поскольку в качестве дополнительного ограничителя используется тема письма, то сначала я сохраняю ее в наборе Check_Subject. Почему бы тогда не сделать проверку прямо в SCheck_Subject? А потому, что, если тема отсутствует, то этот набор правил не будет вызван и письмо проскочит.
    Поэтому я сделаю эту проверку в самом последнем рулсете, который нам подвластен - check_eoh.

    1. Итак, вызываем макрос < $&{auth_authen} >, он содержит имя, под которым авторизуется юзер.
    2. Если юзер не использовал smtp-auth, то пропускаем письмо дальше. Я использую для этого маркер CONTINUE, потому что мой рабочий check_eoh довольно обширный, и после этой проверки последуют другие, которые данные юзер должен пройти. Если у вас в check_eoh нет других проверок, то вы можете заменить $: CONTINUE на $@ OK.
    3-4. Далее подаем на вход макрос < $&{client_addr} > - IP юзера. Если он из локальной сети - пропускаем письмо (выходим из check_eoh). Да, зачем-то большая часть smtp-auth-юзеров работает именно из локальной сети. Интересно, зачем им авторизация?
    5-6. Далее подаем на вход доменное имя, соответствующее IP юзера. Если вдруг в нем окажутся совершенно невероятные для вас домены - блокируем. Именно с домена hinet.net я наблюдаю большое количество попыток подбора пароля.
    Oct 28 02:06:57 mail sendmail[6304]: m9RL6VdO006304: 114-44-143-72.dynamic.hinet.net [114.44.143.72]: possible SMTP attack: command=AUTH, count=3
    Мой ответ Чемберлену:
    # BL 18.11.08 asianet
    iptables -A INPUT -s 81.223.156.0/24 -d U.F.A.RB -j DROP

    # BL 17.11.08 asianet
    iptables -A INPUT -s 119.46.0.0/16 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 124.120.0.0/18 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 202.93.60.0/22 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 203.144.128.0/17 -d U.F.A.RB -j DROP

    # BL 17.11.08 hinet
    iptables -A INPUT -s 59.112.0.0/12 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 60.250.0.0/15 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 114.136.0.0/15 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 122.120.0.0/13 -d U.F.A.RB -j DROP

    # BL 14.11.08 asianet
    iptables -A INPUT -s 210.86.192.0/19 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 210.213.0.0/18 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 202.176.64.0/18 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 58.97.0.0/18 -d U.F.A.RB -j DROP

    # BL 14.11.08 hinet.net
    iptables -A INPUT -s 118.160.0.0/12 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 218.160.0.0/12 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 125.224.0.0/13 -d U.F.A.RB -j DROP
    iptables -A INPUT -s 59.124.0.0/14 -d U.F.A.RB -j DROP

    7-9. Далее оставляем в рабочей области только макрос < $&{auth_authen} >, и проверяем, прошел ли он регистрацию.
    Что означает регистрация?
    1. Когда я задумала этот рулсет, я сначала собрала по логам имена всех клиентов, которые работали c использованием smtp-auth последнюю неделю. Ес-но, при этом обращала внимание на то, из чьих сетей работали юзеры и высылали ли при этом подозрительную почту.
    2. Запустив этот рулсет в работу, я ежеминутным крон-скриптом проверяла все неудачные попытки использовать smtp-auth, анализировала по логам адекватность отправителя (чья сеть (уфимские провайдеры или со стороны), адрес отправителя и получателя) и включала юзера в список зарегистрированных в режиме online.
    3. Рассылку о необходимости регистрации посчитала бесполезной: как "редкая птица долетит до середины Днепра", так и редкий юзер прочтет мое сообщение, а если и прочтет, то еще мало кто поймет, о чем речь.
    Итак, если регистрация пройдена (юзер назван в файле /etc/mail/smtp_auth_users), то пропускаем письмо.
    10-11. Далее самое интересное. Подаем на вход тему письма. Если оно содержит секретное слово - пропускаем его. Тема письма в этом случае должна быть написана только и только латиницей. Иначе это правило не заматчится из-за base64 и, как следствие, кракозябров.
    Любое обстоятельное объяснение использованию секретного слова в теме для благополучного прохождения smtp-авторизациии займет минимум страницу (со всеми конкретными примерами из жизни). Поэтому приведу всего один пример. Нас в конторе всего три с половиной человека. И мы доступны юзерам практически круглосуточно и повсеместно (даже на садовом участке я не могу забыть о работе, потому что что в 50 метрах от меня находится участок нашего юзера, а наш Юрий Иваныч так вообще проживает в недавно построенном доме для сотрудников УНЦ РАН и теперь доступен юзерам круглосуточно) .
    Вот это секретное слово рассчитано на те случаи, когда инета под рукой нет, а юзер с его проблемой - вот он, туточки. К примеру, забрались мои коллеги на крышу оборудование проверять, а я так вообще не в городе, тут звонит юзер и ..."Почему я не могу отправить почту ??? Сервер дает в ответ ошибку и ссылку: я все прочитал и ничего не понял. Что мне делать?" Тут ему сообщают, какую тему нужно указать, чтобы письмо ушло. Ес-но, когда Карлсоны спустятся с крыши, они внесут этого юзера в список зарегистрированных, ну а пока можно обойтись и авторизацией по теме.
    Кстати, если бы юзер внимательно прочитал информацию в указанной ссылке, то мог бы и сам решить проблему:
    1) зайти в инет через нашу сеть;
    2) или, если он уже в локальное сети, то убрать из настроек почтовой программы требование smtp-авторизации.
    Но, увы и ах, не прочтут, не поймут, не осмыслят, не осилят, сами не справятся ...
    12-13. Если тема не совпала с секретным словом или вовсе отсутствует - блокируем.
    14. Очищаем макрос {Subject}.

    20.12.2008. Как я говорила, количество попыток подбора паролей к моим ящикам в последнее время резко возросло. Действительно, определить источник сканирования непросто. Не всегда перебор сопровождается такими "маячками":
    Aug 11 11:11:13 mail saslauthd[1234]: do_request : NULL password received
    Dec 19 19:29:31 mail sendmail[30150]: Password verification failed
    Sep 15 16:09:04 mail sendmail[16566]: All-whitespace username.
    Nov 21 15:26:45 mail sendmail[29936]: Can only find author (no password)
    Dec 19 17:31:14 mail sendmail[5765]: mBJCV4oo005765: [1.3.4.3]: possible SMTP attack: command=AUTH, count=3
    Но то, что почти всегда при этом присутствует в логе, - это записи
    Dec 19 13:57:19 mail saslauthd[3997]: do_auth : auth failure: [user=paradise] [service=smtp] [realm=] [mech=shadow] [reason=Unknown]
    Dec 19 13:57:19 mail sendmail[17375]: NOQUEUE: Null connection from host.domain [IP.AD.DD.RESS] or ... did not issue MAIL/EXPN/VRFY/ETRN during connection to ...
    Исключение - do_request : NULL password received.
    Jan 13 10:06:26 mail sendmail[7999]: could not find auxprop plugin, was searching for '[all]'
    Jan 13 10:06:26 mail saslauthd[4010]: do_request : NULL password received
    Jan 13 10:06:26 mail sendmail[7999]: n0D56Q3Z007999: [192.168.0.5] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
    Это мой юзер так пытался отправить письмо.
    В половине случаев эти записи помогают мало. Если вы последите за такими атаками, то поймете почему, а здесь раскрывать карты я не буду.
    Не будучи никогда сторонницей рассылки abuse-уведомлений об атаках (во-первых, некогда; во-вторых; не верю, что эти abuses кто-то читает; в-третьих, если их и кто-то прочитает, не верю в принятие мер), в случае smtp-атаки я все-таки теперь реагирую. Не далее как 16.12.2008 было выслано письмо на Украину по причине многочисленных записей в логе, появляющихся из SteepHost.Net не в первый раз:
    Dec 18 13:23:27 mail saslauthd[3998]: do_auth : auth failure: [user=paradise] [service=smtp] [realm=anrb.ru] [mech=shadow] [reason=Unknown]
    Dec 18 13:23:27 mail sendmail[1220]: mBI8NNkw001220: 50.4.207.91.unknown.SteepHost.Net [91.207.4.50] (may be forged) did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
    Как и водится, реакции нет. В чем я и не сомневалась.

    28. Как отказаться от проверок в остальных рулсетах, если сработал #error в одном из предыдущих рулсетов (быстрый выход из _всех_ правил).

    А теперь о том, что меня всегда напрягало и раздражало:
    если вы пишете свои рулсеты, то, наверное, уже заметили, что блокируя почту в одном из рулсетов, мы не избавляемся от исполнения других рулсетов. То есть, несмотря на вызов мэйлера #error или #discard в одном из рулсетов, и как следствие, завршение именного этого рулсета, sendmail.cf продолжает обрабатываться как ни в чем не бывало.
    ДА, в конечном счете письмо принято не будет, но sendmail исправно "заглянет" в каждый следующий рулсет. И, возможно, в каждом "получит по лбу". Зачем?

    Пример.
    На запись в /etc/mail/access
    bezeqint.net DISCARD
    sendmail, как и следует, отреагировал "discard". На этом бы и остановиться. Ан нет. Sendmail принялся исполнять остальные рулсеты, получив отлупы еще в 3 наборах правил. Причем в CheckReceived & CheckFrom & CheckHeader sendmail "споткнулся" все о тот же домен bezeqint.net.

    Nov 10 09:49:45 mail sendmail[26929]: mAA4neCK026929: ruleset=check_mail, arg1=<temp@bezeqint.net>, relay=[85.12.250.170], discard
    Nov 10 09:49:47 mail sendmail[26929]: mAA4neCK026929: ruleset=CheckReceived, arg1= from [85.12.250.170] by mailmx.bezeqint.net; Mon, 10 Nov 2008 09:47:44 +0500, relay=[85.12.250.170], reject=554 5.0.0 [skipped]
    Nov 10 09:49:47 mail sendmail[26929]: mAA4neCK026929: ruleset=CheckFrom, arg1=\t=?koi8-r?B?7dXOycPJ0MHM2M7ZyiDawcvB2g==?=<temp@bezeqint.net>, relay=[85.12.250.170], reject=554 5.0.0 [skipped]
    Nov 10 09:49:47 mail sendmail[26929]: mAA4neCK026929: ruleset=CheckHeader, arg1= temp@bezeqint.net, relay=[85.12.250.170], reject=554 5.0.0 [skipped]
    Nov 10 09:49:47 mail sendmail[26929]: mAA4neCK026929: from=<temp@bezeqint.net>, size=4317, class=0, nrcpts=1, msgid=<507814054.81073698319406@bezeqint.net>, proto=ESMTP, daemon=MTA, relay=[85.12.250.170]
    Nov 10 09:49:47 mail sendmail[26929]: mAA4neCK026929: to=<paradise@anrb.ru>, delay=00:00:02, pri=34317, stat=Relaying denied. temp@bezeqint.net

    К чему такая добросовестность? И лишняя работа?
    Тогда, когда нагрузка была небольшой, на это можно было закрыть глаза. Но сейчас с этим мириться невозможно
    Я добавлю макрос Exit_ruseset. По умолчанию он будет равен 0. Как только в одном из рулсетов случится отлуп #error or #discard, этот макрос станет равным единице, и остальные рулсеты исполняться не будут (если, конечно, мы заявим о своем нежелании проверки во всех остальных рулсетах).

    LOCAL_CONFIG

    # По умолчанию адрес отправителя не принадлежит белому списку
    D{WL_mail_from}0

    # По умолчанию мы должны пройти через все наши рулсеты
    D{Exit_ruleset}0

    # For full log to maillog
    Ksyslog syslog
    Kstorage macro
    Kcomp arith

    # Внешних отправителей, чья почта не будет фильтроваться, можно задавать через файл
    KNoCheckSender hash /etc/mail/oksender

    # исключения для SPAM2
    KNOSPAM0 regex -a@MATCH tsalenko|alert|workshop|ideal|-job-|(r|z)ashit|rollover|(net|geo)club
    KSPAM2 regex -a@MATCH woman|discount|astrolog|v.agra|anonymous|game|dollar|bonus|casino|re[kc]lam|nouser|prize|job|market|money|cash|shop|xxx|sex|donna|girl|adult|fuck|honey|sweet|porno|playboy|love|lolita|penis|c[0o]ck|kiss|romantic|zhifa|customer|britney|buhuchet|lopez|shit

    SLocal_check_mail
    R$*                   $: $(storage {Mail_from} $@ $1 $) $1

    # Назначаем макросу WL_mail_from, ответственному за отправителей из белого списка, значение 1 и завершаем рулсет.
    # В противном случае - продолжаем.
    # For full email
    R$* < $+ @ $+ >                   $: $(NoCheckSender $2@$3 $:$1<$2@$3> $)
    R@MATCH                   $: $(storage {WL_mail_from} $@ 1 $) @MATCH
    R@MATCH                   $: $(syslog syslog:mail:0: @MATCH - $&{WL_mail_from} $) @MATCH
    R@MATCH                   $@ OK
    # For domain part
    R$* < $+ @ $+ >                   $: $(NoCheckSender $3 $:$1<$2@$3> $)
    R@MATCH                   $: $(storage {WL_mail_from} $@ 1 $) @MATCH
    R@MATCH                   $: $(syslog syslog:mail:1: @MATCH - $&{WL_mail_from} $) @MATCH
    R@MATCH                   $@ OK

    #Do not check if it is local ip-address
    R$*                   $: < $&{client_addr} >
    R< $=R $* >                   $@ OK
    #Do not check if it is smtp-authenticated mail
    R$*                   $: < $&{auth_authen} >
    R< $+ >                   $@ OK

    # Return to Mail_from
    R$*                   $: $&{Mail_from}
    # Clear macros for next message
    R$*                   $: $(storage {Mail_from} $) $1

    #Canonify e-mail address
    R$*                   $: $>Parse0 $>3 $1

    # MD-address is okey (see RFC)
    R<@>                   $@ OK

    # Check to spam-addresses. Сначала обрабатываем исключения.
    R$+<@$+>                   $: $(NOSPAM0 $2 $: $1<@$2> $)
    R@MATCH                   $@ OK
    # Затем - непосредственно спам-шаблоны.
    R$+<@$+>                   $: $(SPAM2 $2 $: $1<@$2> $)
    # Если спам-шаблог обнаружен - назначаем макросу EXit_ruleset значение 1 ...
    R@MATCH                   $(storage {Exit_ruleset} $@ 1 $) @MATCH
    # ... и блокируем письмо
    R@MATCH                   $#error $: 554 Sorry, Your e-mail address looks like SPAM2D. If not, please contact the postmaster@anrb.ru via another e-mail address.

    R$+<@$+>                   $: $(NOSPAM0 $1 $: $1<@$2> $)
    R@MATCH                   $@ OK

    R$+<@$+>                   $: $(SPAM2 $1 $: $1<@$2> $)
    R@MATCH                   $(storage {Exit_ruleset} $@ 1 $) @MATCH
    R@MATCH                   $#error $: 554 Sorry, Your e-mail address looks like SPAM2N. If not, please contact the postmaster@anrb.ru via another e-mail address.

    HFrom: $>CheckFrom
    SCheckFrom
    # Вызываем макрос Exit_rulеset, оставляя при этом в рабочей области значение поля From:
    R$*                   $: <$&{Exit_ruleset}>$1
    R<1>$*                   $@ OK
    #Return to WL_mail_from
    R<0>$*                   $: <$&{WL_mail_from}>$1
    R<1>$*                   $@ OK
    R<0>$*                   $: $1
    R$*<$+@$+>                   $: $(NOSPAM0 $3 $: <$2@$3> $)
    R@MATCH                   $@ OK
    R<$+@$+>                   $: $(SPAM2 $2 $: <$1@$2> $)
    R@MATCH                                     $(storage {Exit_ruleset} $@ 1 $) @MATCH
    R@MATCH                                     $#error $: 554 Sorry, Your e-mail address looks like SPAM2. If not, please contact the postmaster@anrb.ru via another e-mail address.
    R<$+@$+>                   $: $(NOSPAM0 $1 $: <$1@$2> $)
    R@MATCH                   $@ OK
    R<$+@$+>                   $: $(SPAM2 $1 $: <$1@$2> $)
    R@MATCH                   $(storage {Exit_ruleset} $@ 1 $) @MATCH
    R@MATCH                   $#error $: 554 Sorry, Your e-mail address looks like SPAM2. If not, please contact the postmaster@anrb.ru via another e-mail address.

    HSubject: $>Check_Subject
    SCheck_Subject
    R$*                   $: <$&{Exit_ruleset}>$1
    R<1>$*                   $@ OK
    R<0>$*                   $: $1
    R$*Your internet access is going to get suspended$*                   $: $1 Your internet access is going to get suspended $2 $(storage {Exit_ruleset} $@ 1 $)
    R$*Your internet access is going to get suspended$*                   $#error $: 554 There is Trojan.Kllem in your mail.
    R$*You have received an $* eCard $*                   $: $1 You have received an $2 eCard $3 $(storage {Exit_ruleset} $@ 1 $)
    R$*You have received an $* eCard $*                   $#error $: 554 There is Trojan.PWS.GoldSpy in your mail.
    #Return to WL_mail_from
    R$*                   $: <$&{WL_mail_from}>$1
    R<1>$*                   $@ OK
    R<0>$*                   $: $1
    И Т.Д. и т.п. в каждом вашем рулсете.

    29. Запрещаем внешнюю почту, подписанную нашим доменом

    Так как здесь в двух рулсетах нам нужно обойти локальную и авторизованную почту, то я применю новый метод: сначала проверю почту на локальность и по результатам проверки назначу макросу LocUser значение YES or NO.

    1. Локальные сети прописаны в /etc/mail/relay-domains (класс R, принадлежность к нему - $=R)
    LOCAL_CONFIG
    Kstorage macro
    # Индикатор обязательности или ненужности проверки (отправитель наш иль нет). По умолчанию - наш, YES
    D{LocUser}YES
    LOCAL_RULESETS
    SLocal_check_mail
    R$*                 $: < $&{client_addr} > $| $1
    # Почта, исходящая с самого почтовика, проверке не подвергается
    R< 127.0.0.1 > $| $*                 $@ OK
    # Почта, исходящая из локальной сети (/etc/mail/relay-domains) проверке не подвергается
    R< $=R $* > $| $*                  $@ OK
    # Избавляемся от ставшего уже ненужным IP адреса отправителя.
    R< $* > $| $*                  $: $2

    # Осталась почта, исходящая с внешних адресов. Она может оказаться авторизованной.
    R$*                  $: < $&{auth_authen} > $| $1
    # Тогда пропускаем письмо
    R<$+> $| $*                 $@ OK

    # Осталась почта не из локальной сети и неавторизованная. Изменяем значение макроса LocUser на NO, попутно оставляя в рабочем поле только адрес отправителя.
    R$* $| $*                 $: $(storage {LocUser} $@ NO $) $2
    # И проверяем доменную часть
    R$*<$+@$=w>                           $#error $: "554 Forged sender domain."
    # А вдруг отправитель отправил письмо прямо через наш почтовик, тогда угловых скобок может и не быть:
    R$+@$=w                           $#error $: "554 Forged sender domain."

    HFrom:                  $>CheckFrom
    SCheckFrom
    # Добавляем значение макроса LocUser, чтобы решить, стоит ли делать дальнейшую проверку
    R$*                  $: <$&{LocUser}> $1
    # проверяем состояние индикатора {LocUser}. Если YES - сразу заканчиваем рулсет.
    R<YES>$*                 $@ OK
    # Итак, осталась только внешняя почта. Избавляемся от маячка < NO > и угловых скобок, чтобы учесть еще и почту, отправленную через telnet (это на тот случай, если вы не запрещаете такое), плюс добавляем макрос $&{deliveryMode}:
    R< NO >$*                  $: $1
    R$*<$+@$=w>                  $: $2@$3 $| <$&{deliveryMode}>
    R$+@$=w                  $: $1@$2 $| <$&{deliveryMode}>
    # Forged mail from $=w:
    R$+@$=w $* $| <b>         $#error $: "554 Forged sender address in the header From."

    А это иллюстрация того, зачем здесь нам нужен $&{deliveryMode}
    Пока он не применялся, имели место вот такие "ложные срабатывания": здесь письмо было отправлено от моего юзера, в письмо было вложено требование уведомления о доставке. Письмо было доставлено, а в теле уведомления содержался заголовок From:paradise@anrb.ru. Так как уведомление пришло из внешней сети, то сработал мой фильтр. Но так как он сработал на этапе проверки тела письма, то это не повлияло не реальную доставку сообщения. Для того, чтобы избежать таких срабатываний в дальнейшем, я и применяю $&{deliveryMode}.

    Dec 5 10:54:05 mail sendmail[6237]: mB55s3o9006237: from=<paradise@anrb.ru>, size=29595, class=0, nrcpts=1, msgid=<1736607522.20081205104858@anrb.ru>, proto=ESMTP, daemon=MTA, relay=[2.1.3.1]
    Dec 5 10:54:06 mail sendmail[6244]: mB55s3o9006237: to=<gatling@presidium.ras.ru>, ctladdr=<paradise@anrb.ru> (560/45), delay=00:00:03, xdelay=00:00:01, mailer=esmtp, pri=149595, relay=mail.ras.ru. [83.149.192.9], dsn=2.0.0, stat=Sent (Ok: queued as 9E60D8F0067)

    Dec 5 10:54:14 mail sendmail[6301]: mB55sAnO006301: from=<>, size=33125, class=0, nrcpts=1, msgid=<zw1En7eoC000009cd@mail.presidium.ras.ru>, proto=ESMTP, daemon=MTA, relay=mail2.ras.ru [83.149.192.9]
    Dec 5 10:54:14 mail sendmail[6303]: mB55sAnO006301: ruleset=CheckFrom, arg1= =?windows-1251?B?yM3K?= <paradise@anrb.ru>, relay=mail2.ras.ru [83.149.192.9], reject=554 5.0.0 Forged sender address in the header From.
    Dec 5 10:54:14 mail sendmail[6303]: mB55sAnO006301: to=<paradise@anrb.ru>, delay=00:00:00, xdelay=00:00:00, mailer=local, pri=63537, dsn=2.0.0, stat=Sent

    2. Если вы используете для авторизации юзеров только smtp-auth, то упрощенное решение здесь.
    В этом решении я совсем упустила возможность пропуска авторизованных юзеров, если использовать FEATURE(delay_checks). Я уже устала объяснять, почему я не люблю эту фичу, но , если вам хочется "правильного решения", то есть решения, максимально использующего предоставляемый sendmail'ом функционал, то можете сделать так:
    1) - в sendmail.mc включить FEATURE(delay_checks), это позволит не делать проверку адреса отправителя для авторизованных юзеров только в check_mail, проверить же авторизованность отправителя в CheckFrom все равно придется, потому что FEATURE(delay_checks) позволяет пропустить check_relay & check_mail и только их, если юзер авторизовался или работает из локальной сети.
    2) - в /etc/mail/access добавить строку From:yourdomain.ru [TAB] REJECT
    (то, что идет с тэгом From: обрабатывается в check_mail);
    3) - в /etc/mail/access или в /etc/mail/relay-domains добавить 127.0.0.1 для того, чтобы обходить проверку в check_mail почты, отправленной локально с сервера;
    4)в sendmail.mc добавить
    LOCAL_CONFIG
    LOCAL_RULESETS

    HFrom:                  $>CheckFrom
    SCheckFrom
    R$*                  $: < $&{client_addr} > $| $1
    R< 127.0.0.1 > $| $+                  $@ OK
    R$+ $| $+                  $: < $&{auth_authen} > $| $2
    R<$+>$| $+                 $@ OK
    R<>$| $+                 $: $1
    R$*<$+@$=w>                  $: $2@$3 $| <$&{deliveryMode}>
    R$+@$=w                  $: $1@$2 $| <$&{deliveryMode}>
    #Forged mail from $=w:
    R$+@$=w $* $| <b>         $#error $: "554 Forged sender address in the header From."

    3. Если вы используете access для разрешения релеинга, то вот здесь есть другое решение.
    Хочется сказать пару слов об используемом в этом решении canonify.
    Конечно, это грамотно и правильно: прежде чем разбирать адрес отправителя нашими правилами, можно (или нужно?) сначала подвергнуть этот адрес обработке, заложенной в sendmail.cf по умолчанию, т.е. пропустить его через рулсет canonify ( он же третий рулсет), т.е. привести адрес отправителя к каноническому виду. Но! В последнее время я все больше внимания уделяю оптимизации правил. По моим наблюдениям, "кривые" адреса отправителей (т.е. адреса, которые требуют дополнительной обработки для приведения их к стандартному виду) случаются относительно нечасто. Например, за последние 3 дня случилось всего около 150 таких адресов. Реально же через check_mail было пропущено 50-60 тысяч адресов в день. Значит, отказавшись от canonify в Local_check_mail я избавила sendmail, как минимум, от проходов 50000*45 правил где 45 - общее число правил рулсетов canonify & Canonify2.

    Я не использую также и вызов рулсета A, как это сделано в примере с www.linux.org.ru, для определения "судьбы" IP адреса (1.2.3.4) релея отправителя. Просто достаточно было "обложить" правила этого рулсета сислогом, чтобы понять, что он последовательно обрабатывает сети 1.2.3.4, 1.2.3.4, 1.2, 1, да еще пробует их и с тэгом "CONNECT" и без него (для совместимости с предыд. версиями).
    Поскольку безтэговые IP в /etc/mail/access я не использую, и в моем распоряжении ТОЛЬКО сети класса С, то в случае использования access я вполне могла бы обойтись следующими правилами вместо правила из первого пункта R< $=R $* > $| $+                  $@ OK :
    R$*               $: <$&{client_addr}> $| $1
    R< $-.$-.$-.$- > $| $*              $: $(access CONNECT:$1.$2.$3 $) $| $5
    R< RELAY > $| $*              $@ OK
    R$* $| $*              $: $2

    20.01.2009. Отвечая на вопрос "rejecting mail from my own domain Options" на sendmail-конфе, sendmail-гуру D.Stussy говорит:"... best solution is to write a custom ruleset that checks for your domain, a null sender, and the interface IP address (which should be loopback [127.0.0.1] or [::1] or NULL). Otherwise, the mail is coming from outside and is therefore forged... "
    Что такое NULL IP address? Отлаживая задачки по маршрутизации, однажды я увидела вместо привычного < IP > пустые угловые скобки <>. Повторить этот результат не удалось, но это было связано с DSN. И еще следует принять во внимание это.


    30. Вынуждаем локальных клиентов пользоваться только TheBat!

    Спрашивали здесь. Как водится, о результате не доложили. Как человек, в семье которого 4 поколения военных, могу сказать только одно: "Эххх, плачет по вас армия, плачет!"

    LOCAL_CONFIG
    Kstorage macro
    # Индикатор обязательности или ненужности проверки. По умолчанию заголовок X-Mailer не проверяется
    D{XM_check}NO

    LOCAL_RULESETS
    SLocal_check_mail
    R$*                   $: < $&{client_addr} > $| $1
    # Почта, исходящая с самого почтовика, проверке не подвергается
    R< 127.0.0.1 > $| $+                   $@ OK
    # Почта, исходящая из локальной сети проверке подвергается
    R< $=R $* > $| $+                   $: $(storage {XM_check} $@ YES $) < $&{client_addr} > $| $1
    R< $=R $* > $| $+                    $@ OK

    # Осталась почта, исходящая с внешних адресов. Она может оказаться неавторизованной.
    R$*                   $: < $&{auth_authen} > $| $1
    # Тогда заголовок X-Mailer не нужно проверять - заканчиваем рулсет
    R<> $| $+                   $@ OK

    # Она может оказаться авторизованной. Тогда это наш клиент, и заголовок X-Mailer нужно проверить
    R$+ $| $+                    $: $(storage {XM_check} $@ YES $)

    HX-Mailer: $>CheckMailer
    SCheckMailer
    # Добавляем значение макроса XM_check, чтобы решить, стоит ли делать дальнейшую проверку
    R$+                   $: <$&{XM_check}> $1
    # проверяем состояние индикатора {XM_check}. Если NO - сразу заканчиваем рулсет.
    R<NO>$+                   $@ OK

    # В противном случае сначала
    # записываем в макрос XM состояние заголовка X-Mailer.
    # Если X-Mailer присутствует в заголовке письма, в макрос XM запишется OK
    # Если этот заголовок вовсе отсутствует, то макрос XM будет пустой, так как
    # рулсет SCheckMailer вовсе исполняться не будет при отсутствующем X-Mailer
    R<YES>$+                   $: $(storage {XM} $@ OK $) $1
    # проверяем заголовок X-Mailer
    RThe Bat $+                   $@ OK
    R$+                   $#error $@ 5.0.0 $: <$&f>: "550 Please use The Bat mailer."

    Scheck_eoh
    # Снова вызываем значение макроса XM_check, чтобы решить, стоит ли делать дальнейшую проверку
    R$+                    $: <$&{XM_check}>
    R<NO>                   $@ OK

    # Не умудрился ли часом наш клиент отправить почту с отсутствующим заголовком X-Mailer
    R$*                    $: <$&{XM}>
    # Нет - пропускаем
    R<OK>                   $@ OK
    # Да, заголовок отсутствует. Далее на ваше усмотрение: или
    R<>                   $#error $@quarantine $: <$&f>: "550 Please use The Bat mailer."
    или
    R<>                    $#error $@ 5.0.0 $: <$&f>: "550 Please use The Bat mailer."


    31. Подмена адреса отправителя в транзитной почте.

    Перенесено сюда.

    32. Блокировка почты при нахождении одного и того же шаблона в двух разных Received.

    Здесь сложность в том, что шаблон должен встретиться в двух и более разных заголовках Received.
    Значит, нам потребуется счетчик. А это я делать уже научилась.
    Автору этой задачи не понравилось наличие шаблона "from .+ [IP-адрес]" в 2-х Received.
    Я не очень ясно понимаю, как это поможет идентифицировать спам, ну, разве что, это покажет что в череде пересыльщиков почты было 2 хоста, у которых нет доменных имен, что для почтового сервера несколько нетипично. Но первый хост с таким Received может оказаться рабочей станцией (она не обязана иметь domain name), непосредственно с которой клиент отправлял письмо, а другой хост - просто один из транзитных релеев (не mx) отправителя, который по какой-то причине живет без доменного имени.

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

    LOCAL_CONFIG
    Ksyslog syslog
    Kstorage macro
    Kcomp arith
    D{Rec_counter}0
    KfromIPtwice regex -a@MATCH from.*[([0-9]{1,3}.){3}[0-9]{1,3}\]

    LOCAL_RULESETS
    HReceived:                    $>+CheckReceived
    SCheckReceived
    R$*                    $: $1 $| $(fromIPtwice $1 $)
    #R$*                   $: $(syslog syslog:Rec0:<$&{Rec_counter}>-$1 $) $1
    R$* $| @MATCH                   $: $1 $| <$(arith + $@ $&{Rec_counter} $@ 1 $)>
    R$* $| <$+>                   $: $1 $| $(storage {Rec_counter} $@ $2 $) <$2>
    #R$* $| <2>                   $: $(syslog syslog:Rec1:<$&{Rec_counter}>-$1 $) $1
    R$* $| <2>                    $#error $@quarantine $: Sorry, etc ...
    R$* $| $*                   $: $1
    #R$*                    $: $(syslog syslog:Rec2:<$&{Rec_counter}>-$1 $) $1


    33. Выборочный dnsbl.

    Недавно я сказала VadeRetro знаменитые слова Кота Матроскина:"Чего-то, Шариков, зряяя мы тебя кооормим", и отключила все dnsbl-базы, кроме spamcop, увеличив тем самым нагрузку на VR. Как следствие, в ящиках юзеров стало появляться гораздо больше спам-писем (помеченных или нет). Не всем это понравилось. Оказалось, что у разных пользователей разное отношение и к спаму, и к ложным срабатываниям. То есть часть пользователей согласна на применение к их почте всех используемых ранее dnsbl-баз.
    Я уже говорила, что не люблю FEATURE(delay_check), потому что это меняет порядок исполнения рулсетов, и наиболее результативный check_relay начинает исполняться позже.
    Поэтому, я оставлю в конфиге для всех
    FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}')
    , но добавлю свои правила для проверки в остальных базах только для избранного круга.

    Решение черновое. Буду заниматься им после НГ.
    LOCAL_CONFIG
    # map for DNS based blacklist lookups
    Kdnsbl dns -R A -T<TMP> - вот это лишнее если вы используете вышеупомянутый FEATURE(`dnsbl',...), если же вы его не используете, то , возможно, вам лучше использовать FEATURE(check_delay), если вы не озадачены проблемой оптимизации конфига.
    Ksyslog syslog
    Kstorage macro
    KDnsbl2_list hash -T<TMPF> /etc/mail/Dnsbl2
    D{Exit_ruleset}0

    LOCAL_RULESETS
    Local_check_rcpt
    # Для начала избавимся от проверки почты, отправленной нашими юзерами:
    # Do not check if it is local ip-address
    R$*                   $: < $&{client_addr} > $| $1
    R< $=R $* > $| $+                    $@ OK
    # Do not check if it is smtp-authenticated mail
    R$*                   $: < $&{auth_authen} > $| $1
    R< $+ > $| $+                    $@ OK
    R< > $| $+                    $: $1

    # Почту для локальных пользователей отправляем на дальнейшую проверку в Dnsbl2_list
    R<$+@$=w>                           $: $(Dnsbl2_list $1 $)
    R$+@$=w                                    $: $(Dnsbl2_list $1 $)
    # Я не стала отправлять локальную почту на проверку в отдельный рулсет. Это чревато тем, что, если кто-то подставит в качестве адреса отправителя "@MATCH", то сработает следующая строка. Но ничего криминального в этом я не вижу: все равно в основном наборе правил check_rcpt такой адрес будет отвергнут.
    R@MATCH                                    $: $>Dnsbl2_check
    # Если вы предполагаете обходить все дальнейшие проверки в остальных рулсетах в случае обнаружения IP в одной из dnsbl-баз, то пригодится следующая строка:
    R$#$*                                    $(storage {Exit_ruleset} $@ 1 $) $#$1
    # А для всех в случае отлупа в SDnsbl2_check:
    R$#$*                                    $#$3

    SDnsbl2_check
    # DNS based IP address spam list cbl.abuseat.org
    R$*                           $: $&{client_addr}
    R$-.$-.$-.$-                  $: <?> $(dnsbl $4.$3.$2.$1.cbl.abuseat.org. $: OK $)
    R<?>OK                           $: OKSOFAR
    R<?>$+<TMP>                  $: TMPOK
    R<?>$+                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see cbl.abuseat.org

    # DNS based IP address spam list zen.spamhaus.org
    R$*                           $: $&{client_addr}
    R$-.$-.$-.$-                  $: <?> $(dnsbl $4.$3.$2.$1.zen.spamhaus.org. $: OK $)
    R<?>OK                           $: OKSOFAR
    R<?>$+<TMP>                  $: TMPOK
    R<?>$+                           $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see zen.spamhaus.org

    Ну и во всех остальных наборах нужно добавить по образу и подобию:
    HFrom: $>CheckFrom
    SCheckFrom
    # Вызываем макрос Exit_rulеset, оставляя при этом в рабочей области значение поля From:
    R$*                   $: <$&{Exit_ruleset}>$1
    R<1>$*                   $@ OK
    R<0>$*                   $: $1
    # и т.д.

    /etc/mail/Dnsbl2_list:
    user1                  @MATCH
    user2                  @MATCH
    ...
    user10                  @MATCH

    makemap hash Dnsbl2 <Dnsbl2

    34. Как добавить свой заголовок.

    03.03.08. Пример отсюда.
    Автор - Glen Barney, как он сам о себе сказал - " SENDMAIL/MAPS/ORBS fan (NOT guru!) ". Но Per Hedeland его решение вполне одобрил.
    Здесь результатом проверки в dnsbl-базе явялется не отказ от приема письма, а добавление дополнительного заголовка X-SPAM-Warning:.
    Я внесла рекомендованные гуру изменения, получилось что-то такое (не проверялось).
    LOCAL_CONFIG
    Kstorage macro
    Ksyslog syslog
    # map for DNS based blacklist lookups
    Kdnsbl dns -R A -T<TMP>

    C{persistentMacros}{Mmm}
    H?${Mmm}?X-SPAM-Warning: Sending machine is listed in ${Mmm}

    LOCAL_RULESETS
    Slocal_check_relay
    # DNS based IP address spam list zen.spamhaus.org
    R$*                    $: $&{client_addr}
    R$-.$-.$-.$-                   $: <?> $(dnsbl $4.$3.$2.$1.zen.spamhaus.org. $: OK $)
    R<?>OK                    $: OKSOFAR
    R<?>$+<TMP>                   $: TMPOK
    # !!! R<?>$+                    $#error $@ 5.7.1 $: Mail from $&{client_addr} rejected - see zen.spamhaus.org
    R<?>$*                            $: $(storage {Mmm} $@ zen.spamhaus.org $) OKSOFAR

    04.03.09. Эта задачка показалась мне очччень интересной, если использовать добавленный заголовок для фильтрации писем по папкам TheBat!ом. Кроме того она перекликается с предыдущей.
    Проверено: It wokrs! Получилось следующее. Сейчас я использую 2 только dnsbl-листа. Следующими правилами добавляю фильтрацию с.п. третьего dnsbl zen.spamhaus.org для адм-группы с добавлением дополнит. заголовка X-SPAM-Warning:. Затем настраиваю TheBat! и почта с IP, засветившихся в zen.spamhaus.org, будет складываться в отдельную папку.

    LOCAL_CONFIG
    C{persistentMacros}{AddHdSpWarn}
    H?${AddHdSpWarn}?X-SPAM-Warning: Sending IP address is listed in ${AddHdSpWarn}
    KADMADR regex -a@ADMLIST ^(adm(in(istrator)?)?|info|root|(post|host|web|drweb)master|(mailer|drweb)-daemon|noc)$

    LOCAL_RULESETS
    SLocal_check_rcpt
    # Save rcpt addr in the macro {Mail_to}
    R$*                                    $: $(storage {Mail_to} $@ $1 $) $1
    # Я использую белые списки отправителей: в Local_chck_mail заполняется макрос {WL_mail_from} (по умолчанию - 0).
    # Return to WL_mail_from
    R$*                                    $: $1 $| $&{WL_mail_from}
    R$* $| 1                           $@ OK
    R$* $| $*                           $: $1

    # Check local rcpt
    R<$+@$=w>                           $: $(ADMADR $1 $)
    # DNS based IP address spam list zen.spamhaus.org
    R@ADMLIST                           $: <ADM> $&{client_addr}
    R<ADM> $-.$-.$-.$-                  $: <ADM> <?> $(dnsbl $4.$3.$2.$1.zen.spamhaus.org. $: OK $)
    R<ADM><?>OK                           $: CONTINUE
    R<ADM><?>$+<TMP>                  $: CONTINUE
    # Fill {AddHdSpWarn} if zen.spamhaus.org says "It present"
    R<ADM><?>$+                           $: $(storage {AddHdSpWarn} $@ zen.spamhaus.org $) <ADM><?>$1
    R<ADM>$+                           $: $(syslog syslog:rcpt:10: $&{Mail_to}-$&{AddHdSpWarn}-$1 $)
    #$#error $@ 5.7.1 $: "550 Mail from " $&{client_addr} " rejected - see zen.spamhaus.org"

    # Return to Mail_to
    R$*                                    $: $&{Mail_to}
    # Clear the macro Mail_to for the next message
    R$*                                    $: $(storage {Mail_to} $) $1
    # Check if rcpt is proper after our manipulations
    R$*                                    $: $(syslog syslog:rcpt:0: $1 $) $1

    Это немного упрощенный блок проверки IP zen.spamhaus.org. Можно заменить.
    R<$+@$=w>                           $: $(ADMADR $1 $)
    # DNS based IP address spam list zen.spamhaus.org
    R@ADMLIST                           $: <ADM> $&{client_addr}
    R<ADM> $-.$-.$-.$-                  $: <ADM> $(dnsbl $4.$3.$2.$1.zen.spamhaus.org. $: OK $)
    R<ADM>127.0.0.$+                  $: $(storage {AddHdSpWarn} $@ zen.spamhaus.org $) <ADM2>
    R<ADM2>                                    $: $(syslog syslog:rcpt:10: $&{Mail_to}-$&{AddHdSpWarn} $)

    Mar 4 18:31:03 mail sendmail[12810]: n24DUvD9012810: syslog:rcpt:10:<info@anrb.ru>-.zen.spamhaus.org.-<?>127.0.0.11
    Mar 4 18:31:21 mail sendmail[12810]: n24DUvD9012810: from=<detkovedoz@udm.ru>, size=33934, class=0, nrcpts=1, msgid=<6890897103.28417719795507@udm.ru>, proto=ESMTP, daemon=MTA, relay=189-18-138-106.dsl.telesp.net.br [189.18.138.106]
    Mar 4 18:31:21 mail sendmail[12882]: n24DUvD9012810: to=<info@anrb.ru>, delay=00:00:18, xdelay=00:00:00, mailer=local, pri=64446, dsn=2.0.0, stat=Sent

    Заголовок письма:
    From detkovedoz@udm.ru Wed Mar 4 18:31:21 2009
    X-SPAM-Warning:Sending IP address is listed in zen.spamhaus.org
    Return-Path: <detkovedoz@udm.ru>
    Received: from adriano (189-18-138-106.dsl.telesp.net.br [189.18.138.106])
             by mail.anrb.ru (8.14.2/8.14.2) with ESMTP id n24DUvD9012810;
             Wed, 4 Mar 2009 18:31:03 +0500
    Subject: [VR:SPAM:: ]=?koi8-r?B?7M/MydTBIMnazcXOyczBIM3V1tUhIPPFztPBw8nPzs7ZxSDGz9TPIA==?=
             =?koi8-r?B?08XL09XBzNjO2cgg1dTFyCDQxdfJw9kh?=
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
    boundary="--------------------4DBZO37DI88RV6"
    X-Drweb-SpamState: yes
    X-Drweb-SpamState-Num: 1
    X-Drweb-SpamScore: 200
    X-Drweb-SpamVersion: Vade Retro 01.281.16 AV+AS Profile: <none>; Bailout: N/A
    X-Antivirus: Dr.Web (R) for Unix mail servers drweb plugin ver.4.44.2.0805030
    X-Antivirus-Code: 0x100000
    Date: Wed, 4 Mar 2009 10:23:10 -0300
    From: =?koi8-r?B?8MHQwdLBw8PJ?= <detkovedoz@udm.ru>
    X-Priority: 3 (Normal)
    Message-Id: <6890897103.28417719795507@udm.ru>
    To: info@anrb.ru

    Теперь настраиваю TheBat!

    Создаю в папке Postmaster папку X-SPAM
    Выделяю (Postmaster->Inbox) ->Далее в верхней строке меню Account->Sorting Office/Filters ->
    Account - Postmaster, Incoming mail - правая кнопка мышки - New Filter
    В правом разделе: Name: X-SPAM-WARN,
    Condition: Header contains X-SPAM-WARNING,
    Actions: MoveMessage folder \\Postmaster\X-SPAM
    Можно отметить
    Re-filter selected folder after editing.
    Тогда папка Inbox будет просмотрена на наличие уже полученных писем с таким заголовком.
    Или можно предварительно выделить письмо с таким заголовком в Inbox, и потом произвести изменение настроек. ТОгда именно это письмо будет перемещено в X-SPAM как реакция на Re-filter selected folder after editing.

    Нестрашный минус. Если письмо пришло нескольким получателям, среди которых есть кто-то из адм-адреса, письмо получит дополнит. заголовок в каждом письме.

    Еще ссылки.
    [1]
    12.03.2009. И все-таки мне пришлось вернуть проверку IP в zen.spamhaus.org по умолчанию для всех, потому как 50 спам-сообщений в день в один ящик - это уже слишком... А приведенная выше избирательная проверка теперь осуществляется в dnsbl.sorbs.net.


    35. Оч. мудреная проверка в dnsbl или скрещиваем пп. 33 и 34.

    01.04.09. Все готово и остается только выложить, когда будет время.

    36. Как задать в /etc/mail/access какое угодно число сетей класса С всего двумя строками.

    23.04.09. Почему возникает такая задача. Да потому что по понятным причинам такое в sendmail не предусмотрено.
    А мы пойдем другим путем! С 20.04.2009 sendmail прекрасненько понимает и принимает неполные сетки. Жить стало веселей!
    Да, чтоб не забыть: в который раз говорю большое спасибо Владимиру Васильеву, который объяснил мне, почему не срабатывали мои
    CONNECT:ufacom.ru [TAB] OK
    CONNECT:ufanet.ru [TAB] OK
    Еще раз о том же.
    Зачем это нужно. В различные dnsbl попали почти все сетки местных провайдеров. А значит, мои юзеры не могут работать с моим почтовиком из дома. Если бы мне пришлось прописывать все местные сети в access, то это бы заняло около 700 строк. А сейчас это занимает всего 26 строк (2*13 - количество сетей различного размера).
    В sendmail для CIDR notation предусмотрена программа cidrexpand, которая преобразует записи вида 1.2.3.0/30 в текстовом файле access в список IP адресов, составляющих эту сеть, но только в access.db.
    Per Hedeland: "...I.e., for octet-boundary subnets, access db has a compact "native" format, but in other cases cidrexpand is definitely the way to go. Of course it might also make sense to always use "CIDR notation" in the text file, and let cidrexpand worry about when it is "needed" - at least if you have a non-trivial set of networks..."
    Меня не устраивает в этом решении то, что в моем случае это приведет все к тем же 700 записям пусть не в текстовом access, а в access.db. И как отметил один из пользователей cidrexpand,
    "I use cidrexpand for the access db, like so:
    # access.db is special - it might contain CIDR notations,
    # which require expansion in order to actually be interpreted.
    # Note: this could lead to a VERY large expanded db.
    access.db: access.txt
    @cidrexpand < $< | makemap hash $@

    25.06.09. Ну вот после 2-х месяцев нормальной работы этот модуль можно выложить. Задача решена только для сетей класса С.

    /etc/mail/access
    # ufanet: 94.41.0-127
    NETCONNECT:94.41                   0
    PRCONNECT:94.41                   128

    # BIS(BashInformSvyaz), DSL pool: 94.75.0-63
    NETCONNECT:94.75                   0
    PRCONNECT:94.75                           64

    # BIS, bashtel: 95.110.0-127
    NETCONNECT:95.110                  0
    PRCONNECT:95.110                  128
    и т.д. и т.п.

    Далее придется отредактировать proto.m4. Сохраните предварительно копию этого файла. Можно, конечно, сделать грамотно и культурно через определение какого-нибудь нового FEATURE, как это сделано здесь, но этой техникой я не владею (а научиться этому можно только самостоятельно путем анализа первоисточников, да и, как подсказали в этом треде гуру, без редактирования proto.m4 данную задачу решить невозможно). Хотя FEATURE - это как раз и есть правильный подход, а редактирование proto.m4 - это некультурно.

    Итак, в /usr/src/sendmail/cf/m4/proto.m4 находим строки:
    ...
    ifdef(`_CONN_CONTROL_',`dnl
    ifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
    dnl workspace: ignored...
    R$*                  $: $>"ConnControl" dummy')', `dnl')
    Теперь я добавляю проверку в bl.spamcop.net, потому что хочу, чтобы она исполнилась перед моей проверкой (назову ее REGINONAL NET). При таком подходе нужно убрать или закомментировать объявление
    dnl FEATURE(`dnsbl',`bl.spamcop.net', `Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}')
    из/в конфиг(а/е).
    # DNS based IP address spam list bl.spamcop.net
    R$*                           $: $&{client_addr}
    R$-.$-.$-.$-                  $: <?> $(dnsbl $4.$3.$2.$1.bl.spamcop.net. $: OK $)
    R<?>OK                           $: OKSOFAR
    R<?>$+<TMP>                  $: TMPOK
    R<?>$+                  $#error $@ 5.7.1 $: Spam blocked see: http://spamcop.net/bl.shtml?$&{client_addr}

    Теперь идет вызов моего модуля PrConnect:
    R$*                  $: $>"PrConnect" dummy
    #R$*                  $: $(syslog syslog:PrCon:6: $1 $) $1
    Если модуль вернул значение REGIONAL NET, то делаем запись в лог и заканчиваем исполнение Local_check_relay:
    RREGIONAL NET         $: $(syslog syslog:PrCon:6: REGIONAL NET $&{client_name} $&{client_addr} $) REGIONAL NET
    RREGIONAL NET         $@ OK

    Это нижняя часть разрыва proto.m4 после первой моей вставки:
    undivert(8)
    ifdef(`_REQUIRE_RDNS_', `dnl
    ....
    SConnControl
    ...
    ...
    Вторая вставка идет сразу после рулсета ConnControl:
    SPrConnect
    R$*                           $: <$&{client_addr}>
    # Does this IP belong to any net with NETCONNECT tags?
    R<$-.$-.$-.$->                  $: <$(access NETCONNECT:$1.$2 $:OK $)>
    # R$*                           $: $(syslog syslog:PrCon:1: $1 $) $1
    # No, exit.
    R<OK>                           $@ OK         

    # Yes, it does. Well, NET number remains in the workspace. It looks like if IP is in regional net.
    R<$+>                           $: <$&{client_addr}><$1>
    # Is $3 less then NET's number?
    R<$-.$-.$-.$-><$+>         $: $(arith l $@ $3 $@ $5 $) <$5>
    # R$*                           $: $(syslog syslog:PrCon:2: $1 $) $1
    # Yes, it is. IP is not from regional NET. Exit.
    RTRUE<$+>                  $@ OK
    # NO, continue ...
    RFALSE<$+>                  $: <$1>

    # Well, NET's number remains in the workspace. Add IP again.
    R<$+>                           $: <$1><$&{client_addr}>
    # Take from access the number of hosts.
    R<$+><$-.$-.$-.$->         $: <$1><$(access PRCONNECT:$2.$3 $:OK $)>
    # R$*                           $: $(syslog syslog:PrCon:3: $1 $) $1
    # Oops. Where is this record? Exit.
    R<$+><OK>                  $@ OK         

    # Well, number of hosts remains in the workspace.
    # Second value of the net = NET's number + number of hosts
    R<$+><$+>                  $: <$(arith + $@ $1 $@ $2 $)>
    # R$*                           $: $(syslog syslog:PrCon:4: $1 $) $1
    R<$+>                           $: <$&{client_addr}><$1>
    # Is IP in the REGIONAL NET?
    R<$-.$-.$-.$-><$+>         $: $(arith l $@ $3 $@ $5 $)
    # R$*                           $: $(syslog syslog:PrCon:5: $1 $) $1
    RTRUE                           $@ REGIONAL NET
    RFALSE                           $@ OK

    undivert(9)dnl

    Далее я добавляю след. строки в конфиг:
    FEATURE(`dnsbl', `cbl.abuseat.org', `"550 Mail from " $&{client_addr} " rejected - see cbl.abuseat.org/lookup.cgi?ip="$&{client_addr}')
    FEATURE(`dnsbl', `zen.spamhaus.org', `"550 Mail from " $&{client_addr} " rejected - see zen.spamhaus.org"')
    Что мы теперь имеем?
    Dnsbl spamcop отрабатывает для всех. Далее идет проверка IP на принадлежность региональной сети. Если проверка дает положительный результат, остальные dnsbl не проверяются (почти все региональные сетки засвечены в различных dnsbl, а из дома мои юзеры работают в основном через местных провайдеров). В противном случае проверяем IP источника письма еще в 2-х базах.

    16.07.09. Возможно, я напрасно напрягаюсь по поводу большого количества строк в access. Гуру имеют по 3000 записей - и ничего, не переживают ... А я все ношусь с оптимизацией ...

    37. Dndbl-сервис на основе доменных имен.

    Спрашивали здесь. Не тестировалось.
    # DNS based domain address spam list sc.surl.org (этот список состоит из спам-web-ссылок, содержащихся в теле письма, и потому здесь неуместен, но мне некогда искать dnsbl, которые содержат доменные адреса хостов-отправителей)
    R$*                    $: $&{client_name}
    R$*                    $: $1
    R[$*]                    $: CONTINUE
    R$*                    $: $(dnsbl $1.sc.surl.org. $:OK $)
    ROK                    $: OKSOFAR
    R$+                    $: TMPOK
    R$+                    #error $@ 5.7.1 $: Spam blocked,see: http://url

    38. Как запретить определенному пользователю отправлять вложения.

    26.01.2010. Не вдаваясь в детали и признавая некоторую бессмысленность такого ограничения (хотя бы потому, что его легко обойти, просто вставив документ в письмо), опишу только направление движения.
    Если бы стояла задача запрета на получение писем со вложениями, то здесь идеально подошел бы procmail. Пример похожей задачки есть здесь.
    У нас же задача обратная, но принцип решения тот же: определить отправителя, обнаружить определенные сочетания символов в теле письма, принять решение (отказать, положить в карантин, тихо умолчать об уничтожении письма).
    Здесь нам понадобится milter-regex или Sentinel, так как именно он занимается разбором тела письма, а так как ограничение накладывается только на определенного пользователя, то нам не обойтись без milter-manager, который позволяет управлять запуском различных фильтров, исходя из различных условий.

    39. Двойные-тройные буквы "j" & "y".

    15.01.2011. Пока в стадии неспешного (со временем начинаешь относиться к спаму философски :) обдумывания - что с этим можно сделать?
    KJJJ regex -a@MATCH j.+j
    KYYY regex -a@MATCH y.+y

    R<$+ @ $+>          $: $(JJJ $1 $:$&{Mail_from} $)
    R<$+ @ $+>          $: $(YYY $1 $:$&{Mail_from} $)
    R@MATCH                                    $: $(storage {NEW1} $@ 1 $) @MATCH
    R@MATCH                                    $: $(syslog syslog:mail:NEW1: $&{Mail_from} $) $&{Mail_from}

    exclusion_string="Wiley|lIBRARY|REPLY|every|yuly|sydney|john|andrey|lyndsey|afanas|kyrgy|daisy|joan|Psychology|kathryney"

    Jan 14 11:23:58 mail sendmail[15248]: p0E6Ns8S015248: syslog:mail:NEW1:<bo-bx136hvazwj61uau9wda6rdy9dhvj8@b.usagca.com>
    Jan 14 11:58:12 mail sendmail[24013]: p0E6w9TO024013: syslog:mail:NEW1:<nwyjwryxrtjnjg@alabamagiving.org>
    Jan 14 12:02:41 mail sendmail[32403]: p0E72a5F032403: syslog:mail:NEW1:<popjldtrsjmy@afplc.org>
    Jan 14 12:02:43 mail sendmail[32403]: p0E72a5H032403: syslog:mail:NEW1:<ycdyrfpn@aboutcocaine.org>
    Jan 14 12:02:46 mail sendmail[32412]: p0E72giU032412: syslog:mail:NEW1:<msemymympwn@accessiblechicago.org>
    Jan 14 12:02:46 mail sendmail[32413]: p0E72gNu032413: syslog:mail:NEW1:<pgidjwckjnb@alwafaaa.org>
    Jan 14 12:02:51 mail sendmail[32434]: p0E72lBv032434: syslog:mail:NEW1:<toujfealljrj@abvmschool.org>
    Jan 14 12:18:14 mail sendmail[4572]: p0E7IAIo004572: syslog:mail:NEW1:<ejbskctjx@akf.org>
    Jan 14 12:24:51 mail sendmail[6522]: p0E7Oln1006522: syslog:mail:NEW1:<eryhkyfmnebpl@agapelovedeaf.org>
    Jan 14 12:48:22 mail sendmail[12599]: p0E7mHSR012599: syslog:mail:NEW1:<mcndojouiugbj@acta.org>
    Jan 14 13:45:05 mail sendmail[2039]: p0E8j1Ak002039: syslog:mail:NEW1:<cmns+bncCJGg4ujdBhDbmMDpBBoEzgjkvw@googlegroups.com>
    Jan 14 14:57:03 mail sendmail[29329]: p0E9uxOo029329: syslog:mail:NEW1:<fjxdjhajuzic@nsk.sibirtelecom.ru>
    Jan 14 16:42:11 mail sendmail[14241]: p0EBg7k3014241: syslog:mail:NEW1:<qnjsjn@martinsc.net>
    Jan 14 18:00:16 mail sendmail[28381]: p0ECxrRe028381: syslog:mail:NEW1:<dallyoy30@regalcandy.com>
    Jan 14 18:48:15 mail sendmail[6057]: p0EDmBc2006057: syslog:mail:NEW1:<n-vaJgLhgLG3RY8eC5mJjBpzNCr19G-jvGpXW8EtQVYl9U_0K2P-@bounce.linkedin.com>
    Jan 14 19:23:39 mail sendmail[26719]: p0EENZ0Y026719: syslog:mail:NEW1:<jjj------1984@att.net>
    Jan 14 20:43:51 mail sendmail[20730]: p0EFhl3V020730: syslog:mail:NEW1:<update+zj4oztt=ooj6@facebookmail.com>
    Jan 14 21:34:17 mail sendmail[9627]: p0EGYDsA009627: syslog:mail:NEW1:<v-cciacio_bhlflmica_fhodlhj_fhodlhj_a@bounce.ealert.nature.com>
    Jan 15 01:45:42 mail sendmail[32241]: p0EKjcr6032241: syslog:mail:NEW1:<cmns+bncCNjN6t2rBxDA6sLpBBoEOJ7qnQ@googlegroups.com>
    Jan 15 10:12:09 mail sendmail[9293]: p0F5C5CG009293: syslog:mail:NEW1:<update+zj4oz_osj_=y@facebookmail.com>
    Jan 15 11:26:43 mail sendmail[25952]: p0F6Qc0f025952: syslog:mail:NEW1:<matzosjmj1@edlioncontrols.ru>
    Jan 15 12:33:45 mail sendmail[12122]: p0F7Xfu4012122: syslog:mail:NEW1:<iptwyrywhgr@acfah.org>
    Jan 15 12:33:50 mail sendmail[12126]: p0F7Xk4D012126: syslog:mail:NEW1:<thqvvycvexbyrh@afrigrowth.org>
    Jan 15 14:39:23 mail sendmail[17672]: p0F9dJqC017672: syslog:mail:NEW1:<cmns+bncCJGg4ujdBhCW1cXpBBoEmYYflQ@googlegroups.com>
    Jan 15 16:18:58 mail sendmail[19633]: p0FBIsKv019633: syslog:mail:NEW1:<3-IExTRQKBfglttlqjfqjwyx-stwjuq3lttlqj.htrxhfqffswg.wz@alerts.bounces.google.com>

    Ясно одно: в простом варианте эта проверка не пойдет. Ее нужно об-но дополнять проверками на кол-во получателей, на "корявость" HELO, на "некрасивость" REceived, и откладывать данные письма в карантин.

    40. Undelivered Mail Returned to Sender. Соберем для Вас по сети интернет базу данных потенциальных клиентов для Вашего Бизнеса.

    23.11.2011. Проблема имеет отношение к backscatter - нежелательным DSN (спам-DSN).
    Я и мои пользователи регулярно получаем извещения о невозможности доставки сообщения, посланного якобы с наших адресов на наши же адреса. Так как мой сервер не принимает почту, подписанную моим доменом, но при этом приходящую из чужих сетей, то поддельное письмо от <gatling@anrb.ru>, предназаченное самому себе (<gatling@anrb.ru>), отвергается. Сервер-отправитель обязан сообщить отправителю о невозможности доставки. В итоге мой пользователь получает спам-DSN.

    Добавляем в /etc/procmailrc:
    :0 B
    * Subject: =\?utf\-8\?B\?ISEh0KHQvtCx0LXRgNC10Lwg0LTQu9GPINCS0LDRgSDQv9C
    {
    :0
    * !^Return-Path:
    /var/spool/mail/dsnspam
    }

    mail -fH /var/spool/mail/dsnspam:
    N 93 MAILER-DAEMON@wadn Wed Nov 23 19:59 129/5924 Undelivered Mail Returned
    N 94 MAILER-DAEMON@dile Wed Nov 23 20:02 67/2953 Undeliverable mail:
    N 95 MAILER-DAEMON@dile Wed Nov 23 20:02 67/2953 Undeliverable mail:
    N 96 MAILER-DAEMON@gw.e Wed Nov 23 20:12 92/3841 Undelivered Mail Returned
    N 97 MAILER-DAEMON@webk Wed Nov 23 20:34 62/3006 Returned mail: response e
    N 98 MAILER-DAEMON@mail Wed Nov 23 20:56 157/7677 Undelivered Mail Returned

    Итак, данная задачка решена для того случая, когда первоначальное спам-письмо начиналось со слов "Соберем для вас ". Теперь думаем дальше. Ищем более общее решение.
    Что объединяет данные spam-dsn'ы? То, что все это внешняя почта, подписанная моим доменом. Следовательно, в тексте отказа содержится одна и та же запись.

    Добавляем в /etc/procmailrc:
    :0 B
    * Текст отказа
    {
    :0
    * !^Return-Path:
    /var/spool/mail/dsnspam
    }
    и... наблюдаем.

    Минусом данного решения является следующее: уехавший сотрудник первым делом настроит почтовую программу на удаленном компе и попытается отправить почту коллегам. Мой сервер откажет ему

    41.

    YY. Оптимизация правил или что бы такого сделать плохого ...

    30.12.2008.
    Если бы сегодня я начинала настройку почтовой системы с нуля, то постаралась бы сделать следующее:
    - развела входящую и исходящую почту по 2 sendmail'ам;
    - локальность почты (т.е. то, что почту отправляет мой юзер) определяла один раз и запоминала в макрос, а дальше использовала только значение этого макроса (0/1);
    - избегала исполнение других рулсетов, если в предыдущем уже случился отказ (быстрый выход из правил);
    - активно использовала систему начисления баллов за неочевидные признаки спама (Claus Assmann тоже об этом говорил, см. Maps useful for anti-UBE:
    The new arith map can be used for something like scoring; initialize a macro {SpamScore} with 0 (using the macro map)
    and add a score each time you find something "suspicious" in the envelope or header. Then check it in the check_eoh ruleset
    and accept or reject the e-mail accordingly. A simple binary system (Yes/No) can of course also be implemented:
    set a macro {Friend} to YES if the envelope from address or the address of the connecting system can be found
    in the access map with an appropriate RHS. );
    - smtp-auth-юзеров держала в отдельном файле и не разрешала smtp-авторизацию всем по умолчанию (т.е. не использовала SASLAUTHD_AUTHMECH=shadow);
    - отказалась от вызова canonify в локальных рулсетах;
    - во всех своих рулсетах, за исключением Local_check_*, использовала DeliveryMode, чтобы избежать "ложных" срабатываний при форварде письма; хотя письмо при этом все равно принимается, но каждый раз, когда я вижу в логе неправомерную запись ruleset=... как-то нехорошо ёкает сердце, "а оно мне надо" ? Тем более, что это решаемо ...
    -

    ZZ. Что бы еще такого сделать плохого ...

    06.02.2009.
    1. Если будет время, есть желание попробовать поработать с spf-записями с помощью правил sendmail'a.






    Обратная связь
    Страница создана 27 июня 2007г. Последнее обновление - 23 января 2011г.