Главная | Контакты



Главная > Программы > Postfix

Строим почтовый сервер. Postfix+Dovecot+Mysql. Часть Третья: Борьба со спамом

Строим почтовый сервер. Postfix+Dovecot+Mysql. Часть Третья: Борьба со спамом

Решаем проблему борьбы со спамом.

Фильтрация спама разбивается на две концепции:

  • Вывод о том, что сообщение является не желательным делается после принятия сообщения, на основании анализа заголовков и содержимого письма.
  • Вывод о том что, сообщение является не желательным делается на этапе соединения, на основании анализа ip адреса отправителя, обратного DNS запроса, анализа SMTP команд сделанных удаленным почтовым клиентом или сервером.

Первый способ представляется мне менее предпочтительным, потому что анализ содержимого увеличивает нагрузку на на сервер, кроме этого такая система все же делает сетевые проверки, что увеличивает задержку и увеличивает почтовую очередь. Но тем не менее сам факт приема почты гарантирует то, что все письма остаются в целости и сохранности, на худой конец можно складывать в отдельный почтовый ящик.
Второй способ более эффективен, но отвергнутое письмо как правило теряется безвозвратно. Это накладывает дополнительную ответственность на администратора. Приходится тщательно анализировать логи, собирать статистику, и составлять белые списки. Но лично я выбираю этот способ за его эффективность.

 

Начинаем борьбу со спамом встроенными средствами самого Postfix, надо заметить, что средства это достаточно мощные. Основные идеи я взял с сайта www.postfix.ru. В main.cf добавляем:

smtpd_helo_restrictions = permit_mynetworks,

permit_sasl_authenticated,
check_helo_access hash:/etc/postfix/helo_access,
permit_tls_all_clientcerts,
reject_unknown_helo_hostname

Фильтруем по команде HELO почтового сервера. Принимаются все соединения от своих сетей. Второе правило очень важное, дело в том, что наверняка найдется несколько серверов которые шлют вам почту, но в HELO о себе сообщают не свой FQDN. Это вполне нормальное явление для сервера типа exchange.supercompany.local, с таким же супер админом. К сожалению объяснять таким кренделям, что их сервер сконфигурирован не верно, абсолютно бесполезно, а почту от них принимать приходится. Так что создаем в /etc/postfix/ файлик helo_access и наполняем его таким содержимым:

exchange.supercompany.local OK
exchange1.supercompany.local OK
exchange2.supercompany.local OK

Разделителем должен быть TAB. И после того как добавили все что надо, выполняем команду:

sudo postmap /etc/postfix/helo_access

Дальше принимаем все TLS соединения, и в конце запрещаем принимать почту от серверов которые в HELO сообщают не свой FQDN.
Едем дальше:

Создаем необходимые нам классы:
smtpd_restriction_classes = verify_sender, block_dsl, client_ok, rbl_dul_ru, rbl_cbl, rbl_spamcop, bogon_ip, virbl, surbl

Описание классов:

verify_sender = reject_unverified_sender, permit
block_dsl = regexp:/etc/postfix/block_dsl.txt
client_ok = check_client_access hash:$config_directory/access_client_ok
rbl_dul_ru = reject_rbl_client dul.ru
rbl_cbl = reject_rbl_client cbl.abuseat.org
rbl_spamcop = reject_rbl_client bl.spamcop.net
bogon_ip = reject_rbl_client bogons.cymru.com
virbl = reject_rbl_client virbl.dnsbl.bit.nl
surbl = reject_rbl_client multi.surbl.org

smtpd_client_restrictions = permit_mynetworks,

check_helo_access pcre:$config_directory/helo_checks,
permit_sasl_authenticated,
permit_tls_all_clientcerts,
client_ok,
block_dsl,
reject_unknown_address,
reject_unknown_recipient_domain,
reject_unknown_sender_domain,
bogon_ip,
surbl,
virbl,
rbl_dul_ru,
rbl_cbl,
rbl_spamcop

Сначала безусловно принимаем почту от наших сетей. Потом исследуем всяческие аномалии в адресе отправителя. Например из интернета нельзя почту отправить с адреса 192.168.15.1. Для этого предназначен файлик /etc/postfix/helo_checks.txt, его содержимое можно скачать тут.

