[Exim-users] Не попасть в черные списки

Lena на lena.kiev.ua Lena на lena.kiev.ua
Вс Авг 19 18:15:00 UTC 2012


У всех админов Exim есть пользователи с виндой. Нереально уберечь
всех и каждого пользователя от щелкания по каким попало ссылкам.
Некоторые ссылки автоматически перенаправляют браузер на
специальные зловредные (malware) сайты, атакующие уязвимости в
браузерах и их plugin-ах: Flash, Adobe Acrobat/Reader, Java.
Антивирусы плохо помогают. Malware крадет сохраненные в настройках
почтовых программ (например Outlook Express) логин, пароль,
имя хоста релея ("SMTP-сервера") и номер порта, 
возможно даже не оставаясь на скомпрометированном компе,
так что потом сканировать антивирусами бесполезно.
Украденные пароли используются для рассылки спама,
в том числе через ваши Exim-ы.
Наверно, часть паролей крадут другими путями -
phishing (обманом побуждая пользователей написать мошеннику письмо с паролем
или ввести пароль на сайте мошенника) или пробуя самые часто используемые
пароли (типа пароль 12345 или логин test, пароль test) через POP3 или SMTP.

В результате такого исходящего спама (с использованием украденных у ваших
пользователей паролей) IP-адреса ваших серверов попадают в черные списки.
Чтобы это предотвратить, ранее в этой конференции предложили запретить
пользователям отправлять письма с аутентикацией (с паролем)
кроме как через зашифрованное соединение (smtps/SSL/TLS), надеясь, что
программы спамеров так не умеют. Но вот сегодня я получила
спам, инжектированный с аутентикацией через smtps:

> Received: from vm-emlprdomr-02.its.yale.edu ([130.132.50.143])
> 	by lena.kiev.ua with esmtps (TLSv1:DHE-RSA-AES256-SHA:256)
> 	(Exim 4.80 (FreeBSD))
> 	(envelope-from <dave на gmail.com>)
> 	id 1T32EO-000CuC-CF
> 	for lena на lena.kiev.ua; Sun, 19 Aug 2012 12:55:41 +0300
> Received: from RCASRVR02.ETS.LOCAL (c-24-126-93-217.hsd1.md.comcast.net [24.126.93.217])
> 	(authenticated bits=0)
> 	by vm-emlprdomr-02.its.yale.edu (8.14.4/8.14.4) with ESMTP id q7J953pc001966
> 	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
> 	Sun, 19 Aug 2012 05:44:30 -0400
> Message-Id: <201208190944.q7J953pc001966 на vm-emlprdomr-02.its.yale.edu>
> Content-Type: multipart/alternative; boundary="===============1964112493=="
> MIME-Version: 1.0
> Subject: 2012 Dave & Angela Dawes Cash/Charity Donation programme!! 
> To: Recipients <dave на gmail.com>
> From: Dave & Angela Dawes<dave на gmail.com>
> Date: Sun, 19 Aug 2012 05:43:31 -0400
> Reply-To: daveangela_dawes28 на rogers.com
> X-Scanned-By: MIMEDefang 2.71 on 130.132.50.143

Боюсь, что та идея скоро перестанет сдерживать спамеров.
Следовательно, ВСЕМ админам Exim необходимо как можно быстрее
(значит, автоматически) блокировать украденные пароли.
Полностью блокировать, а не лимитировать пользователям количество писем,
т.к. честным пользователям лимиты создают проблемы, а спам всё равно
просачивается, в результате сервер попадает в черные списки.
Ранее я приводила фрагменты конфига Exim, реализующие такое автоматическое
блокирование украденных паролей (и заодно блокирование
подбора паролей через SMTP, что не настолько важно, но немножко полезно).
Здесь повторяю, разжевывая более подробно для новичков,
что нужно изменить в конфиге Exim (версии не менее 4.67):

1. Замените абзац со строкой "accept  authenticated = *" на три абзаца:

  accept authenticated = *
        set acl_m_user = $authenticated_id
