Неприступный почтовый сервер, или жизнь без спама

King аватар

Читать далее...
Просто хорошая статья. Взята здесь.

Борьба со спамом — это головная боль всех ответственных администраторов почты. Чего только они не изобретают, чтобы любимым пользователям лучше жилось. Однако, как показала практика общения со многими системными администраторами, почему-то далеко не все представляют как правильно фильтровать спам.

Чаще всего встречается подход «добавим кучу RBL (DNSBL) и будем радоваться жизни». Подход не верный чуть более, чем полностью. Второй по популярности — контент-фильтры, зачастую купленные за бешеные деньги. Такой подход тоже в большинстве случаев совершенно неоправдан.

А ведь всё так просто, для спокойной жизни достаточно всего лишь пристально присматриваться к трём заголовкам входящей SMTP сессии. Порывшись на Хабре и в закоулках интернета так и не нашёл исчерпывающей статьи на тему правильной настройки SMTP сервера с точки зрения противодействия спаму. Поэтому решил расписать всё, что знаю на эту тему сам и чем успешно пользуюсь.

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

Итак, если вы хотите обезопасить своих пользователей от спама или наоборот, хотите чтобы кто-то случайно не обезопасил пользователей от ваших писем — добро пожаловать под кат.

Небольшая замечание: статья написана с прицелом на настройку почтового сервера Postfix, но в целом носит скорей теоретический характер. Описанные опции Postfix нужно указывать в соответствующих *_restriction параметрах конфигурационного файла, за подробностями обращайтесь к любому руководству по настройке Postfix.

Немного об SMTP протоколе

Электронная почта имеет много аналогий с почтой обычной. Самое для нас главное сейчас то, что вся информация на электронном «конверте» представляет из себя всего лишь два адреса: получателя и отправителя, а также штампик почтальона, конверт доставившего.

Немного отвлечёмся: представьте, что к вам придёт лицо крайне отталкивающей наружности и вручит плотно запечатанную посылку с обратным адресом «Трям из Тилимилитрямдии». Рискнёте принять и открыть? Вряд ли. Так вот, электронную почту можно тоже легко проверять и отсеивать исходя только из адресной информации, причём простор для возможных действий тут гораздо шире.

Как вам должно быть известно, почта в Интернете передаётся между почтовыми серверами по протоколу SMTP. Любое общение по этому протоколу начинается с трёх обязательных заголовков: HELO, MAIL FROM и RCPT TO. То есть перед тем, как начать передавать какие-либо данные, сервер сначала представляется (HELO), потом сообщает обратный адрес отправителя (MAIL FROM) и затем — адрес получателя (RCPT TO). Эти три заголовка и есть подпись на электронном конверте, и практически весь спам можно отсеять только исходя из их анализа. Большинство попыток передать что-то моему серверу не доходят дальше MAIL FROM, то есть письма отсеиваются ещё до фактического принятия, что значительно снижает нагрузку. То есть вместо того, чтобы открыть посылку от Тряма и обнаружить там споры сибирской язвы, я сразу посылаю почтальона куда подальше.

Итак, что же надо делать, чтобы не принимать письма, заведомо являющиеся спамом? Пойдём по порядку.

Немного о DNS

Когда-то на заре Интернета почта доставлялась непосредственно на узлы, указанные в почтовом адресе. То есть для доставки письма для user@domain.com почтовый сервер искал IP адрес domain.com и пытался послать посылочку по найденному IP. Потом появились MX записи, которые разом решили большинство проблем подобной организации почтового взаимодействия. Однако некоторые программы всё ещё могут работать с A записями при доставке почты. Но у вас, конечно, есть хотя бы одна MX запись для вашего домена, не так ли?

MX записи содержат адреса серверов, на которые должны доставляться письма для указанного домена. Однако в целях борьбы со спамом появилась технология, позволяющая указывать в DNS также адреса серверов, с которых могут приходить письма от указанного домена. Имя ей — Sender Policy Framework.

Подробно вдаваться во все тонкости технологии я не буду, скажу лишь, что TXT запись

v=spf1 +mx -all

для вашего домена скажет всем клиентам, поддерживающим проверку SPF, что письма из вашего домена могут приходить исключительно с серверов, указанных в MX записях. Можно сделать правило мягче, написав вместо -all ~all. За подробностями обращайтесь в Google и на официальный сайт SPF.