Дальше принимаем почту от авторизовавшихся через SASL клиентов, что логично, если юзер знает пароль то он порядочный человек ;) Также принимаем почту через TLS соединения.
Дальше если все же найдется хороший сервер который отсечется этим фильтром, его можно добавить в файл /etc/postfix/client_ok, причем все дальнейшие проверки в этом фильтре на них не будут распространяться. Это полезно когда нужный сервер попал в какой либо RBL. Формат этого файла аналогичен формату файла helo_access.
Ну дальше начинаем запрещать:
block_dsl — класс описанный выше. Это список правил для фильтрации dialup и dsl сетей. Как правило в таких сетях имена хостов содержат какое либо характерное слово по которому можно определить, что это динамический ip адрес принадлежащий какому то пулу. Содержимое файла /etc/postfix/block_dsl.txt скчать можно тут

Дальше запрещаем доступ, если для имени домена адреса отправителя и получателя не существует запись A или MX в DNS. И дальше идут сетевые проверки в RBL.

Дальше:

smtpd_sender_restrictions = permit_mynetworks,

permit_sasl_authenticated,
permit_tls_all_clientcerts,
check_sender_access hash:$config_directory/access_vip_sender,
reject_unauth_pipelining,
reject_non_fqdn_sender,
reject_unlisted_sender

Аналогично, разрешаем сначала все нужное и запрещаем не нужное, но перед этим делаем для себя путь для создания исключений. Файл /etc/postfix/access_vip_sender, формат аналогичен приведенным выше файлам аналогичного назначения.

Запрещаем некорректное использование команд конвейерной обработки, запрещаем доступ, если адрес отправителя сообщения имеет не верный формат, запрещаем доступ если в базе нет учетной записи для отправителя.

smtpd_recipient_restrictions = permit_mynetworks,

permit_sasl_authenticated,
permit_tls_all_clientcerts,
permit_tls_clientcerts,
reject_unauth_destination,
reject_non_fqdn_recipient,
reject_unlisted_recipient

Разрешаем что надо. Запрещаем отправку сообщений, получатели которых находятся за пределами доменов, которые описаны в параметрах $mydestination, $inet_interfaces и $virtual_maps, т.е запрещаем открытый релей. Запрещаем доступ, если адрес получателя сообщения имеет не верный формат и учетной записи получателя нет в базе.
Для фильтрации заголовков сформируем файл /etc/postfix/header_checks. Скчать его можно тут

Наличие только этих фильтров позволит отклонить 90% спама, но к сожалению этого мало! Просматривая ежедневный отчет, я могу констатировать что 99% почтовых сообщений являются спамом. При общем траффике скажем 10 000 сообщений в сутки и при такой эффективности фильтра мы получим 1000 спаммерских писем и только 100 полезных. Таковы к сожалению реалии. Так что нам придется использовать дополнительные инструменты.

Подключим проверку SPF. Для этого скачаем архив и распакуем.
Из архива нам нужен файл postfix-policyd-spf-perl, скопируем его в директорию /usr/libexec/postfix. Для работы скрипта нужен модуль perl Mail::SPF.
Установим его:

perl -MCPAN -e shell

Отвечаем на задаваемые скриптом вопросы, выбираем ближайшее зеркало и в открывшемся шелле набираем:

install Mail::SPF

Модуль скачается соберется и установится. Если для его установки понадобятся еще какие либо модули, скрипт предложит их скачать и собрать.
В smtpd_recipient_restrictions добавляем:

smtpd_recipient_restrictions = permit_mynetworks,

.....................
.....................
..........................
reject_unauth_destination,
check_policy_service unix:private/policy,

check_policy_service unix:private/policy ОБЯЗАТЕЛЬНО должен идти ПОСЛЕ reject_unauth_destination, иначе получим открытый релей!!!

И дальше в main.cf:

policy_time_limit = 3600

В master.cf добавляем:

lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
# =====================================================================
#
policy unix - n n - 0 spawn
user=nobody argv=/usr/bin/perl /usr/libexec/postfix/postfix-policyd-spf-perl
#
# ====================================================================

И перезапускаем Postfix. Теперь в логах мы должны наблюдать следующую картину:

Jan 28 11:29:11 mail postfix/policy-spf[18849]: : Policy action=PREPEND Received-SPF: pass (mail.ru: 194.67.23.149 is authorized to use 'user@mail.ru' in 'mfrom' identity (mechanism 'ip4:194.67.23.0/24' matched)) receiver=mail.example.com; identity=mfrom; envelope-from="user@mail.ru"; helo=mx3.mail.ru; client-ip=194.67.23.149

