web-dev-qa-db-ja.com

procmailで特定のメールを拒否することは可能ですか? [SMTPセッションでは、電子メールの内容に基づいて拒否します]

Procmailがsendmailから呼び出され、受信メールを正しいメールボックスにフィルタリングする典型的な設定を想定しましょう。 sendmailへの着信SMTP接続がまだアクティブな間に実行されますか、それとも電子メールがすでに受け入れられた後に実行されますか?

前者の場合、procmailがsendmailにエラーを返し、sendmailがエラーコード(たとえば、554 Transaction failedを受け入れながら SMTP DATA )で応答する可能性があることを理解しています。通常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:<[email protected]>
S: 250 Ok
C: RCPT TO:<[email protected]>
S: 250 Ok
C: RCPT TO:<[email protected]>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Bob Example" <[email protected]>
C: To: "Alice Example" <[email protected]>
C: Cc: [email protected]
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ですが、 DATA request に応答して有効なエラーである可能性があります。そして、クライアントはQUITで応答する場合としない場合がありますが、私は気にしません。

これはおそらく、SMTPプロトコルがTCPレベルでどのように実装されているかに依存します。クライアントから受信するDATAの量を、たとえば、最初の50バイトに制限できますか(たとえば、 TCP frame)?SMTPプロトコルでは、クライアントがDATAのコンテンツを送信しているときにエラーで応答できますか?

また、サーバーがDATAの最初の部分を受信した後に意図的に切断した場合(クライアントにエラーを送信しようとするのではなく)、送信中にTCP接続が誤って切断されたのと同じです。電子メール:正常に動作するMTAは、電子メールの再接続と再配信を試みますが、スパマーはおそらく再試行する必要はありません。

1
Greg

あなたが説明していることは完全に実行可能ですが、Sendmailwillはこの状況でバウンスメッセージを生成します。これはプロトコル設計の一部です。これを行う方法は、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が何でも処理できるようにするには、メッセージ全体をすでに受信している必要があります。この後期段階でSMTPDATAトランザクションを明示的に失敗させることは、受信を元に戻すことができないため、かなり無意味です。 DATAが完了したら、メッセージを黙って捨てたい場合は、/dev/nullに配信してください。

とはいえ、できるだけ早く拒否することは有益です。不正な送信者に対してIPレベルのブロックを実装できれば、ネットワークスタック上ではるかに単純で穏やかになります。 (私が読んでいる「ゾンビネットワーク」の行の間-これらの送信者が、たとえばSpamhaus DNSBLによってブロックされているかどうか知っていますか?)

1
tripleee

Milter(MIMEDefang.org milterなど)の使用を検討しましたか?
MIMEDefangの動作は、カスタマイズ可能なPerlスクリプトによって制御されます。メッセージの内容に基づいて、SMTPセッションで拒否を取得できるはずです。また、ソリューションを他のMTAに移植できるようにします。後置。

従来のMIMEDefangの例には、SpamAssassin(spamines)スコアが高いメッセージの拒否が含まれます。それだけでそのような電子メールのほとんどをブロックする可能性があります。

1
AnFi

Procmailは、メールが受信された後に実行されるローカルメーラーとして機能すると思います。基本的に、それは配信の次のステップです。したがって、sendmailプロセスへの電子メールを受け入れている接続には影響しません。メールをローカルで別のローカルユーザーに送信する場合の別の例を考えてみてください。最初にsendmailプロセスに受け入れられ、他のローカルユーザーが見つからない場合は、別の電子メールでエラーメッセージが表示されます。

1
Petr Chloupek