Саморазоблачение - рандом, хитрости и чужой опыт

Пересылка почты - примеры работы системы в разных ситуациях

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

ВАЖНО! Эта страница является частью списка заметок о настройке почтовой системы (Postfix+Dovecot и пр.).
Родительская страница - обязательна к просмотру: Установка и настройка почтового сервера

Подробнее о конфигурации к которой относятся примеры в этой статье - см. ссылку выше.
Тем же - коротко об основных терминах (MTA, MDA, MUA и т.п.).

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

Это скорее конспект-шпаргалка, чем достоверный справочник. Кроме ответов здесь могут присутствовать вопросы.

Содержание

  1. Порты
  2. Пришло письмо снаружи, для получателя в родном домене
  3. Пришло письмо снаружи для чужого получателя
  4. Пришло письмо от отправителя в родном домене, для получателя в родном домене
  5. Отправка писем - общие сведения в контексте рассматриваемой конфигурации
  6. Кто сохраняет письмо в "Отправленные"
  7. Письмо отправляемое через 587 порт
  8. Сбои в работе принимающего почту сервера
  9. Проверка отправки почты из PHP
  10. Источники
Здесь описываются примеры для одного конкретного частного случая конфигурации почтовой системы.

Порты

Все ненужные порты можно закрыть снаружи Iptables (+ использовать некоторые дополнительные средства защиты, которые выходят за рамки темы). Закрыть не столько снаружи, но и изнутри. Во внешний мир и для внешнего мира (это две разные ситуации) для почты обязательно должен быть открыт только SMTP - 25 порт (для MTA). Внутри, за Iptables всё может быть немного по-другому.

Почтовые службы могут быть настроены например так (перечислено не все):

# sockstat -l
USER       PROCESS             PID    PROTO  SOURCE ADDRESS         FOREIGN ADDRESS        STATE
...
opendkim   opendkim            ...     tcp4   127.0.0.1:8891            *:*                LISTEN
clamav     clamav-milter       ...     tcp4   127.0.0.1:10026           *:*                LISTEN
root       /usr/sbin/postg     ...     tcp4   127.0.0.1:10023           *:*                LISTEN
root       dovecot             ...     tcp4   127.0.0.1:143             *:*                LISTEN
root       dovecot             ...     tcp4   127.0.0.1:4190            *:*                LISTEN
root       master              ...     tcp4   127.0.0.1:25              *:*                LISTEN
root       master              ...     tcp4   IP.IP.IP.IP:25            *:*                LISTEN
root       master              ...     tcp4   127.0.0.1:587             *:*                LISTEN
root       master              ...     tcp4   IP.IP.IP.IP:587           *:*                LISTEN
...
IP.IP.IP.IP - адрес внешнего интерфейса.

opendkim - сервер проверки и наложения цифровых подписей OpenDKIM.

clamav-milter - антивирус ClamAV.

/usr/sbin/postg - Postgrey, позволяющий принимать почту только с заданной попытки (проверка настойчивости внешнего MTA).

dovecot ... :143 - Dovecot IMAP.

dovecot ... :4190 - ManageSieve, сервер пользовательских фильтров.

master - это демон Posfix.

Здесь видно, что POP вообще отключен. IMAP (:143) висит только на внутреннем интерфейсе (это нормально, пока внешнего MUA-клиента нет) и отвечает за него - Dovecot.

Postfix слушает порт 25 (SMTP) на внешнем и внутреннем интерфейсе. Его основная функция - принимать почту для своего и только своего домена, а также отправлять свою и только свою почту.

587 порт тоже слушается Postfix на обоих интерфейсах и сконфигурирован на подключение MUA для отправки почты (отправляет ее наружу Postfix потом все равно с 25 порта, а ожидает ее от MUA для отправки - на 587).

При использовании только локального MUA, 587 порт можно закрыть для доступа снаружи, посредством Iptables (потом открыть в любой момент при необходимости).

LMTP работает через UNIX-сокет:

# netstat -l -p | grep lmtp
...
unix  2      [ ACC ]     STREAM     LISTENING     ...     .../dovecot        /var/spool/postfix/private/dovecot-lmtp
...

Пришло письмо снаружи, для получателя в родном домене

Пройдемся по всей цепочке вместе с письмом. Начинается всё для нашей почтовой системы с Postfix.

