6. 問題検出と処理 (Problem Detection and Handling)
このセクションでは、メール送信中に発生するさまざまな問題をSMTP実装がどのように処理すべきかについて説明する。
6.1. 信頼できる配信と電子メールによる応答 (Reliable Delivery and Replies by Email)
配信状態通知 (Delivery Status Notifications, DSN)
メールを配信できない場合、送信システムは、送信者に通知するために配信状態通知 (バウンスメッセージ) を生成すべきである (SHOULD)。
DSN要件:
- リバースパス (MAIL FROMアドレス) に送信されなければならない (MUST)
- ループを防ぐためにヌルリバースパス (
MAIL FROM:<>) を使用しなければならない (MUST) - 元のメッセージまたはヘッダーを含むべきである (SHOULD)
- 失敗の理由を指定すべきである (SHOULD)
タイムアウトと再試行
再試行スケジュール:
- 初回失敗: 30分後に再試行
- その後の失敗: 指数バックオフ (1時間、2時間、4時間など)
- 最大再試行期間: 少なくとも4〜5日
- 最終的な失敗: 送信者にバウンスを送信
警告メッセージ:
- 4〜6時間後: 送信者に遅延警告を送信
- 遅延の理由を含む
- 配信試行が継続していることを送信者に通知する
6.2. 望ましくない、未承諾、および「攻撃」メッセージ (Unwanted, Unsolicited, and "Attack" Messages)
SMTPサーバーは、悪用に対する保護を実装すべきである (SHOULD):
スパム防止
技術:
- 受信者検証: メールを受け入れる前に受信者が存在することを確認する
- 送信者検証: SPF、DKIM、DMARCをチェックする
- レート制限: 接続/時間ごとのメッセージを制限する
- グレイリスティング: 初めての送信者を一時的に拒否する
- コンテンツフィルタリング: スパムパターンのメッセージコンテンツをスキャンする
- レピュテーションシステム: 送信者のレピュテーションを追跡する
サービス拒否 (DoS) 保護
防御:
- 接続制限: 単一IPからの同時接続を制限する
- レート制限: 秒ごとのコマンドを制限する
- ターピット: 疑わしい送信者を遅くする
- リソース制限: 接続ごとのCPUとメモリ使用量に上限を設ける
- タイムアウトの強制: アイドル接続を切断する
ディレクトリハーベスト攻撃 (DHA)
攻撃者は、推測されたアドレスでRCPT TOコマンドを送信して、有効なメールボックスを見つける。
対策:
❌ 脆弱:
C: RCPT TO:<[email protected]>
S: 550 No such user (無効を明らかにする)
C: RCPT TO:<[email protected]>
S: 250 Ok (有効を明らかにする)
✅ 保護:
- RCPTコマンドへの応答を遅延させる
- 有効と無効に同じ応答を使用する (例: 常に「250 Ok」)
- DATAの間または後にのみ受信者を検証する
- RCPTコマンドをレート制限する
バックスキャッター防止
バックスキャッター: 偽造された送信者アドレスに送信されるバウンスで、付随的なスパムを作成する。
防止:
- SMTP時に拒否: SMTPトランザクション中 (DATAの前) に無効な受信者を拒否する
- 送信者の検証: 偽造された送信者からのメールを受け入れない
- バウンスを生成しない: 不明/疑わしい送信元からのメールに対して
6.3. ループ検出 (Loop Detection)
メールループは、メッセージが同じサーバーを繰り返し転送されるときに発生する。
検出方法
方法1: Receivedヘッダー数
メッセージ内のReceivedヘッダーを数える
カウント > 100の場合:
「554 5.4.6 Too many hops」で拒否
方法2: Receivedヘッダー分析
Receivedヘッダーを解析
現在のサーバーが複数回表示されるかチェック
はいの場合:
ループを検出して拒否
方法3: Message-ID追跡
最近処理されたメッセージのMessage-IDを記憶
短時間内に同じMessage-IDが再び見られた場合:
おそらくループ、拒否
ループ防止
ベストプラクティス:
- ホップ制限: 50〜100のReceivedヘッダーの後に拒否する
- パターン検出: トレース内の繰り返しサーバー名を識別する
- ループの中断: ループしているように見えるメールを転送しない
- 構成レビュー: ループを作成する転送規則を避ける
6.4. 不規則性の補償 (Compensating for Irregularities)
実世界のSMTP実装は、時々標準から逸脱する。堅牢な実装は、一般的な不規則性を優雅に処理すべきである (SHOULD)。
一般的な不規則性
1. 余分な空白
一部の実装は余分なスペースを送信する:
❌ 非標準:
C: MAIL FROM: <[email protected]> (余分なスペース)
✅ 堅牢な処理:
正しく受け入れて解析する
2. 大文字小文字が混在したコマンド
❌ 非標準:
C: Mail From:<[email protected]>
✅ 堅牢な処理:
大文字小文字を区別しないものとして扱う
3. 角括弧の欠落
一部の古いシステムは、アドレスの周りの <> を省略する:
❌ 非標準:
C: MAIL FROM:[email protected]
✅ 堅牢な処理:
括弧ありとなしの両方を受け入れる
4. CRまたはLFのみ (CRLFではない)
標準はCRLF (\r\n) を要求するが、一部はLF (\n) またはCR (\r) のみを送信する:
✅ 堅牢な処理:
CR、LF、またはCRLFを行終端記号として受け入れる
(ただし、常にCRLFを送信する)
5. 長い行
一部の実装は、制限を超える行を送信する:
✅ 堅牢な処理:
- 512オクテットより長い行を受け入れる
- 必要に応じて内部的に分割する
- SMTPトランザクション中に中断しない
堅牢性の原則
「送信するものは保守的に、受け入れるものは寛大に」
- 送信: 標準に厳格に準拠する
- 受信: 小さな逸脱を優雅に受け入れる
- ログ記録: 非標準動作を記録する
- しない: 黙って修正して転送しない (相互運用性の問題を維持する)