Борьба со спамом в MTA EXIM на основе ACL

29 Aug 2009 | Автор: dd |

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

В этой связи MTA Exim имеет большое подспорье, в виде ACL листов, которые позволяют отсекать спам на основе стоп-слов, заголовков SMTP диалога, использования HELO в диалоге и многое другое.
Ниже я привожу используемую мной конфигурацию файла exim.conf c фрагментом раздела ACL. Небольшие комментарии, надеюсь помогут разобраться, хотя  все должно быть понятно из описания логирования:

####################################

begin acl

#  Отбиваем всякие пакости на основе проверки содержимого письма
acl_check_virus:
deny  message   = Message rejected: virus found. NO PASARAN!(Ernesto Che Guevara).
hosts  = *
demime = *
malware = *
accept

acl_check_rcpt:
accept  hosts = :
accept  local_parts =
deny    hosts =

# Задаем почтовые адреса для внутреннего использования, с закрытой внешней пересылкой
deny    message         = SRY, but address not permitted for external use!
hosts           = !+relay_from_hosts
local_parts     = all
!authenticated  = *

# пропускаем почту через RBL
deny    message       = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text\
If you think that the system is mistaken, please report details to abuse@odminblog.ru

!authenticated  = *
log_message   = found in $dnslist_domain
dnslists      = relays.mail-abuse.org

deny    message       = rejected, $sender_host_address Open Proxy, see: $dnslist_domain\n$dnslist_text\
If you think that the system is mistaken, please report details to abuse@odminblog.ru

!authenticated  = *
log_message   = found in $dnslist_domain
dnslists      = dnsbl.void.ru

deny    message       = Spam blocked see:http://www.spamcop.net/w3m?action=checkblock&ip=$sender_host_address\
If you think that the system is mistaken, please report details to abuse@odminblog.ru

!authenticated  = *
log_message   = found in $dnslist_domain
dnslists      = bl.spamcop.net

deny    message        = host is listed in $dnslist_domain
!authenticated  = *
log_message   = found in $dnslist_domain
dnslists     =     opm.blitzed.org

deny    message       = rejected, $sender_host_address is listed in: http://relays.osirusoft.com/cgi-bin/rbcheck.cgi \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!authenticated  = *
!local_parts    = abuse                # Эта строка задает игнорирование данного правила для заданных адресов
log_message   = found in spamguard.leadmon.net
dnslists      = spamguard.leadmon.net

deny    message       = rejected, $sender_host_address is listed in: http://www.spamsources.fabel.dk/ \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!authenticated  = *
!local_parts    = abuse
log_message   = found in http://www.spamsources.fabel.dk/
dnslists      = spamsources.fabel.dk

deny    message       = rejected, $sender_host_address is listed in: http://www.spamhaus.org/ \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!authenticated  = *
!local_parts    = abuse
log_message   = found in http://www.spamhaus.org/
dnslists      =         sbl.spamhaus.org : \
xbl.spamhaus.org : \
pbl.spamhaus.org : \
sbl-xbl.spamhaus.org : \
zen.spamhaus.org

# Проводим процедуру обратного звонка, т.е. при поступлении запроса на отправку от отпределенного адреса, происходит встречный запрос к серверу отправителя
verify = sender/callout=90s,maxwait=120s
verify = recipient/defer_ok/callout=90s/callout_defer_ok
message = The sender cannot be verified. Check your email-client settings! \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!local_parts    = abuse
!sender_domains = +domains_disable_senderverify # в данном списке, объявленом в главной конфигурации, мы задаем исключения для доменов

deny    message       = rejected, $sender_host_address is listed in: http://mail-abuse.org/ \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!authenticated  = *
!local_parts    = abuse
log_message   =   found in  www.mail-abuse.org
dnslists        = blackholes.mail-abuse.org : \
dialup.mail-abuse.org

# Проверяем диалог на соответствие RFC
deny message        = HELO/EHLO required by SMTP RFC
condition           =  ${if eq{$sender_helo_name}{}{yes}{no}}
delay           = TEERGRUBE

# Проверяем корректность IP адреса отправителя, проверка направлена на манипуляции с HELO
deny message        = Forged IP detected in HELO-$sender_helo_name
hosts          = !+relay_from_hosts
log_message    = Forged IP detected in HELO: $sender_helo_name
!authenticated  = *
condition      = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
delay          = TEERGRUBE