Postfix

Клиент (чужой MTA-сервер снаружи) подключается к 25 порту внешнего сетевого интерфейса.

Сервер Postfix-smtpd принимает подключение (в стандартном варианте) в любом случае. Далее клиент может писать почти любую чушь, пока не дойдет до команды rcpt to:. После получения этой команды наш сервер (Postfix-smtpd) проверяет некоторые параметры: client, helo, sender, recipient (эти слова присутствуют в именах параметров, в конфигурационных файлах Postfix).

client - это тот внешний сервер, который соединился и пытается доставить письмо.

helo, sender, recipient - это параметры внутри письма, не обязательно имеющие отношение к клиенту.

У клиента (client) проверяется наличие хоста и соответствие ему зарегистрированного в DNS - IP. Так же проверяется обратное - прописан ли для этого IP указанный хост (PTR).

helo задействует проверку по ряду параметров, включая проверку - не пытается ли клиент представится нашим родным доменом. Можно проверять - совпадает ли клиент с отправителем, но это настолько неправильно, что в Postfix для этого даже нет специальных директив в конфиге (нужно извращаться). И это не зря - многие нормальные отправители работают через релеи провайдера.

Получатель и отправитель, указанные в письме (recipient, sender) так же проверяются по ряду параметров.

Отправитель (sender, который не обязательно должен совпадать с клиентом) проверяется на предмет правильности доменной части (справа от @) - есть ли такой домен, есть ли у него правильный IP в DNS, и обратная запись PTR - есть ли у этого IP такой домен. Можно еще делать специальную проверку - коннектиться к серверу отправителя и имитировать отправку ему письма, чтобы узнать у сервера отправителя - есть ли такой отправитель, и принимает ли он письма (так например, отсекутся automailer'ы - уведомления от регистратора о конце срока оплаты за домен :), хотя их можно внести в белый список... - но это другая история).

Далее проверяется получатель (recipient). Тут всё немного интереснее.

Сначала конечно проверяется домен получателя - свой ли? Проверяется - есть ли такой получатель в списке почтовых ящиков.

Postfix подключается к SQL-базе PostfixAdmin и ищет почтовый ящик, а так-же активен ли он, если он нашелся (поле пароля Postfix вообще никогда не использует - в этом варианте конфигурации). Так же происходит проверка алиасов и пр.

Если ящик не найден Postfix еще на этапе SMTP-соединения даст отсечку (reject) клиенту и не примет письмо.

Если ящик найден, то Postfix записывает письмо (принимает) во временный "отстойник" (очередь) и продолжает свои дотошные проверки :) (на этом этапе в процессе начинает участвовать менеджер очереди сообщений Postfix - qmgr).

Но еще до очереди проверяется: включен ли для получателя автоответчик Vacation (это тоже отдельная история), происходит проверка на вирусы с использованием ClamAV, и проверка на наличие/отсутствие отправителя в спам-списках авторитетных внешних базах.

Также можно подключить почтовый фильтр Milter, использовать специальные проверки заголовка письма и его содержимого, проверять подпись DKIM, SPF, и даже использовать баллы (очки). Но это всё я здесь пока пропущу...

А вот о технологии PostGray (серые списки) упомяну вкратце. Работает это так. Postfix задерживает получение письма (дает отказ клиенту), одновременно внеся клиента в свой список. Нормальный клиент (не спамер) обязательно сделает еще не одну честную попытку через некоторое время отправить письмо. Во время повторного сеанса связи, Postfix найдет ранее сохраненную попытку в своем сером списке, и, убедившись в настойчивости клиента, - все-таки примет письмо со второго раза. Спамер обычно после первого отказа исчезает и больше не появляется, либо повторяет попытку слишком быстро и настойчиво.

После всех проверок Postfix письмо попадает в очередь, а после этого менеджер очереди определяет его дальнейшую судьбу. Если это письмо свое и должно быть доставлено в ящик - Postfix передает его Dovecot.

lmtp: Postfix - Dovecot