# в случае ящиков в /var/mail: ${sg{$authenticated_id}{\N\W.*$\N}{}}
        condition = ${if exists{$spool_directory/blocked_authenticated_users}}
        condition = ${lookup{$acl_m_user}lsearch\
                    {$spool_directory/blocked_authenticated_users}{1}{0}}
        control = freeze/no_tell
        control = submission/domain=
        add_header = X-Authenticated-As: $acl_m_user

  accept authenticated = *
        !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender
        ratelimit = LIM / PERIOD / per_rcpt / user-$acl_m_user
        continue = ${run{SHELL -c "echo $acl_m_user \
           >>$spool_directory/blocked_authenticated_users; \
           \N{\N echo Subject: user $acl_m_user blocked; echo; echo because \
           has sent mail to LIM invalid recipients during PERIOD.; \
           \N}\N | EXIMBINARY WARNTO"}}
        control = freeze/no_tell
        control = submission/domain=
        add_header = X-Authenticated-As: $acl_m_user

  accept authenticated = *
        control = submission/domain=

2. Если в строке "hostlist   relay_from_hosts ="
есть что-то кроме "localhost" или "127.0.0.1" или IP-адреса этого сервера,
т.е. ваш сервер является релеем для локальной сети
или своих пользователей по IP-адресу, то абзац со строкой
"accept  hosts         = +relay_from_hosts"
замените на три абзаца:

  accept hosts = !@[] : +relay_from_hosts
        set acl_m_user = $sender_host_address
                         # или имя пользователя от RADIUS
        condition = ${if exists{$spool_directory/blocked_relay_users}}
        condition = ${lookup{$acl_m_user}lsearch\
                    {$spool_directory/blocked_relay_users}{1}{0}}
        control = freeze/no_tell
        control = submission/domain=
        add_header = X-Relayed-From: $acl_m_user

  accept hosts = !@[] : +relay_from_hosts
        !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender
        ratelimit = LIM / PERIOD / per_rcpt / relayuser-$acl_m_user
        continue = ${run{SHELL -c "echo $acl_m_user \
           >>$spool_directory/blocked_relay_users; \
           \N{\N echo Subject: relay user $acl_m_user blocked; echo; echo \
           because has sent mail to LIM invalid recipients during PERIOD.; \
           \N}\N | EXIMBINARY WARNTO"}}
        control = freeze/no_tell
        control = submission/domain=
        add_header = X-Relayed-From: $acl_m_user

  accept hosts = +relay_from_hosts
        control = submission/domain=

3. В начало конфига вставьте:

acl_smtp_connect = acl_check_connect
acl_smtp_auth = acl_check_auth
acl_smtp_mail = acl_check_mail
acl_smtp_quit = acl_check_quit
acl_smtp_notquit = acl_check_notquit
LIM = 100
PERIOD = 1h
WARNTO = emailадресадмина
EXIMBINARY = /usr/local/sbin/exim -f root
SHELL = /bin/sh

В строке WARNTO надо указать email адрес админа или support-а,
куда пойдут автоматические уведомления о блокировании.
В строках EXIMBINARY и SHELL поправьте пути, я указала для FreeBSD.

4. Сразу после строки "begin acl" вставьте:

acl_check_auth:
  drop  message = authentication is allowed only once per message in order \
                  to slow down bruteforce cracking
        set acl_m_auth = ${eval10:0$acl_m_auth+1}
        condition = ${if >{$acl_m_auth}{2}}
        delay = 22s

  drop  message = blacklisted for bruteforce cracking attempt
        set acl_c_authnomail = ${eval10:0$acl_c_authnomail+1}
        condition = ${if >{$acl_c_authnomail}{4}}
        continue = ${run{SHELL -c "echo $sender_host_address \
           >>$spool_directory/blocked_IPs; \
           \N{\N echo Subject: $sender_host_address blocked; echo; echo \
           for bruteforce auth cracking attempt.; \
           \N}\N | EXIMBINARY WARNTO"}}

  accept

acl_check_quit:
  warn  condition = ${if def:authentication_failed}
        condition = $authentication_failed
        logwrite = :reject: quit after authentication failed: \
                            ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}
        ratelimit = 7 / 5m / strict / per_conn
        continue = ${run{SHELL -c "echo $sender_host_address \
           >>$spool_directory/blocked_IPs; \
           \N{\N echo Subject: $sender_host_address blocked; echo; echo \
           for bruteforce auth cracking attempt.; \
           \N}\N | EXIMBINARY WARNTO"}}