# Проверяем корректность IP адреса отправителя, проверка направлена на манипуляции с HELO
deny message        = Forged IP detected in HELO -$sender_helo_name != $sender_host_address
hosts          = !+relay_from_hosts
!authenticated  = *
condition      = ${if match{$sender_helo_name}{\N^\d+(\.\d+){3}$\N} {yes}{no}}
condition      = ${if eq{$sender_helo_name}{$sender_host_address} {no}{yes}}
delay          = TEERGRUBE

deny message        = Forged hostname detected in HELO -$sender_helo_name
hosts          = !+relay_from_hosts
!authenticated  = *
log_message     = Forged hostname detected in HELO -$sender_helo_name
condition       = ${if match_domain{$sender_helo_name}{+local_domains} {yes}{no}}
delay           = TEERGRUBE

# Отбиваем больше одного пустого отправителя
deny message        = Only one recipient accepted for NULL sender
senders        = :
condition      = ${if >{$rcpt_count}{1} {1}}
delay          = TEERGRUBE

####### Данный раздел перекрывает большие листы рассылки и перебор пользователей
.ifdef ALLOWEDRCPTFAIL
drop message   = too many unknown users (${eval:$rcpt_fail_count+1} failed recipients)
log_message    = Dictionary attack (${eval:$rcpt_fail_count+1} failed recipients).
condition      = ${if >{$rcpt_fail_count}{${eval:ALLOWEDRCPTFAIL-2}} {1}{0}}
delay          = ${eval:FAILEDRCPTDELAY*$rcpt_fail_count}s
domains        = +local_domains
hosts          = !+relay_from_hosts
!authenticated  = *
.endif
deny message        = unknown user
log_message    = Teergrube: dictionary attack (${eval:$rcpt_fail_count+1} failed recipients)
condition      = ${if >{$rcpt_fail_count}{0} {1}{0}}
delay          = ${eval:FAILEDRCPTDELAY*$rcpt_fail_count}s
domains        = +local_domains
!verify         = recipient

deny hosts     = !+localadds:!+hosts_disable_callback:*
sender_domains = !+envdomain_disable_callback:!+domains_callback_norandom:!+domains_disable_senderverify:*
local_parts    = !+noenvfromcallback
!verify         = sender/callout=90s,random
delay          = TEERGRUBE

# Проводим обратный звонок, для всех кроме специально заданных доменов и хостов
deny hosts     = !+localadds:!+hosts_disable_callback:*
sender_domains = !+domains_callback_norandom:!+domains_disable_senderverify
local_parts    = !+noenvfromcallback
!verify         = sender/callout=90s
delay          = TEERGRUBE

############### Проводим проверки на уровне SMTP диалога

deny    message       = Wrong HELO – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
!local_parts    = abuse
!authenticated = *
condition     = ${if !match{$sender_helo_name}{\N\w\.\w\N}{yes}{no}}

deny    message       = Too short HELO – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
!local_parts    = abuse
!authenticated = *
condition     = ${if <{${strlen:$sender_helo_name}}{5}{yes}{no}}

deny    message       = Bad HELO domain symbols – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
!local_parts    = abuse
!authenticated = *
condition     = ${if match{$sender_helo_name}{\N_\N}{yes}{no}}

deny    message       = HELO is IP address – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!local_parts    = abuse
condition     = ${if isip{$sender_helo_name}}

deny    message       = Used HELO: $sender_helo_name not equal IP: $sender_host_address – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
!local_parts    = abuse
!authenticated = *
condition     = ${if match{$sender_helo_name}{\N^\[(\d+\.\d+\.\d+\.\d+)\]$\N}\
{yes}{no}}
condition     = ${if !eq{$sender_host_address}{${sg{$sender_helo_name}\
{\N^\[(\d+\.\d+\.\d+\.\d+)\]$\N}{\$1}}}\
{yes}{no}}

deny    message       = Must be letters in HELO domain – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
!local_parts    = abuse
!authenticated = *
condition     = ${if match{$sender_helo_name}\
{\N^[-\d\.]+$\N}{yes}{no}}

deny    message       = Wrong HELO domain – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
!local_parts    = abuse
!authenticated = *
condition     = ${if match{$sender_helo_name}{\N^.*\.(arpa|local|localdomain)$\N}{yes}{no}}

deny    message       = Main Hostname in your HELO – access denied. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !127.0.0.1
!local_parts    = abuse
condition     = ${if match{$sender_helo_name}{$primary_hostname}{yes}{no}}