Далее подключим Greylisting. — способ автоматической блокировки спама, основанный на том, что «поведение» программного обеспечения, предназначенного для рассылки спама, отличается от поведения обычных серверов электронной почты. Если почтовый сервер получателя отказывается принять письмо и сообщает о «временной ошибке», сервер отправителя обязан позже повторить попытку. Спамерское программное обеспечение в таких случаях, обычно, не пытается этого делать.

Для того, чтобы установить Greylisting, нам надо установить дополнительный репозиторий:

[den@centos ~]$ sudo vi /etc/yum.repos.d/policydrpm.repo
[policydrpm]
name=abcbit Repo
baseurl=http://www.c-corp.net/linux/centos/5/c-corp/i386/
enabled=1
gpgcheck=0

Установим:

[den@centos ~]$ sudo yum install policyd

Создаем пользователя с правами которого будет выполняться демон policyd:

sudo groupadd -g 204 policyd sudo useradd -u 204 -d /dev/null -s /bin/false -g policyd policyd

Все необходимые для работы демона данные хранятся в базе mysql. Создаем базу в которой демон policyd хранит свои данные. Для этого из архива исходников policyd надо вытащить файл DATABASE.mysql и выполнить следующую команду:

mysql -u root -p < ./ DATABASE.mysql

Вылезет приглашение ввести пароль, надо ввести пароль суперпользователя mysql.
Все база готова.
Создаем пользователя который имеет права на эту базу:
 

mysql -u root -p

Вводим пароль рута mysql. В шелле mysql выполняем следующую команду:

GRANT ALL ON policyd.* TO policyd@localhost IDENTIFIED BY "yourpassword";

Дальше правим конфиг демона:

sudo vi /etc/policyd.conf # ip address or hostname to connect to:
#
# if you want to connect to a host/ip, enter it here.
# if you want to via a unix socket, set MYSQLHOST=""
#
MYSQLHOST="127.0.0.1"
#База может находиться и в сети. Но в нашем случае это не так.
#
# database name:
#
# name of database to connect to
#
MYSQLDBASE="policyd"
#
# database username:
#
# username to connect to database as
#
MYSQLUSER="postfix"
#
# database password:
#
# password to for username
#
MYSQLPASS="yourpassword"
#Явки и пароли для доступа к базе. Используем созданного выше пользователя.
# debugging information: default: 3
#
# only use debugging when there are problems
#
# 0 -> off (recommended)
# 1 -> standard debugging
# 2 -> 1+mysql queries+results
# 3 -> 1+2+network debugging
# 0=off
DEBUG=3
#Уровень дебага. На время тестирования оставляем самый высокий.
#
# bind to ip address:
#
# ip address which the policy daemon will listen on
#
BINDHOST=127.0.0.1
#Слушаем только на 127.0.0.1.
#
# port to bind to:
#
# port which the policy daemon will listen on
#
BINDPORT=10031