Письмо из очереди Postfix должно попасть к Dovecot. Для этого через заранее настроенный unix-сокет начинается обмен данными по протоколу LMTP. Unix-сокет представляет из себя файл, связанный в данном случае с процессом сервера Dovecot-lmtpd. Клиент (Postfix-lmtp) к примеру записывает данные "в файл", которые с другой стороны тут же считывает сервер (Dovecot-lmtpd). Т.е. запись в "сокет-файл", на диск, на самом деле не происходит{информация требует проверки и уточнения}, т.к. все данные перехватывает обратная сторона. Естественно пусть к файлу сокета, и у клиента, и у сервера в настройках должен быть одинаковым. Например: /var/spool/postfix/private/dovecot-lmtp

Чтобы писать/читать сокет, нужно иметь соответствующие права на файл или выступать от имени (под именем) соответствующего системного пользователя/группы (и Dovecot и Postfix умеют включать такую "мимикрию", т.к. главные демоны работают от имени root).

Dovecot

Итак Dovecot-lmtpd принимает эстафету от Postfix-lmtp (без "d" в конце!). В конечном итоге Dovecot должен-таки отправить письмо в конечную папку юзера, но перед этим он его тоже проверяет. Подключаются ACL (если они есть). ACL (Access Control List) - это список контроля. Он бывает глобальный (для всех), бывает персональный - для определенного ящика. Если не возникло никаких проблем - подключается Dovecot-Sieve. Это плагин (необязательный, как и quota, как и acl) в составе Dovecot. Плагин реализует одноименный язык (Sieve - это собственно название этого языка) описания правил фильтрации почтовых сообщений.

Пройдя все эти испытания :), письмо наконец попадает в конечный ящик (соответствующую папку пользователя).

Если испытания не пройдены (например исчерпана квота или отправитель письма занесен пользователем ящика в черный список), то посредством того же lmtp, Postfix получает соответствующий ответ, после чего, в зависимости от ситуации и настроек, отправляет специальное уведомление отправителю (приложив исходное письмо), либо поступает с этим письмом в соответствие с настройками для таких ситуаций{информация требует проверки и уточнения}.

Для проверки квоты (а так же чтобы узнать путь к конечной папке ящика и пр.), Dovecot делает запрос в SQL-базу PostfixAdmin.

Пришло письмо снаружи для чужого получателя

Предыдущий раздел обязателен к прочтению

В этом случае, в описываемой конфигурации, клиент получает отсечку (reject) с сообщением о том, что доступ в качестве релея запрещен. На самом деле релей работает, но только для доверенных сетей. Можно сделать совсем параноидально - ограничить доверие даже к локальной сети одним адресом ( mynetworks = 127.0.0.1/32 - в конфигах Postfix).

Пришло письмо от отправителя в родном домене, для получателя в родном домене

В том случае, если такое письмо доставляется от чужого сервера, - повторяется ситуация описанная в разделе - Пришло письмо снаружи, для получателя в родном домене. При этом, когда сервер проверяет отправителя письма (sender), то он проверяет сам себя. Проверка же клиента (чужого сервера, который осуществляет доставку) - происходит точно так же, как описано в упомянутом выше разделе - "со всей строгостью". Так же строго проверяется и получатель (recipient), и если он не будет найден, то письмо будет отброшено еще на этапе SMTP-соединения (т.е. даже не попадет в очередь) с соответствующим сообщением.

Отправка писем - общие сведения в контексте рассматриваемой конфигурации

Для начала одно важно замечание. Отправка письма состоит из двух этапов (сессий): прием письма от MUA и отправка письма далее по назначению. В первом случае Postfix выступает в роли сервера, во втором - в роли клиента. Таким образом может получиться так, что письмо будет принято к отправке от MUA но так и не уйдет. При этом MUA будет "ложно информирован" о том, что письмо якобы ушло и даже может поместить его в папку "Отправленные".

Есть два способа начать отправку почты. Подключиться изнутри на 25 порт, используя Postfix как релей (это разрешено для доверенных сетей, и локальный адрес 127.0.0.1 как раз относится к доверенным), или подключиться на 587 порт (Postfix) который как раз предназначен только для приема почты, которую необходимо отправить.