Всегда прописывайте SPF запись для домена, а так же включайте проверку SPF на своих почтовых серверах. Я рекомендую жёстко запрещать отправку писем из вашего домена со всех хостов, кроме ваших MX серверов. Вкупе с проверкой SPF на вашем сервере подобная настройка сразу срежет все письма, посылаемые со сторонних хостов от имени пользователей вашего домена на адреса пользователей вашего же домена. А такого спама чуть ли не половина, поскольку обычно SMTP серверы очень плохо защищены от писем из своего же собственного домена, и спамеры этим активно пользуются. SPF раз и навсегда избавит вас от писем Васе Пупкину, написанных судя по конверту Васей же Пупкиным, но пришедших с сервера в каком-нибудь Никарагуа.

Как настроить SPF в Postfix вам расскажет гугл, информации навалом и ошибиться нельзя, так что не будем тратить время на технический подробности.

Есть ещё пару крайне важных замечаний по поводу DNS. Скорее всего вы знаете, что основные записи DNS, так называемые A записи, преобразуют имя в IP адрес. Кроме них есть ещё CNAME записи, которые назначают псевдоним уже существующему имени. Именно эти два типа записей составляют основу всей системы доменных имён.

Но мало кто из пользователей знает, что есть так же обратные записи, которые преобразуют IP в доменное имя. Они носят название PTR. Так вот, есть два неписаных (строго говоря) правила, которым всё же все следуют:

  • Для каждой A записи должна существовать зеркальная PTR запись, то есть по имени хоста через DNS получаем IP, а по IP — обратно то же имя хоста.
  • В качестве адреса в MX записи всегда должно стоять имя (не IP!) хоста, для которого существует A запись. То есть нельзя, чтобы в MX записи стоял IP или псевдоним (CNAME).

Если вы не соблюдёте одно из этих требований — приготовьтесь к тому, что минимум четверть почты с вашего домена будет распознаваться как спам. Обусловлено это простым тезисом: благонадёжный отправитель всегда всё настраивает соблюдая правила, соответственно если правила не соблюдены — то отправителю доверять не следует, а значит и принимать от него почту — тоже.

Ну а чтобы включить проверку PTR у себя, используйте опцию

reject_unknown_client_hostname

Она требует, чтобы IP, с которого совершается соединение, резолвился в имя через PTR, а это имя резолвилось в свою очередь обратно в искомый IP.

Есть и менее жёсткое ограничение, задаваемое опцией

reject_unknown_reverse_client_hostname

В этом случае сервер будет проверять только наличие PTR записи, но не будет требовать существования соответствующей записи A.

Проверяем приветствие

Итак, кто-то захотел передать вашему серверу письмо. Передача начинается с приветствия — заголовка HELO. В HELO должно быть указано полное доменное имя (FQDN) отправителя, соответственно если это не так — можете смело сразу же отказывать в принятии. В Postfix для этого служат две опции:

reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname

Первая запрещает приём писем от хостов, передающих приветствие с некорректным синтаксисом, вторая — от хостов, передающих не FQDN в HELO запросе.

Однако не FQDN передают только самые глупые спамеры (и продукты MS, но им, как известно, законы не писаны), в конце концов представиться gmail.com не составляет труда. Поэтому надо ещё немного присмотреться к HELO. Для этого служат опция

reject_unknown_helo_hostname

Которая запрещает приём писем от серверов, представляющихся адресом, для которого не существует A или MX записи.

Отправитель — а стоит ли ему доверять?

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

Однако если в адресе отправителя указан домен, который вовсе не существует, то письмо совершенно очевидно принимать не стоит. И уж точно не стоит принимать письмо, в котором в качестве обратного адреса указано нечто, вообще адресом не являющееся. За отказ в принятии для таких писем отвечают две опции:

reject_non_fqdn_sender
reject_unknown_sender_domain

Первая — проверка адреса на написание, вторая — проверка существования домена.

Уже неплохо, но можно сделать кое-что ещё. Можно запросить сервер, обслуживающий указанный адрес отправителя, на предмет существования на нём пользователя с этим адресом. Действительно, вроде бы неплохая идея удостовериться в том, что обратный адрес действительно существует, иначе нам вполне может придти письмо от эфемерного фантома, о котором никто и не слыхивал.

Технически это реализуется очень просто: наш сервер открывает встречную SMTP-сессию, пытаясь послать письмо по адресу отправителя. Если удаётся успешно пройти этап посылки RCPT TO с этим адресом, т.е. если принимающий сервер вдруг не заявляет, что указанного ящика на нём нет, то считается, что присланный нам обратный адрес существует. Данные (то есть письмо) при проверке естественно никакие не передаются, сессия прерывается после RCPT TO.