#Порт 10031, это нам понадобится для прикручивания к постфиксу.
#
# path to pidfile:
#
# where policyd will write its current pid to
#
PIDFILE=/var/run/policyd.pid
#Путь к pid файлу.
#
# syslog facility
#
# what syslog facility to log to
#
SYSLOG_FACILITY="LOG_MAIL | LOG_INFO"
#Пишем сообщения демона в maillog.
###########
# SECURITY #
###########
#
# chroot:
#
# directory to change to before binding
#
CHROOT=/
#Кому интересно могут зачрутить демон.
#
# uid:
#
# userid for the policy daemon to run as
#
UID=204
#UID созданного нами пользователя с правами которого работает демон, не стоит запускать его с правами рута.
#
# gid:
#
# groupid for the policy daemon to run as
#
GID=204
#GID созданного нами пользователя.
#
# connection acl:
#
# this is the list of ip addresses or networks (cidr format) that
# will be allowed to connect to policyd. leaving this blank causes
# policyd to reject all connection attempts.
#
CONN_ACL="127.0.0.1"
#Список сетей которые могут подключаться к демону.
#Дальнейший список опций сильно зависит от того, что вам нужно от этого инструмента. Позволяет он сделать не мало. Мне понадобился только сам грейлистинг:
#
# enable greylisting default: on
#
# whether greylisting should be enabled or disabled.
#
# 1=on 0=off
GREYLISTING=1
#Ответ который выдается клиенту при первом коннекте:
#
# greylist rejection: default: "Please try later"
#
# what error message the connecting host will recieve
# when a new triplet has been created.
#
GREYLIST_REJECTION="Please try later."
#Сколько октетов IP адреса хранить в базе:
# greylist host address: default: off
#
# by default policyd will only use 3 octets when dealing
# with greylisting information. this allows policyd to
# work around roaming MTAs which are known to move mail
# between different queues after a 450/temp rejection.
#
# some dont want this functionality and wish to be more
# aggressive when receiving mail. example of the format
# of the ips stored:
#
# 1=192
# 2=192.168
# 3=192.168.0 <- default/recommended
# 4=192.168.0.1
#
GREYLIST_HOSTADDR=3
#Промежуток времени через который мы сочтем, что сессия с ip не спаммерская:
# triplet timeout: default: 4 minutes
#
# when a triplet is created from the first mail delivery
# attempt, what period of time should go by before we
# allow the 'final delivery'. a study shows that there
# is no difference between 1 minute and 1 hour for spam
# at this point in time. a sane limit would be 5 minutes.
#
TRIPLET_TIME=4m
#Включаем белый список:
########################
# WHITELISTING (functional) #
########################
#
# whitelisting: default: on
#
# this enables whitelisting of ip/netblocks. this is needed
# if you want to allow any of the whitelisting features.
#
# 1=on 0=off
WHITELISTING=1
#Белый список мы будем вести на основании DNS имен.
# whitelist client dns name
#
# this allows you whitelist clients that have proper resolving
# records. for example, i could whitelist 'bulk.scd.yahoo.com'.
# so any connections from n6a.bulk.scd.yahoo.com or
# n6b.bulk.scd.yahoo.com would be whitelisted. this type of
# whitelisting gives far greater power when it comes to
# whitelisting ISPs or big companies which you know do not
# house spammers. please note. this table must NOT have more
# than 10 000 -> 15 000 entries.
#
# 1=on 0=off
WHITELISTDNSNAME=1

Теперь добавим несколько строк в файлик /etc/postfix/main.cf

smtpd_recipient_restrictions = permit_mynetworks,

permit_sasl_authenticated,
.......................,
.......................,
.......................,
check_policy_service unix:private/policy,
check_policy_service inet:127.0.0.1:10031,
reject_non_fqdn_recipient,
reject_unlisted_recipient

Для того чтобы ввести домен в белый список в шеле mysql необходимо выполнить такую команду:

INSERT INTO whitelist_dnsname (_whitelist,_description) \
VALUES ('%.mail.ru','# whitelist *.mail.ru');

Это легче делать используя для какой либо фронтэнд к mysql, например PhpMyAdmin.
Установка и конфигурирование PhpMyAdmin выходят за рамки этой статьи.
Работу policyd можно наблюдать в почтовом логе:

Mar 30 21:37:22 mail postfix/smtpd[32087]: NOQUEUE: reject: RCPT from 5acf87b2.bb.sky.com[90.207.135.178]: 450 4.7.1

Механизм грейлистинга является очень эффективным инструментом в борьбе со спамом, но использовать его нужно с умом. Дело в том, что большинство больших почтовых сервисов вроде того же mail.ru используют для отправки почты не один ip адрес. Поэтому попросив у mail.ru отправить нам почту позже, мы запросто можем получить следующую попытку отправки этого же письма уже с другого ip, само собой и эта сессия получит от нас вежливый отказ. Третья попытка может исходить еще с одного ip и окончится с тем же успехом и т.д. Таким образом, задержка в получении почты может составить далеко не те 4 минуты, что мы радостно написали у себя в конфиге. Поэтому необходимо сначала собрать статистику, а потом сформировать белый список доменов, от которых мы будем получать почту минуя механизм грейлистинга. Замечу, что это ни коим образом не означает, что нас удастся провести выдав себя за тот же mail.ru подделав заголовки, выше мы включили необходимые проверки обратной зоны, и такие умники пошли лесом еще на этапе соединения.

Copyright © ABC-BIT 2010
info@abc-bit.ru

Автор: Basmach & Den
19.04.2010

Материал взят с сайта: http://abc-bit.ru/help/articles/articles_17.html

Главная > Программы > Postfix