# Блокировка попытки подмены IP адреса отправителя на адрес получателя
deny     message       = “Go ahead, it’s mine IP!!!!”
condition     = ${if eq{$sender_helo_name}{$sender_host_address} \
{true}{false}}
hosts         = * : !+relay_from_hosts

# Запрет на использование в доменных именах различных приставок модемного доступа, на основе стоп-слов.
deny    message       = Access denied – dsl/dialup/cable relays HELO detected, use your ISP SMTP server. \
If you think that the system is mistaken, please report details to abuse@odminblog.ru
hosts         = !+relay_from_hosts
sender_domains = !+greedy_suckers    # Исключение для серверов, имеющих в имени, приведенные стоп-слова
!local_parts    = abuse
!authenticated = *
condition     = ${if match{$sender_helo_name}\
{\N^((\d{1,3}[\.\-_x]){3}|.*(\d{6,12}|wireless|broadband|modem|dyn|\
cable|client|dial|unused|gprs|dsl|dhcp|user|vpn|home|dip|catv|(v|w)\
lan|as(1|2|3|4|5)|dynamic(?>ip)|host-ip|ppp|cdma|(?<!mx|s)pool|unassigned)\
.*\.[-a-z0-9]+\.\w+|.*(?<!smtp).*(cust|host).*\.[-a-z0-9]+\.\w+)$\N}\
{yes}{no}}

VN:F [1.9.21_1169]
Rating: 5.0/10 (2 votes cast)
VN:F [1.9.21_1169]
Rating: +4 (from 4 votes)
Борьба со спамом в MTA EXIM на основе ACL, 5.0 out of 10 based on 2 ratings
How to do llc accounting: everything you need to know.

Теги: , , ,

Отзывов: 4 на «Борьба со спамом в MTA EXIM на основе ACL»

  1. Автор: Павел на 25 Nov 2010

    Добрый день, Господа! Не подскажите воспользовался вашим acl-ом борьбы со спамом, теперь у меня в логах пишет:
    unkown named host list “+hosts_disable_callback”

    Я понимаю что отсутствует этот параметр в конфиге, но как его записать и что туда записать, заранее спасибо!
    Попробывал вот-так:
    hostlist hosts_disable_callback = (но не знаю что сюда написать, чтобы было все правильно)

    [Reply]

    anchous Reply:

    ну да- листа не хватает, так что добавляетет в main и в них пишете либо хосты через символ “:” , т.е. “IP1 : IP2 : IP3″ , либо путь до файла где эти адреса будут храниться.
    Но для себя я задаю примерно так:
    hostlist hosts_disable_callback = 127.0.0.1
    и уже в
    domainlist envdomain_disable_callback = /путь до файла
    domainlist domains_callback_norandom= /путь до файла
    взвожу какие домены не отзванивать

    [Reply]

    VN:F [1.9.21_1169]
    Rating: 0.0/5 (0 votes cast)
    VN:F [1.9.21_1169]
    Rating: +1 (from 1 vote)
  2. Автор: Margaritto на 14 Nov 2013

    Круто!

    Спасибо за правила, их как раз мне не хватало.

    Exim – надо пичкать правилами, в противном случае спам завалит сам сервер, и самое плохое – сам сервер начнет рассылать спам. Попав в черные списки.
    Кстати с нами такое произошло не давно, наш Exim попал в DNSBL список. Семь серверов занесли почтарь к себе. Ладно вот спам валил на сервак, но занести почтарь в черные списки – это жестко!

    У нас стояла аутентификация, и по идее ни кто не должен был рассылать спам с нашего сервера. Но хитрые спамеры каким- то волшебным образом взяли сервер к себе в обороты.
    Смотрел логи почтовика, там вообще валом записей, как в этом разобратся – хрен поймешь. Думал установлю анализатор лона isoqlog и узнаю кто был рассадником спама. Но не тут то было, узнал только инфу по реальным ящикам которые есть на сервере, и на этом все. Хотя думал что этот анализатор покажет много инфы как например “pflogsumm” для Postfix.
    Сегодня буду смотреть очередь Exim, там поди много писем со спамом к нему и от него.

    Хотя бы там найду проблему….

    А эти правила много спама отбивают?

    [Reply]

    anchous Reply:

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

    [Reply]

    VN:F [1.9.21_1169]
    Rating: 0.0/5 (0 votes cast)
    VN:F [1.9.21_1169]
    Rating: 0 (from 0 votes)

Ваш отзыв