За такую проверку обратного адреса отвечает опция

reject_unverified_sender

Из сказанного выше следует, что для любого адреса, с которого вы рассылаете почту из своего домена, должен существовать ящик на вашем сервере. Иначе ваши письма не пройдут проверку обратного адреса на стороне получателя и соответственно не будут доставлены по назначению. Это актуально для всяких рассылок и прочей вроде как односторонней коммуникации, не требующей ответа. Всегда создавайте ящики для всех адресов, с которых вы рассылаете почту. Если вы не хотите получать ответы на какой-то адрес, то просто посылайте письма на него в /dev/null, но принимать эти письма вы обязаны.

А получатель-то вообще существует?

Вот мы и дошли до последнего заголовка конверта — до получателя. Тут всё просто: во-первых, хорошо бы проверить, что переданная нам информация вообще является адресом электронной почты. Для этого служит директива

reject_non_fqdn_recipient

Кроме того нам бы не хотелось принимать почту на адреса, для которых у нас нет почтовых ящиков. Чтобы настроить такое поведение надо сначала создать список обслуживаемых ящиков, дальше рассказать о нём Postfix через один из *_recipient_maps параметров конфигурационного файла, ну а дальше либо воспользоваться параметром конфигурационного файла

smtpd_reject_unlisted_recipient = yes

Либо запрещающей опцией, имеющей тот же эффект:

reject_unlisted_recipient

В любом случае Postfix перестанет принимать письма для обслуживаемых доменов, если не существует ящика для получателя. Однако это ограничение никак не скажется на пересылке корреспонденции на адреса, которые не находятся в обслуживаемых доменах.

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

reject_unauth_destination

Она запрещает отсылку писем всем незарегистрированным пользователям (да, вам придётся настроить SMTP авторизацию). Всегда используйте эту опцию! Иначе быстро попадёте во всякие DNSBL.

В качестве промежуточного итога

Вот так только на основе анализа трёх заголовков конверта можно отсеять огромное количество спама. Однако спамеры хитрые, поэтому этого всё же недостаточно.

Грейлистинг

Иногда почтовые серверы бывают перегружены и не могут принять письмо. Как вы думаете, что они отвечают на входящие запросы в этом случае? Как ни странно так и отвечают — сервер временно недоступен, попробуйте позже. Ни один нормальный отправитель никогда в этом случае не посчитает, что письмо доставить нельзя со всеми вытекающими последствиями. Напротив, отправитель предпримет попытки доставить письмо позже, поставив его в свою очередь на отправку.
Этот факт можно (и без сомнения нужно!) очень эффективно использовать: при каждой первой попытке соединения с незнакомого хоста наш сервер будет отправлять сообщение о временной ошибке, а пропускать письмо только со второго раза. Это отсеет сразу чуть ли не весь оставшийся спам, поскольку спамсерверы практически никогда не предпринимают больше одной попытки доставки письма (иначе они бы просто «упали» от переполнения очереди). Эта технология называется Greylisting, и использовать её в современных реалиях просто необходимо.

Минусом применения является небольшая (обычно не более получаса) задержка в доставке писем при первом соединении от неизвестного хоста. То есть если ещё не известный нашему постфиксу сервер хочет передать письмо, то при первой попытке соединения ему отправляется ошибка о временной недоступности. Если сервер повторил попытку соединения — то письмо принимается, а сервер заносится в надёжные узлы и в дальнейшем письма от него принимаются без задержек.

О настройке грейлистинга в Postfix так же предлагаю прочитать в Google, это несложно и ошибиться не получится.

Блоклисты, или как делать не надо

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

С ног на голову, или посмотрим с другой стороны баррикад

Фильтровать спам научились, теперь же я постараюсь свести воедино всю информацию на тему того, что же надо делать, что бы не попасть в спам.

Для администраторов почтовых серверов:

  • Всегда делайте MX записи ссылающимися на записи A.
  • Запись A для почтового сервера всегда должна иметь зеркальную PTR запись.
  • Хост из HELO заголовка должен иметь A или MX запись.
  • Всегда создавайте SPF записи (да-да, это-то как раз не обязательно, но просто правило хорошего тона).
  • Для всех писем, рассылаемых из обслуживаемого домена, ящик для обратного адреса должен существовать и принимать почту.

