Назад | Перейти на главную страницу

Можно ли отклонять определенные письма в procmail? [В сеансе SMTP отклоняется на основе содержимого электронной почты]

Давайте предположим типичную настройку, в которой procmail вызывается из sendmail для фильтрации входящих писем в правильные почтовые ящики. Это делается, пока входящее SMTP-соединение с sendmail все еще активно, или это делается после того, как электронное письмо уже было принято?

Если первое, то я понимаю, что procmail может вернуть sendmail ошибку, чтобы sendmail ответил кодом ошибки, например 554 Transaction failed принимая ДАННЫЕ SMTP, вместо обычных 200?

В моем случае sendmail вызывает procmail из базы данных псевдонимов с такими записями:

theaddres:   theaddres-somedomain-com.virtual

theaddres-somedomain-com.virtual:   |"/usr/libexec/sm.bin/someuser.virtual somedomain@theaddress"

Затем выполняется сценарий procmail:

root@mda:/etc/mail # less /usr/libexec/sm.bin/someuser.virtual 
/usr/local/bin/procmail -a $1 /usr/local/etc/procmailrc/someuser.virtual

РЕДАКТИРОВАТЬ:

Добавляем более подробное объяснение. Во-первых, я хотел бы установить, если описанный ниже поток, основанный на Пример Википедии, возможно в протоколе SMTP вообще. Если да, то если это возможно с помощью procmail. Затем, если нет (что, я думаю, так), если существует реализация (например, milter), в которой это было бы возможно.

S: 220 smtp.example.com ESMTP Postfix
C: HELO relay.example.org 
S: 250 Hello relay.example.org, I am glad to meet you
C: MAIL FROM:<bob@example.org>
S: 250 Ok
C: RCPT TO:<alice@example.com>
S: 250 Ok
C: RCPT TO:<theboss@example.com>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Bob Example" <bob@example.org>
C: To: "Alice Example" <alice@example.com>
C: Cc: theboss@example.com
C: Date: Tue, 15 January 2008 16:02:43 -0500
C: Subject: Test message
C: 
C: Hello Alice.
C: This is a test message with 5 header fields and 4 lines in the message body.

Now this is what I would like to see:
S (after receiving the first 2 lines out of 4): 452 Requested action not taken: insufficient system storage
C: QUIT
S: 221 Bye
{The server closes the connection}

Таким образом, сервер перестает получать электронное письмо (например, потому, что он обнаружил в электронном письме последовательность «Это тестовое сообщение») и отвечает клиенту с ошибкой. В данном случае это 452, но это может быть любая ошибка, действительная в ответ на Запрос данных. И клиент может или не может ответить QUIT, мне все равно.

Вероятно, это зависит от того, как протокол SMTP реализован на уровне TCP. Могу ли я ограничить количество ДАННЫХ, полученных от клиента, скажем, 50 начальными байтами (например, путем ограничения размера кадра TCP)? Позволяет ли протокол SMTP мне отвечать с ошибкой, когда клиент отправляет содержимое DATA?

Кроме того, если сервер намеренно отключился после получения начальной части ДАННЫХ (вместо попытки отправить клиенту ошибку), это не будет отличаться от случайного разрыва TCP-соединения при передаче электронной почты. Хорошо работающий MTA попытается повторно подключиться и повторно доставить электронное письмо, спамер, вероятно, не потрудится повторить попытку.

Рассматривали ли вы использование milter (например, MIMEDefang.org milter)?
Поведение MIMEDefang контролируется настраиваемым сценарием Perl. Должна быть возможность получать отказы в сеансе smtp на основе содержимого сообщения. Это также сделает решение переносимым для других MTA, например. постфикс.

Классические примеры MIMEDefang включают отклонение сообщений с высоким рейтингом SpamAssassin (спам). Только он может блокировать большинство таких писем.

Я думаю, что procmail действует как локальная почтовая программа, которая запускается после того, как письмо принято. По сути, это следующий шаг в доставке. Таким образом, это не может повлиять на соединение, которое принимает электронную почту к процессу sendmail. Подумайте о другом примере, когда вы отправляете электронное письмо локально другому локальному пользователю. Сначала он принимается в процессе sendmail, и если другой локальный пользователь отсутствует, вы получите сообщение об ошибке по другому адресу электронной почты.

То, что вы описываете, вполне возможно, но Sendmail воля в этой ситуации создать рикошет; это часть конструкции протокола. Способ сделать это - завершить работу Procmail с помощью подходящего кода выхода, чтобы сообщить причину возврата обратно в Sendmail.

Например, чтобы вернуть ошибку «пользователь неизвестен»,

:0
* ^Received: from badhelo \(badhost \[10\.9\.8\.7\]\) by yourhost
{ EXITCODE=67 HOST= }

В EXITCODE указывает код возврата, с которым нужно выйти, и переназначение HOST имеет неясный, но хорошо задокументированный побочный эффект немедленного прекращения работы Procmail.

Видеть http://www.iki.fi/era/procmail/mini-faq.html#exitcode для получения более подробной информации, например, sysexits.h для списка фактических кодов выхода.

Вы не сможете контролировать, произойдет ли это во время или после завершения SMTP-транзакции. Насколько я помню, когда Sendmail был еще популярен, он на самом деле обрабатывал правила Procmail во время получения сообщения, но это деталь реализации, которая может зависеть от различных обстоятельств и, возможно, меняться между версиями. В любом случае SMTP - это протокол с промежуточным хранением; если транзакция завершилась неудачно и клиент уже отключился, сервер попытается подключиться обратно к серверу MX отправителя, чтобы доставить возврат. (Бывают ситуации, когда это нежелательно; например, отскок для отскока не должен генерироваться и доставляться.)

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

Тем не менее, выгодно отказаться как можно раньше. Если вы можете реализовать блокировку IP-уровня для плохих отправителей, это будет намного проще и мягче в сетевом стеке. (Между строк я читаю «сеть зомби» - знаете ли вы, заблокированы ли эти отправители, например, DNSBL Spamhaus?)