В первом случае (25 порт) аутентификация не требуется вообще (для localhost), во втором случае (587 порт) требуется не только аутентификация, но и обязательно использование TLS/SSL шифрования. Второй вариант можно, при необходимости, в любой момент открыть для доступа снаружи т.к. он достаточно защищен для этого. Первый вариант, упрощенный, удобен для использования сайтом или MUA установленным в той же локальной системе (хотя в описываемой конфигурации это не так - локальный MUA работает через 587 порт и использует шифрование, - это сделано для того, чтобы в будущем иметь возможность быстрее перенести его на другой сервер без дополнительной перенастройки, если это понадобится). Второй вариант (587 порт) здесь предусмотрен больше для задела на будущее - когда понадобится использование удаленного MUA (Outlook, Bat и т.п.).

В этом случае такое разделение функций между портами повышает общую надежность системы.

Кто сохраняет письмо в "Отправленные"

Чаще всего это делает MUA. Отправляя письмо, он выполняет две операции: отправляет письмо через SMTP + сохраняет копию в "Отправленные" (на сервере, если используется IMAP, либо только у себя, при использовании SMTP/POP). Если же письмо через SMTP отправляет, например сайт или спамер/хакер подключившийся посредством telnet и как-то узнавший пароль, либо заливший вредоносный скрипт на сервер, то контроль за отправленными письмами теряется. Тем не менее можно организовать контроль всех отправляемых писем (включая письма от несуществующего отправителя) и доставку копий всех отправленных в соответствующие ящики.

Подробнее о том, как это сделать, см. в заметке - Копии всех отправленных.

Письмо отправляемое через 587 порт

"Отправка писем - общие сведения в контексте рассматриваемой конфигурации" - обязательно к прочтению

Postfix

Первым в цепочке для отправляемого письма будет Postfix.

Обращения к 587 порту обрабатываются Postfix-сервисом submission.

В рассматриваемой конфигурации, на этот порт может подключиться только авторизовавшийся пользователь, использующий шифрование. Пользователь, подключившийся извне, сможет отправлять письма только от своего имени. Но если MUA - локальный (например RoundCube, установленный в той же системе, что и MTA), то он попадает в категорию доверенных и сможет отправлять письма от имени кого угодно (это регулируется в списке параметров для smtpd_sender_restrictions , в конфиге Postfix, и это доверие можно убрать).

В остальном поведение Postfix для удаленного и для локального MUA - одинаково.

Сбои в работе принимающего почту сервера

Если принимающий почту сервер отсутствует в сети (а резервного/ых нет), или если в его настройках допущена ошибка (о чем он сообщает MTA-клиенту), или если сервер перегружен, то MTA-клиент повторяет попытки доставить почту через определенные промежутки времени, заданное количество раз (такие попытки могут продолжаться например в течение суток). Количество попыток, их промежутки и продолжительность определяется настройками отправляющего почту MTA. Спамерские MTA обычно прекращают доставку после первой же неудачи.

Здесь описываются примеры для одного конкретного частного случая конфигурации почтовой системы.

Проверка отправки почты из PHP

Если в файле конфигурации PHP /etc/php5/apache2/php.ini параметр, отвечающий за определение механизма отправки почты sendmail_path закомментирован (обычно так и есть), то скорее всего это означает значение по умолчанию "/usr/sbin/sendmail -t -i".

Чтобы проверить отправку почты из PHP, нужно создать где-нибудь в доступном месте файл

mailtest.php :

<? 
$mailto = "mailto@domain.tld";
mail($mailto, "Test mail subject from PHP", "test mail body") or die("Error send mail from &lt;" . $mailto . "&gt;"); 
echo "Mail send to &lt;" . $mailto . "&gt;"; 
?>

Получив письмо на указанный в скрипте адрес (адрес здесь нужно заменить на свой валидный), имеет смысл изучить в нем отправителя и все заголовки. Если в заголовке присутствует имя скрипта - его можно удалить (см. как - по ссылке чуть ниже).

См. также раздел Postfix, Sendmail, Heirloom Mailx (nail) и PHP, в заметке Postfix - описание настроек, в контексте рассматриваемой конфигурации.

Там же описано, как для таких ситуаций изменить отправителя (обычно он, в лучшем случае: "www-data@domain.tld"), а также: как Postfix безболезненно подменяет Sendmail.


Источники

Источники информации и ссылки перечислены на отдельной странице, указанной внизу главной страницы темы:
Установка и настройка почтового сервера

Оставьте комментарий

Вы можете войти под своим логином или зарегистрироваться на сайте.