Для тех, кто рассылает почту (из программ, с сайтов и т.д.):

  • Всегда посылайте почту только с существующим обратным адресом.
  • Никогда не посылайте почту с неподконтрольного вам домена, не проверив правила SPF для него. Например gmail.com в текущий момент позволяет посылать письма от его имени любому серверу, а вот yandex.ru и mail.ru сообщают через SPF о том, что посылка от их имени со сторонних серверов должна вызывать на себя пристальное внимание, что истолковывается умными спамфильтрами как увеличение уровня оценки спама для данного письма.
  • Никогда не посылайте почту через неправильно настроенные SMTP серверы. Проверить сервер на вшивость по списку выше — дело 5 минут, вам поможет утилита dig или nslookup.

Резюме

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

Однако никогда не забывайте про описанное в этой статье при настройке почты, потому что приведенные параметры позволяют снизить нагрузку на сервер на порядки по отношению к использованию только контекстных фильтров, да и дополнительно обеспечивают отличную фильтрацию.

UPD: Во-первых спасибо Vanav за критически важные замечания. Во вторых подразумеваемое изначально мной, но видимо всё же не до конца понятое резюме по приведённым опциям:

Вы должны сами решить, какие ограничения вы готовы поставить на свой сервер, а какие — нет. Многие скептически относятся ко многим представленным выше проверкам. Однако все они используются на реальных SMTP серверах в интернете, поэтому даже если вы включите вообще всё — вы будете далеко не одиноки. Поэтому если вы заметили сервер, который настроен неверно, не поленитесь отправить его администратору письмо на эту тему, возможно вы поможете ему избежать гнева со стороны пользователей, чья корреспонденция не дошла (если его уже не выгнали взашей с работы к моменту написания вами письма). И никогда не забывайте, что ломанные хосты можно добавить в вайтлист, дабы принимать от них почту без проверок.

Ваша оценка: Ничего Средняя оценка: 10 (7 votes)

достаточно полный вариант можно здесь росмотреть
http://wiki.centos.org/HowTos/postfix_restrictions
также есть проблема с грейлистом при приёме с публичных серверов
таких как Gmail MailRU и т.д.(они могут куждую попытку доставки делать с разных IP )
поэтому придлагаю модифицировать https://launchpad.net/postfix-policyd-spf-perl/
в котором сервера с корректной записью SPF пропускать мимо грейлиста

Chawoosh аватар

RBL не использую вообще - они похоже специализируются на "мимо кассы" в основном.
Самое простое - проверка на наличие имени в обратной зоне, вручную заполняемые "белые" и "чёрные" листы как для принимаемых, так и для отправляемых посланий. Чуть сложнее - включать в белый список сервера, на которые были письма от внутренних пользователей на N дней/недель. И естественно авторизация пользователей.

Почта для домена идёт только с одного сервера, который является mx и называется ns
ещё есть сервера mail, ftp, www. Хочу разрешить принимать только с mx

@                       IN      TXT     "v=spf1 +mx -all"

правильно? или надо
ns                      IN      TXT     "v=spf1 +mx -all"

такие записи не корректны
расмотрим на примере mail.ru
http://old.openspf.org/wizard.html?mydomain=mail.ru&a=no&mx=yes&ptr=no&a...
для домена указываем нейтральный SPF
mail.ru. IN TXT "v=spf1 mx ?all"
конкретно для каждого MX - запрещающий
mxs.mail.ru. IN TXT "v=spf1 a -all"

тогда SPAM маскирующийся под наш MX будет отвергнут получателем по результатам проверки EHLO

вроде так))

Во-первых, спасибо за ответ

Во-вторых, там в мастере на последний вопрос ответ "Yes", поэтому
mail.ru. IN TXT "v=spf1 mx ~all"

В третьих, вот здесь http://www.openspf.org/SPF_Record_Syntax приведен такой пример.
"v=spf1 mx -all"
Allow domain's MXes to send mail for the domain, prohibit all others.

Кстати, и статья выше указывает на такой вариант
mail.ru. IN TXT "v=spf1 mx -all"

Мне кажется, что одной такой строчки будет достаточно. Только вот как бы проверить?

Вы были правы, нужно 2 строки, вот статья http://www.zytrax.com/books/dns/ch9/spf.html, откуда процитирую:

1. the domain SPF is returned from a sender-domain query using the sender's email address e.g. sender = info@example.com sender-domain = example.com. The SPF record only allows the MX host to send for the domain.
2. the mail host SPF is present in case the receiving MTA uses a reverse query to obtain the source-ip host name and then does a query for the SPF record of that host. The SPF record states that the A record of mail.example.com alone is permitted to send mail for the domain.

RSS-материал