Пересылка почты - примеры работы системы в разных ситуациях
Краткое описание подопытной конфигурации. Список портов и интерфейсов. Примеры прохождения письма по всей цепочке внутри системы. Ответы на некоторые вопросы, которые могут возникнуть по принципам работы и настройке рассматриваемого набора программ почтовой системы и разбираемого в этой серии заметок частного случая их конфигурации.
ВАЖНО! Эта страница является частью списка заметок о настройке почтовой системы (Postfix+Dovecot и пр.).
Родительская страница - обязательна к просмотру: Установка и настройка почтового сервера
Подробнее о конфигурации к которой относятся примеры в этой статье - см. ссылку выше.
Тем же - коротко об основных терминах (MTA, MDA, MUA и т.п.).
Эта заметка имеет характер исследования. Все упомянутые в заметке эксперименты проводились на ОС Debian. Пожалуйста не используйте слепое копирование примеров. Автор не гарантирует, что применение изложенной здесь информации не приведет к потере данных.
Содержание
- Порты
- Пришло письмо снаружи, для получателя в родном домене
- Пришло письмо снаружи для чужого получателя
- Пришло письмо от отправителя в родном домене, для получателя в родном домене
- Отправка писем - общие сведения в контексте рассматриваемой конфигурации
- Кто сохраняет письмо в "Отправленные"
- Письмо отправляемое через 587 порт
- Сбои в работе принимающего почту сервера
- Проверка отправки почты из PHP
- Источники
Порты
Все ненужные порты можно закрыть снаружи 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
Пришло письмо от отправителя в родном домене, для получателя в родном домене
В том случае, если такое письмо доставляется от чужого сервера, - повторяется ситуация описанная в разделе - Пришло письмо снаружи, для получателя в родном домене. При этом, когда сервер проверяет отправителя письма (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 для удаленного и для локального MUA - одинаково.
Сбои в работе принимающего почту сервера
Если принимающий почту сервер отсутствует в сети (а резервного/ых нет), или если в его настройках допущена ошибка (о чем он сообщает MTA-клиенту), или если сервер перегружен, то MTA-клиент повторяет попытки доставить почту через определенные промежутки времени, заданное количество раз (такие попытки могут продолжаться например в течение суток). Количество попыток, их промежутки и продолжительность определяется настройками отправляющего почту MTA. Спамерские MTA обычно прекращают доставку после первой же неудачи.
Проверка отправки почты из PHP
Если в файле конфигурации PHP /etc/php5/apache2/php.ini
Чтобы проверить отправку почты из PHP, нужно создать где-нибудь в доступном месте файл
mailtest.php
<? $mailto = "mailto@domain.tld"; mail($mailto, "Test mail subject from PHP", "test mail body") or die("Error send mail from <" . $mailto . ">"); echo "Mail send to <" . $mailto . ">"; ?>
Получив письмо на указанный в скрипте адрес (адрес здесь нужно заменить на свой валидный), имеет смысл изучить в нем отправителя и все заголовки. Если в заголовке присутствует имя скрипта - его можно удалить (см. как - по ссылке чуть ниже).
См. также раздел Postfix, Sendmail, Heirloom Mailx (nail) и PHP, в заметке Postfix - описание настроек, в контексте рассматриваемой конфигурации.
Там же описано, как для таких ситуаций изменить отправителя (обычно он, в лучшем случае:
Источники
Источники информации и ссылки перечислены на отдельной странице, указанной внизу главной страницы темы:
Установка и настройка почтового сервера
Оставьте комментарий
Вы можете войти под своим логином или зарегистрироваться на сайте.