Фильтруем спам правильно. С примерами для postfix.
Аренда сервера
VPS, VDS, Windows VPS - от $10
VPS
Содержание:
Структура SMTP сессии
Перед тем как заняться фильтрацией спама нужно четко представлять себе как происходит взаимодействие почтовых серверов при передаче писем. Когда один почтовый сервер пытается передать другому письмо, то между ними всегда происходит диалог, который можно наглядно продемонстрировать. Для того, чтобы продемонстрировать этот диалог воспользуемся утилитой telnet на нашем сервере и попробуем при ее помощи отправить почтовое сообщение на ящик [email protected] от имени [email protected]:
# telnet examplereceiver.com 25
Connected to examplereceiver.com.
Escape character is ‘^]’.
220 examplereceiver.com ESMTP
helo examplesender.com
250 examplereceiver ready to serve
mail from:[email protected]
250 OK
rcpt to:[email protected]
250 OK
data
354 Go ahead
Hello world!
.
250 OK id=1Lu83v-0002nd-Su
Строки выделенные красным – это команды, которые мы посылаем серверу examplereceiver.com, строки выделеныне зеленым – это ответы сервера examplereceiver.com на наши команды. Давайте подробнее разберем что мы передаем и что получаем в ходе SMTP сессии.
“helo examplesender.com“. Мы представляемся серверу получателя, посылая ему в качестве приветствия имя нашего сервера. В ответ сервер examplereceiver.com возвращает нам код 250, который означает, что наша команда принята и можно продолжить дальше.
“mail from:[email protected]“. Мы сообщаем серверу получателя о том, от кого мы передаем письмо, в данном случае это адрес [email protected], получаем ответ с кодом 250, который означает, что наша команда принята и можно продолжить дальше.
“rcpt to:[email protected]“. Мы сообщаем серверу получателя кому адресовано письмо ([email protected]), в ответ снова получаем код 250 и продолжаем дальше.
“data“. Этой командой мы сообщаем серверу получателя о том, что мы хотим передать непосредственно текст почтового сообщения. В ответ получаем код 354, который означает “начните передачу тела сообщения”. Письмо заканчивается новой строкой и точкой в началае этой строки, что позволяет серверу получателя узнать где заканчивается наше письмо. На стадии data передаются еще служебные заголовки сообщения, такие как “Subject”, “Date”, Content-Type и т.д., но в данном случае мы передали только текст письма (Hello world!) и завершили передачу точкой в начале новой строки. В ответ получив код 250 и id, который присвоил этому письму сервер examplereceiver.com.
Итак, каждая SMTP сессия, состоит из 4 этапов, их последовательность всегда такая:
1. helo
2. mail from
3. rcpt to
4. data
Названия этих 4 этапов и их последовательность нужно выучить наизусть. Это самые базовые элементы, без них никуда. Если Вам что-то непонятно до данного момента, лучше вернитесь назад, перечитайте еще раз, попробуйте своими руками отправить письмо telnet’ом, задавайте уточняющие вопросы здесь или на форуме… в общем делайте что хотите – но структура SMTP сессии и полное понимание того, что делает каждая команда должно быть у Вас на уровне “разбудите в три часа ночи, спросите – я всё расскажу”. Без этого нет смысла продолжать.
Варианты фильтров
Обратная DNS запись (PTR запись). Считается правилом хорошего тона, когда администратор назначает каждому хосту обратную (PTR) запись. Кроме того, считается таким же хорошим тоном, когда обратная запись запись совпадает с прямой (А) записью.
N.B. При настройке своего почтового сервера потрудитесь, чтобы обратная запись совпадала с прямой. Т.е. если Вы, сделав dig -x (команда для *nix среды), для хоста 256.155.148.244 получили ответ mx.example.com, то и прямая запись mx.example.com должна указывать на 256.155.148.244. В противном случае не удивляйтесь если половина почтовых серверов откажется принимать Ваши письма. PTR запись прописывается у владельца блока IP адресов, скорее всего это Ваш провайдер.
Отсутствие обратной записи у сервера отправителя косвенно указывает на то, что сообщение является спамом. Вы не найдете ни одного сервера gmail, yahoo, mail.ru, yandex.ru и т.д., которые бы не имели обратной записи. И, хотя, теоретически отсутствие обратной записи не может служить критерием для оценки спамности письма, но как показывает практика в 99% случаев обратная запись отсутствует именно у хостов рассылающих спам, поэтому по отсутствию обратной записи у отправителя вполне можно отсеивать спам, а сталкиваясь с оставшимся 1% – заносить их в список исключений. Соответствующие директивы в конфиге postfix: reject_unknown_client.
HELO/EHLO. RFC прямо не обязывает, но рекомендует отправителям начинать SMTP сессию с HELO, в котором указано полноценное доменное имя (fully qualified domain name или сокращенно FQDN, например “smtp.example.com”). И, хотя, нет прямого обязательства это делать, но как и в случае с обратной записью передача в HELO неполноценного доменного имени (например “example”) или передача несуществующего доменного имени де-факто стали косвенными указателями на то, что письмо является спамом. Соответствующие директивы в конфиге postfix: reject_invalid_hostname, reject_non_fqdn_hostname, reject_unknown_hostname.
N.B. При настройке своего почтового сервера потрудитесь, чтобы в HELO Ваш сервер отдавал то, что прописано в PTR записи… Ведь материал выше Вы читали внимательно и PTR запись и А запись у Вас уже совпадают, не так ли? ;)
MAIL FROM. Как мы выяснили, в команде mail from отправитель передаёт получателю имя почтового ящика того, кто отправил письмо. Если в mail from указан почтовый адрес, даже домен которого не существует (например [email protected]), стоит ли нам принимать такое письмо? Однозначно нет. В ходе SMTP сессии мы можем проверить существование домена и, при его отсутствии, смело отвергнуть сообщение. Кроме того, если окажется что домен существует, мы можем проверить наличие указанного почтового ящика в домене отправителя (практически все MTA это умеют делать, называется “sender verify”). Для этого получатель создает обратную SMTP сессию в сторону отправителя, которая проходит три стадии: helo, mail from, rcpt to и не доходя до data завершается. Представим, что получатель в ходе SMTP сессии получил “mail from:[email protected]”. В рамках проверки “sender verify” получатель инициирует SMTP сессию назад в сторону отправителя, где в rcpt to передает “rcpt to:[email protected]”. Если он получает ответ 250 (продолжайте), то все ок – отправитель существует. Если же получает “550″ (user unknown), значит отправитель не существует и нам шлют письмо с поддельным адресом отправителя и это письмо можно отвергнуть. Но здесь палка о двух концах: с одной стороны поддельный адрес – это нехорошо, это скорее всего спам. С другой стороны существует немало честных рассылок, правда настроенных непонятно кем, когда рассылка идет с несуществующего адреса. И фильтровать такие рассылки только потому, что они криво настроены тоже не вариант. В общем стоит ли использовать sender verify или нет – мнения разделяются, но я бы рекомендовал все-таки включить sender verify, а сталкиваясь с криво настроенными рассылками – добавлять их в список исключений. Соответствующие директивы в конфиге postfix: reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unverified_sender.
N.B. Если Вы настраиваете почтовую рассылку, которая не требует ответов, то потрудитесь создать почтовый ящик от имени которого идёт рассылка. Можете не читать его, можете планировщиком (например cron для *nix) удалять из него сообщения каждую ночь, можете что хотите делать с сообщениями в этом ящике, но ящик должен существовать.
RCPT TO. На стадии rcpt to мы получаем адрес того, кому предназначено письмо. Данные из rcpt to мы можем точно также подвергнуть проверке, как и helo, и mail from. Что же мы можем проверить? Мы можем проверить правильно ли указан адрес получателя, является ли он FQDN адресом. Обслуживаем ли мы домен, на ящик которого нам собираются передать письмо. Существует ли в обслуживаемом нами домене ящик, на который собираются передать письмо. Если почтовый ящик получателя не являет собой FQDN имя (например [email protected] вместо [email protected]), то такое письмо можно отклонить. Если нам передают письмо для пользователя из домена, который мы не обслуживаем (например [email protected]), то его мы тоже отклоняем. Тоже самое с несуществующими пользователями в локальных доменах – отклоняем. Соответствующие директивы в конфиге postfix: reject_non_fqdn_recipient, reject_unauth_destination, reject_unlisted_recipient.
DNSBL. Суть работы фильтра DNSBL сводится к тому, принимающая сторона может проверить наличие/отсутствие IP адреса отправляющей стороны в черном списке и принять решения что делать с письмом. При этом, обычно, держателем черных списков выступает третья сторона. Соответствующие директивы в конфиге postfix: reject_rbl_client. Внимание! Никогда не используйте эту опцию! Объяснение ниже.
Greylisting. Серый список. Работа грейлистинга основывается на том, что поведение клиентов рассылающих спам отличается от поведения честных почтовых серверов. В ходе SMTP сессии грейлист отдает клиенту ошибку с кодом (4xx), который означает “временная ошибка, попробуйте повторить позже”. Честный почтовый сервер через время обязательно предпримет попытку повторной доставки, поскольку умеет держать очередь почтовых сообщений. Спамеры же в свою очередь очередей не держат, это продиктовано огромными объемами рассылок, для них держать очередь сообщений просто нецелесообразно. В итоге получается так, что честное письмо немного задерживается (обычно 15-30 мин), затем отправитель заносится в белый список как честный отправитель и в последствии сообщения от него приходят без задержек. Спамеры же отсеиваются, не предпринимая попытки повторной доставки. Соответствующие директивы в конфиге postfix: check_policy_service.
Контент-фильтры. До этого мы рассматривали варианты фильтрации, когда фильтры оперируют данными из начальных стадий SMTP сессии. Контент фильтры же в свою очередь анализируют тело письма. Примеры контент-фильтров: ClamAV, Spamassassin, DSPAM.
Как фильтровать правильно?
Распространенной ошибкой является использование DNSBL, что называется “в лоб”. И, хотя, я уже писал об этом ранее, но нелишним будет повторить еще раз: Почему я не использую DNSBL.
Итак, как же фильтровать спам правильно?
Самое важное – полностью отказаться от DNSBL. В конфигурационном файле postfix’а не должно быть ни единого черного списка. Вместо этого лучше включить проверку PTR записи, фильтры HELO/EHLO, проверку отправителя, greylist. Очень много спама из ботнетов оседает на проверке PTR записи, фильтрах HELO/EHLO и грейлисте.
Перед всеми фильтрами стоит добавить собственный белый список. В этот список Вы будете заносить честные сервера, которые неправильно настроены и из-за этого отфильтровываются. Их будет крайне мало, но они будут.
Вот готовые настройки для postfix:
smtpd_helo_required = yes
smtpd_recipient_restrictions =
# whitelists:
permit_mynetworks,
check_client_access hash:/usr/local/etc/postfix/access,
# host check's:
reject_unknown_client,
# HELO check's:
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_unknown_hostname,
# MAIL FROM check's:
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_unverified_sender,
# RCPT TO check's:
reject_non_fqdn_recipient,
reject_unauth_pipelining,
reject_unauth_destination,
reject_unlisted_recipient,
# Greylist:
check_policy_service inet:127.0.0.1:10023,
permit
Пояснение к некоторым опциям:
address_verify_sender – задаем пустой From для обратной проверки адреса отправителя. Иначе будет пинг-понг если вторая сторона тоже захочет верифицировать отправителя.
smtpd_helo_required – требуем от клиентов начинать сессию с приветствия.
reject_unknown_client – не принимаем почту от тех, у кого нет PTR записи
reject_unverified_sender – проверка адреса отправителя на существование
check_policy_service – указываем postfix’у порт где слушает greylist демон.
Этих опций Вам будет вполне достаточно, для спокойной работы. Даже без контент фильтра результат будет в десятки раз лучше, чем от DNSBL. А с контент фильтром и подавно.
Дополнительные записи:
17 комментариев
Пункт первый: обратная запись. Правило хорошего тона – это конечно звучит гордо. Но если я не ошибаюсь, нет в RFC требования о том, что A и PTR должны быть прописаны одинаково. Значит или отлуп всем, у кого нет PTR записи, или руками прописывать исключения. И еще до того, как прописал исключение, возможно придется объяснять (менеджеру коммерческого отдела, директору, … ), почему письмо было не принято. Думаю, что о разнице между A и PTR записями вышеозначенные товарищи слушать долго не захотят.
У нас на фирме исторически сложилось так, что реальный IP всегда был один, а почтовых доменов несколько. Я прописал PTR для главного, но к сожалению в один PTR несколько доменов поместить нельзя. Отазываться от всех почтовых доменов … можно, но нелегко. Брать пучок реальных IP по одному для каждого домена – смысла не вижу. Разве что настроить релей почты всех дополнительных доменов через основной… Как ваше правило спам/не спам в этом случае, засчитает почту за правильную или тоже зарежет? Это вопрос а не риторика :) просто я в мире unix как заяц в геометрии.
Пункт второй: graylist. В принципе, неплохая технология. Хотя самые умные/хитрые спамеры эту учитывают. :( И наши коммерсанты каждую вторую неделю прибегают с претензиями, почему письмо от клиента не пришло сразу после телефонного разговора, где им сказали, что письмо уже отправили. Успокаиваю, говорю что спам-система задержала, что оно через полчаса-час придет. Все равно недовольны.
1. Про DNS записи. В RFC требования нет. Но лучше чтобы всё-таки совпадало. Я знаю такие почтовые системы, которые при совпадении А и PTR не грейлистят почту и отправляют на грейлистинг тех, у кого не совпадает. Т.е. если совпадения не будет – ничего страшного не случится, но если будет – могут случиться мелкие полезности :)
Вы сильно ошибаетесь, говоря:
“У нас на фирме исторически сложилось так, что реальный IP всегда был один, а почтовых доменов несколько. Я прописал PTR для главного, но к сожалению в один PTR несколько доменов поместить нельзя.”
Вы попросту путаете имя хоста (релея) и домен, который обслуживает данный релей. Даю наводку: “cat /var/log/maillog|grep inbox.ru|grep mail.ru”. После этого внимательно подумать почему письма от inbox.ru успешно принимаются от релеев fххх.mail.ru. Можете еще сделать вот так:
$ host f178.mail.ru
f178.mail.ru has address 194.67.57.199
$ host 194.67.57.199
199.57.67.194.in-addr.arpa domain name pointer f178.mail.ru.
и тоже подумать.
2. Про greylist. Кто мешает не грейлистить почту для особо критичных ящиков? В список исключений их и пусть наслаждаются горами спама. Например вpostgrey файл с таким списком именуется postgrey_whitelist_recipients
У меня все под Windows живет, я вообще в мире Unix почти ничего не понимаю. Поэтому команды, над которыми Вы советовали подумать, мне отстучать негде. :( Хотя подумать и сделать для себя вопрос яснее было бы неплохо. Есть ли вариант продолжить разговор без Unix консоли? :)
Greylist: я пока добавляю исключения не для моих получателей, а для отдельных постоянных корреспондентов моих получателей. Ну и функция auto whitelist немного помогает – если мой коллега написал кому-то письмо, фильтр запомнит адрес на указанное количество дней и ответное письмо не будет учитываться грейлистом.
Жаль, что этот метод не панацея, самые хитрые спамеры продолжают долбиться и обходят грейлист.
Извините за задержку с ответом, я закрыл страницу вашего блога, а уведомление об ответе на комментарий на почту не приходило.
С уважением!
Вам не нужно повторять эти действия, в предыдущем сообщении я выложил готовые результаты. Вам остается только подумать почему письма от inbox.ru успешно рассылаются серверами, у которых в PTR прописано fххх.mail.ru. После чего Вы поймете абсурдность утверждения “IP всегда был один, а почтовых доменов несколько. Я прописал PTR для главного, но к сожалению в один PTR несколько доменов поместить нельзя”.
Пока что и не должны приходить. Вы ведь не зарегистрировались и не подтвердили e-mail. Регистрация пока недоступна, я с wordpress’ом всё еще разбираюсь, думаю на след. неделе будет регистрация, тогда будут и уведомления по почте.
здрасте! вот часть моего конфига постфикса:
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_client_restrictions = permit_mynetworks, hash:/etc/postfix/access, reject_rhsbl_client dsn.rfc-ignorant.org, reject_rbl_client bl.spamcop.net, permit_sasl_authenticated
reject_unknown_hostname
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks, check_helo_access hash:/etc/postfix/whitelist, check_helo_access regexp:/etc/postfix/helo_regexp, check_helo_access regexp:/etc/postfix/dul_checks, reject_invalid_hostname, reject_unknown_hostname, reject_non_fqdn_hostname, permit
smtpd_recipient_restrictions = hash:/etc/postfix/access, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unknown_recipient_domain, reject_rhsbl_recipient dsn.rfc-ignorant.org, reject_unauth_destination, permit
smtpd_data_restrictions = reject_unauth_pipelining, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unknown_sender_domain, permit
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_client_restrictions = permit_mynetworks, hash:/etc/postfix/access, reject_rhsbl_client dsn.rfc-ignorant.org, reject_rbl_client bl.spamcop.net, permit_sasl_authenticated
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks, check_helo_access hash:/etc/postfix/whitelist, check_helo_access regexp:/etc/postfix/helo_regexp, check_helo_access regexp:/etc/postfix/dul_checks, reject_invalid_hostname, reject_unknown_hostname, reject_non_fqdn_hostname, permit
smtpd_recipient_restrictions = hash:/etc/postfix/access, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unknown_recipient_domain, reject_rhsbl_recipient dsn.rfc-ignorant.org, reject_unauth_destination, permit
smtpd_data_restrictions = reject_unauth_pipelining, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unknown_sender_domain, permit
smtpd_sender_restrictions = hash:/etc/postfix/access, permit_mynetworks, permit_sasl_authenticated, reject_unknown_sender_domain , reject_rhsbl_sender dsn.rfc-ignorant.org , reject_non_fqdn_sender, reject_unauth_pipelining
smtpd_sender_restrictions = hash:/etc/postfix/access, permit_mynetworks, permit_sasl_authenticated, reject_unknown_sender_domain , reject_rhsbl_sender dsn.rfc-ignorant.org , reject_non_fqdn_sender, reject_unauth_pipelining
скажите, плиз, почему иногда пролазит спам с такими заголовками
Return-Path:
X-Original-To: моя@почта.net
Delivered-To: моя@почта.net
Received: from kdn.ktguide.com (unknown [118.43.79.122])
by почта.net (Postfix) with ESMTP id D198F19E62A
for ; Mon, 1 Jun 2009 10:40:16 +0700 (NOVST)
From: =?koi8-r?B?7MHQyc4=?=
To: Dmitry моя@почта.net
Subject: =?koi8-r?B?8+z19uLhIPBP/vTv9/noIPLh8/P57O/r?=
Reply-To: =?koi8-r?B?7MHQyc4=?=
X-Mailer: PHP/4.3.2
X-Priority: 3
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary=”——————–7YMVGNAEEHOI8J”
Message-Id:
Date: Mon, 1 Jun 2009 10:40:16 +0700 (NOVST)
по идее с неизвестных адресов unknown [118.43.79.122] не должно же пропускать…
Ок, мой уровень знаний предполагает (dig @212.1.104.10 inbox.ru mx), что inbox использует mxs.mail.ru в качестве релея. А также то, что A и PTR записи mxs.mail.ru и 94.100.176.20 соответствуют друг другу.
Если можно, вернемся к моему примеру. До недавнего времени на 1 IP работало несколько почтовых доменов, которые обслуживает Kerio Mail Server. Непосредственно, без релея на какой-либо единственный промежуточный сервер. A и Mx записи всех доменов указывают на один и тот же IP. Обратная PTR запись указывает на одно из имен. По рекомендациям Вашей статьи письма от такого отправителя можно считать спамом и отбрасывать.
Потому, что нет reject_unknown_client.
Да и еще, уберите вот это:
reject_rhsbl_client dsn.rfc-ignorant.org,
reject_rbl_client bl.spamcop.net
Почему это плохо, написано здесь:http://woland.pl.ua/3-pochemu-ya-ne-ispolzuyu-dnsbl-v-pomoshh-nachinayushhemu-postmasteru/
Вы заблуждаетесь. Вы путаете теплое с мягким. Проверка касается только имени хоста и его ip. При проверке PTR никакие MX’ы не проверяются, а уж тем более соответствие имени хоста доменному адресу в From.
Если у Вас в PTR для адреса 1.1.1.1 прописано my-mega-mx.example.com, а my-mega-mx.example.com в свою очередь указывать на 1.1.1.1, то всё у Вас будет отлично работать.
Спасибо. Когда срочно понадобилось поправить грейлистинг, помогло =)
!!!!!!!
N.B. При настройке своего почтового сервера потрудитесь, чтобы в HELO Ваш сервер отдавал то, что прописано в PTR записи… Ведь материал выше Вы читали внимательно и PTR запись и А запись у Вас уже совпадают, не так ли? ;)
Cитуация.
Почтовый шлюз на границе локальной сети A.B.C.D mx.a.ru
В локальной сети есть почтовый сервер 192.168.0.1 mail.a.ru
Во внешнем ДНС записи A и PTR указывают на A.B.C.D mx.a.ru
Если почта отправляется шлюзом, в соответствии со статьей, получатель проверяет
- A и PTR совпадают
A.B.C.D mx.a.ru
порядок
- Шлюз предствляется HELO mx.a.ru с A совпадает
порядок
Если почта отправляется сервером из локальной сети
получатель проверяет
- A и PTR совпадают
A.B.C.D mx.a.ru
порядок
-Локальный сервер представляется HELO mail.a.ru c А не совпадает
отбой.
Результат отбой легатимной почты?!!!!!
tootsie, во-первых я не рекомендовал включать проверку соответствия HELO днс записям, я всего лишь рекомендовал сделать так, чтобы они совпадали, на всякий случай. Перечитайте еще раз. Во-вторых, цитата из записи: “Перед всеми фильтрами стоит добавить собственный белый список. В этот список Вы будете заносить честные сервера, которые неправильно настроены и из-за этого отфильтровываются. Их будет крайне мало, но они будут.”
Раздел “Dangerous use of smtpd_recipient_restrictions”
и?
Думаю, линк будет интересен тем, кто хочет использовать пример как основу и подстраивать под свои нужды.
А сразу пояснения не отправил, т. к. невнимательно использовал капчу (изображения в браузере отключены) и на 3-й раз не хотел переписывать текст и дал только ссылку.
Ну вот, снова с 1 раза не прошел проверку… Хорошо, что в буфер обмена скопировал. Утомляет. С такой капчей 100 раз подумаю, прежде чем комменты слать…
:)
Там внизу написано:
“Надоело вводить капчу? Войдите или зарегистрируйтесь.”
Странно, в хэндбук написано: Для того чтобы правильно применять ограничения, необходимо понимать, на каком этапе SMTP взаимодействия их можно использовать. Некоторые ограничения не имеют никакого смысла на определенных этапах
А вы все в smtpd_recipient_restrictions сунули. Похоже хэндбук Вы не читали вовсе.
Приведенная Вами цитата вполне справедлива. И никаким образом не идет вразрез с вышеописанным. То, что Вы не до конца поняли о чем речь… Ну, бывает :)
Объясняю: На этапе передачи HELO/EHLO бесполезно проверять e-mail отправителя и получателя, т.к. они еще не были переданы в ходе этой сессии и не известны системе. Неизвестное проверить нельзя.
А вот на этапе передачи адреса получателя уже известно все и проверять можно все. Ну кроме текста письма (это следующий этап – DATA). Такой подход дает: во-первых отсутствие путаницы в конфиге, во-вторых, что более важно, логирование ВСЕХ данных при реджекте. Т.е. если письмо было отклонено из-за кривого HELO, то в логе будет не только IP отправителя и HELO, но также емейл отправителя и емейл получателя, что значительно и существенно облегчает жизнь при поиске чего-то в логе.
Читать – это хорошо. Но там же сказано – нужно ПОНИМАТЬ :)