acl_check_notquit:
  warn  condition = ${if def:authentication_failed}
        condition = $authentication_failed
        logwrite = :reject: $smtp_notquit_reason after authentication failed: \
                            ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}
        condition = ${if eq{$smtp_notquit_reason}{connection-lost}}
        ratelimit = 7 / 5m / strict / per_conn
        continue = ${run{SHELL -c "echo $sender_host_address \
           >>$spool_directory/blocked_IPs; \
           \N{\N echo Subject: $sender_host_address blocked; echo; echo \
           for bruteforce auth cracking attempt.; \
           \N}\N | EXIMBINARY WARNTO"}}

acl_check_mail:
  accept set acl_c_authnomail = 0

acl_check_connect:
  drop  message = $sender_host_address locally blacklisted for a bruteforce \
                  auth (username+password) cracking attempt
        condition = ${if exists{$spool_directory/blocked_IPs}}
        condition = ${lookup{$sender_host_address}lsearch\
                    {$spool_directory/blocked_IPs}{1}{0}}

  accept

Когда на указанный в строке WARNTO ящик придет письмо с темой
типа "115.150.81.95 blocked", ничего делать не нужно, разве что
убедиться, что IP-адрес совершенно посторонний (в этом примере Китай).

А вот когда придет письмо с темой типа "user vasya на muhosransk.ru blocked",
это значит, что с использованием пароля этого пользователя через ваш сервер
было разослано много писем на разные email адреса, причем за последний час
100 из этих адресов были отвергнуты (5xx) получателями. С честными
пользователями такая ситуация весьма маловероятна. А вот спамеры
рассылают по громадным спискам email адресов, в которых полно
более не существующих или никогда не существовавших адресов.
Дело в том, откуда спамеры берут эти списки: роботы и трояны
ищут на web-страничках и в файлах зараженных компьютеров
строки символов, похожие на email адреса. Проверить существование домена
спамерские роботы еще могут, но вот проверить существование каждого
ящика на каждом домене - задача нетривиальная и трудно автоматизируемая,
подавляющее большинство спамеров этим не заморачиваются.
Вот посмотрите в своих логах, на какие адреса ваш Exim отвечал "Unknown user":

cd /var/log/exim; zcat mainlog*.* | fgrep 'Unknown user' | fgrep -v 'sender verify fail' | sed -E -e 's/^.+<.*<//' -e 's/>.+$//' | sort | uniq -c | sort -nr | less

Кроме типовых, но не существующих на ваших доменах адресов
типа webmaster@, sales@, office@, вы увидите Message-ID-ы,
куски email адресов, случайно склеившиеся куски строк. Например,
было 540 попыток заспамить никогда не существовавший адрес на моем домене
x-originating-ipa на lena.kiev.ua
Вот и через ваш сервер спамеры будут пытаться, используя украденный пароль,
слать и на множество несуществующих адресов тоже. На этом и основана эта
автоматика (идея Andrew Hearn из англоязычного [exim-users], реализация моя).
Когда придет письмо-уведомление с темой "user ... blocked",
с помощью команды exipick посмотрите содержимое замороженных (frozen)
в очереди писем, отправленных с указанным в уведомлении логином:

exipick -zi '$h_X-Authenticated-As eq vasya на muhosransk.ru' | xargs -n 1 exim -Mvc | less

Если увидите не спам (весьма маловероятно), то текстовым редактором
удалите из файла blocked_authenticated_users (в директории спула Exim,
например /var/spool/exim/ в FreeBSD) строку с этим логином
(если в файле только одна строка, а так обычно и будет,
то вместо этого можно просто удалить файл)
и разморозьте задержанные письма:

exipick -zi '$h_X-Authenticated-As eq vasya на muhosransk.ru' | xargs exim -Mt

А если увидите спам, то поменяйте пароль этого пользователя, уведомите его
и после смены пароля удалите строку или файл (см. предыдущий абзац).
Чтобы до пользователя дошло, заранее предусмотрите в договоре пункт о
взимании штрафа с пользователя, если его пароль использован для спама
(неважно, сам пользователь спамил или кто-то другой).
Замороженный в очереди спам - доказательство для взимания штрафа.
Когда доказательство уже не нужно, замороженный спам можно удалить из очереди:

exipick -zi '$h_X-Authenticated-As eq vasya на muhosransk.ru' | xargs exim -Mrm

Аналогично с пользователями в локальной сети (файл blocked_relay_users,
тема письма типа "relay user 192.168.12.34 blocked").

Лена



Подробная информация о списке рассылки Exim-users