メールがPostfixによってどのように正確に処理されるか、およびSMTPメールトランザクションの詳細の一部を理解しようとしています。私の短期的な目標は、プロプライエタリ(バイナリ、クローズドソース)のSMTPクライアントをデバッグすることですが、最初に、成功したSMTPトランザクションで何が起こるかを調べようと思いました。
私はLANファイアウォールで送信SMTP(ポート25)をブロックする予定なので、Postfixを内部メールサーバーとして構成し、認証されていないSMTP(ポート25経由)経由でのみメールを送信できる(プリミティブ)ローカルクライアントソフトウェアからのメールを受け入れます。
Postfixログを使用したトラブルシューティング の説明に従って、-v
verboseフラグをmaster.cf
に追加することにより、Postfix smtpd
プロセスのデバッグをオンにしました。次に、 sSMTP (sendmail
の最小実装)を指定したCygwin Muttを使用して、自分のワークステーションからメールを送信しました。
Postfixログは、RCPT TO:
行が正常に処理され、受信者のアドレスが受け入れられると、Postfixのsmtpd
がトランザクションにキューIDを割り当て、250 OK
でSMTPクライアント(sSMTP)に応答したことを示しています。
ただし、DATA
コマンドを発行する代わりに、SMTPクライアントがRSET
を発行して現在のメールトランザクションをリセット/中止し、Postfixが250 OK
で応答しました。
このコマンドコマンドが何をするかについていくつかの調査を行いましたが、当然のことながら Simple Mail Transfer Protocol、RFC 2821 が最も包括的な情報を提供しました。
このコマンドは、現在のメールトランザクションが中止されることを指定します。保存されている送信者、受信者、およびメールデータは破棄する必要があり、すべてのバッファと状態テーブルをクリアする必要があります。受信者は、引数なしでRSETコマンドに「250 OK」応答を送信する必要があります。リセットコマンドは、クライアントがいつでも発行できます。これは、EHLOの直後、セッションでEHLOが発行される前、データの終了インジケーターが送信されて確認された後、またはQUITの直前に発行された場合、実質的にNOOPと同じです(つまり、効果がない場合)。 SMTPサーバーは、RSETを受信した結果として接続を閉じてはなりません(MUST NOT)。そのアクションはQUIT用に予約されています(セクション4.1.1.10を参照)。
EHLOはサーバーによる追加の処理と応答を意味するため、正式なセマンティクスが同じであっても、RSETは通常、そのコマンドを再発行するよりも効率的です。
この仕様の意図とは逆に、SMTPサーバーが基になるTCP=接続が閉じられたかリセットされたという通知を受け取る場合があります。メールシステムの堅牢性を維持するには、 SMTPサーバーはこの状態に備えるべきであり(SHOULD)、接続が消える前にQUITが受信されたかのように処理する必要があります(SHOULD)。
上記はすべて1秒以内に行われたため、タイムアウトの問題は発生しません。
次の1秒で、クライアントは別のRSET
を送信しましたが、クライアントは10秒待ってからMAIL FROM:
、RCPT TO:
で再起動しましたが、今回はDATA
コマンドを発行してトランザクションが完了しました(ログによると、すべて同じ1秒以内です。
基本的に、SMTPクライアントがRSET
コマンドの代わりにDATA
コマンドを発行することによって、独自のトランザクションを中断するのはなぜだろうと思います。
ノート:
質問を編集してメールログファイルからの抽出を含めることもできますが、-v
デバッグを使用すると、非常に冗長になり、無関係なデータの火に人を圧倒したくありません。
SSMTPソースコードを検索しましたが、RSET
についての言及は見つかりませんでした。
なぜSMTPクライアントがDATAコマンドの代わりにRSETコマンドを発行して独自のトランザクションを中断するのかと思っていました。簡単に言えば、そうではありません。これは、アンチウイルスソフトウェアによって傍受されているSMTP接続の症状です。
SSMTPの構成でデバッグオプションを有効にしましたが、CygwinプロセスからのメッセージがWindowsイベントビューアではなく/var/log/messages
に記録されるように、Cygwinにsyslogをインストールして構成する方法を理解するのに少し時間がかかりました。
ただし、最初のMAIL FROM:
およびRCPT TO:
コマンドのみがログに記録されました。これらのコマンドが2回以上送信されたか、またはsSMTP
がRSET
コマンドを送信したという兆候はありませんでした。
私の質問で述べたように、sSMTPソースコードをチェックしましたが、RSET
コマンドを送信するコードがありません。
ユーザーmasegaloehは、ウイルス対策ソフトウェアがSMTPパケットを変更している可能性があることを示唆しました-そして彼は正しかった:私は一時的にコンピューターのSymantec Endpoint Protectionを無効にし、SMTPトランザクションは通常どおりに進行しました。
Symantec Endpoint Protectionを再度有効にした後、TCP接続を監視しました Windows Sysinternals からTCPViewユーティリティを使用して)== Symantec ccSvcHst.exe
プロセスが、宛先ポートが25であるすべてのTCPトラフィックをプロキシしていたことを確認してください。
メールサーバーのポート25にtelnet接続し(netcatはおそらくシマンテックのインターセプトが原因で正しく機能しません)、SMTPコマンドを手動で入力してテストメールを送信しました。同時に、Sudo tail -F /var/log/maillog
の実行中にメールホストへのSSH接続を使用して別のターミナルウィンドウを開き、SMTPサーバーの表示を同時に監視しました。
シマンテックプロキシによって実行される傍受はわずかです。メールクライアントの観点からは、SMTPサーバーと直接通信していないことはほとんどありません。ほとんどのコマンドは送信時にメールサーバーに渡され、期待どおりの応答になります。 DATA
コマンドを入力するまで、Symantecプロキシは物事を変更し始めませんでした。
354 Please start mail input.
これは正常に見えますが、実際には、私のPostfixサーバーからの応答は
354 End data with <CR><LF>.<CR><LF>
また、実際にDATA
コマンドをPostfixに渡さなかったのは、メッセージ本文を完成させ、その後にQUIT
を続けた後です。
注:テストメッセージの内容を入力している間、SymantecプロキシはNOOP
コマンドを発行して、Postfixサーバーへの接続を維持しました。
私の質問で、私の最終的な目標は、組織で使用されている専用(バイナリ、クローズドソース)メールクライアントのトラブルシューティングであると述べました。私はこのクライアントが本当にバグがあることを発見しました:無効なHELO
コマンド(ホスト名なし)を送信し、SMTPサーバーからその構文が間違っていると丁寧に通知された後、単にあきらめてQUITします。 HELO
を必要としないようにPostfixを構成しました(有効またはそれ以外)。
私はこの問題を解決するために、十分な最新のPostfixバージョンが付属するCentOS 7を備えた新しいサーバーをインストールし、 postfix HELOチェックを完全に無効にする (MS Exchangeが無効なHELOコマンドを単に無視する方法と同様です)。
SMTPトランザクションでのRSET
の一般的な使用法についても疑問に思っていたところ、SMTPの元の RFC 821 で次のことがわかりました。
このコマンドは、現在のメールトランザクションを中止することを指定します。保存されている送信者、受信者、およびメールデータは破棄し、すべてのバッファと状態テーブルをクリアする必要があります。受信者はOK応答を送信する必要があります。
RSET
は、受信者の電子メールアドレスが存在しないユーザーのものであることが判明した場合に使用されます。次のSMTPトランザクションは、Aborted SMTP Transaction Scenarioの例です。
R: 220 MIT-Multics.ARPA Simple Mail Transfer Service Ready
S: HELO ISI-VAXA.ARPA
R: 250 MIT-Multics.ARPA
S: MAIL FROM:<[email protected]>
R: 250 OK
S: RCPT TO:<[email protected]>
R: 250 OK
S: RCPT TO:<[email protected]>
R: 550 No such user here
S: RSET
R: 250 OK
S: QUIT
R: 221 MIT-Multics.ARPA Service closing transmission channel
SMTPクライアントは、同じSMTP接続を使用して、複数のメッセージを同じ宛先に送信できます。この機能はPostfixではSMTP接続キャッシングと呼ばれています。このパフォーマンス機能を使用する場合、Postfixは各MAIL FROM
コマンドの前にRSET
を送信して、SMTP接続がまだ使用可能であることを確認します( Postfix接続キャッシュ を参照)。