用語 · メールプロトコルSMTP

メールプロトコルSMTPとは何か、アプリケーションのメールにどう影響するのか

SMTP(Simple Mail Transfer Protocol、簡易メール転送プロトコル)は、メールシステムが送信メールのサブミッション、リレー、受け渡しに使う標準ベースのプロトコルです。アプリケーションは通常、完成したメッセージを認証付きのサブミッションサービスに渡し、その後メールサーバーがSMTPのコマンドとDNSによるルーティングを使って、各受信者に向けてメッセージを運びます。SMTPの応答からは、特定のホップが受信者を受け付けたか拒否したかがわかりますが、受け付けは受信トレイへの到達と同じではありません。アプリケーションには引き続き、永続的なキュー、安全な再試行、メッセージ識別子、認証、バウンス処理が必要です。

SMTPは責任を持つシステム間でメールを転送する

SMTPはストアアンドフォワード型の転送プロトコルです。クライアントはサーバーとのセッションを開き、自身を名乗り、エンベロープの送信者を提示し、1つ以上のエンベロープの受信者を提案し、サーバーが受信に同意した後でメッセージの内容を送信します。サーバーは一部の受信者を受け付けて他を拒否できるため、ステータスはメッセージ全体だけでなく、受信者とトランザクションに属します。サーバーは責任を引き受けると、ローカルに配信するか、DNSのMail Exchanger(MX)レコードで選ばれた別のシステムに向けてメッセージをリレーします。このホップごとの設計があるからこそ、アプリケーションはメールの状態を「送信済み」というひとつの真偽値に集約すべきではありません。アプリケーション、サブミッションサービス、リレー、受信サーバー、メールボックスのフィルタリングシステムは、それぞれ結果の異なる部分を把握しています。SMTPはシステム間でメッセージを運び、プロダクト側の記録とプロバイダーのイベントが、その動きをユーザーと運用担当者に理解できる形にします。

サブミッションとリレーはプロトコル上の異なる役割

RFC 6409は、メッセージのサブミッションとメッセージのリレーを区別しています。サブミッションは、許可されたユーザーやアプリケーションからMessage Submission Agentへの最初の受け渡しで、通常はポート587を使います。リレーはMessage Transfer Agent間の転送で、慣例としてポート25を使います。サブミッションサービスは、誰が新しいメールを投入しているかを把握しているため、認証を要求し、メッセージのフィールドを検証または補完し、送信者ポリシーを適用できます。公開のリレーサーバーは他のドメインと相互運用する必要があり、異なる信頼ルールに従います。したがって、アプリケーションのコードは、宛先サーバーに対して任意にポート25の接続を開くのではなく、プロバイダーが文書化しているサブミッション用エンドポイントに接続するか、そのHTTP APIを使うべきです。この区別によって認証情報の意味も明確になります。SMTPのユーザー名やトークンは特定のサービスへのサブミッションを許可するものであり、宛先ドメインに対する権限を与えるものではありません。サブミッション用の認証情報はサーバー側に置き、プロバイダーが対応していれば送信ワークロードにスコープを限定し、メッセージの内容やクライアントソフトウェアに埋め込むことなくローテーションしてください。

SMTPのエンベロープは表示されるメッセージヘッダーとは異なる

SMTPのトランザクションは、`MAIL FROM`と1つ以上の`RCPT TO`コマンドからなるエンベロープを運びます。転送される内容はそれとは別に、RFC 5322で定義されたインターネットメッセージ形式に従い、From、To、Date、Subject、Message-IDなどのフィールドと本文で構成されます。MIMEの標準は、HTML、代替パート、添付ファイル、非ASCIIデータのためにこの内容を拡張します。エンベロープの送信者は転送の失敗時に使われるアドレスで、表示上のFromの作成者とは異なる場合があります。エンベロープの受信者も、Bccのように、表示上のToやCcのフィールドとは異なる場合があります。これらの構造を、信頼できない文字列の連結で組み立ててはいけません。メンテナンスされているメッセージライブラリを使い、アドレスを検証し、ヘッダーフィールドへの改行インジェクションを防ぎ、安定したMessage-IDを維持してください。トラブルシューティングでは両方の層を確認します。表示上のFromフィールドが正しくても許可されていないエンベロープのIDは修復できず、エンベロープが有効でも不正な形式のMIMEが正しく表示されるようにはなりません。

トランザクションをステートマシンとして読む

基本的なExtended SMTP(ESMTP)のセッションは、サーバーのグリーティングで始まり、次にサーバーが拡張機能を通知できるよう`EHLO`を送ります。サブミッションでは、クライアントがTLSと認証をネゴシエートすることがあります。その後のメールトランザクションでは、`MAIL FROM`、宛先ごとに1つの`RCPT TO`、`DATA`、SMTPのフレーミングに従って終端された完全なメッセージ、そして`QUIT`を使います。この例を、ワイヤープロトコルを手作業で実装する理由にしてはいけません。成熟したSMTPライブラリのほうが、改行コード、ドットの透過処理、機能のネゴシエーション、認証、TLSの状態をより安全に扱えます。認証情報やメッセージ本文全体をログに残さずに、コマンドの種類と応答コードのレベルでライブラリを計測してください。どの受信者がどの段階で失敗したか、そしてメッセージデータの送信後にサーバーが責任を引き受けていたかどうかを記録します。この境界によって、再試行が適切かどうか、重複が起こりうるかどうか、そして失敗が即時の応答ではなく後から届く配信状態通知で伝えられるかどうかが決まります。

再試行を決める前に応答コードを分類する

SMTPの応答クラスは、取るべきアクションを伝えます。2xxの応答は、そのコマンドが正常に完了したことを示します。4xxの応答は一時的な否定完了であり、キューを持つ送信者は時間をおいて再試行できます。5xxの応答は試みたコマンドに対する恒久的な否定完了であり、通常は再試行を繰り返すのではなく、修正、サプレッション、人による調査が必要です。拡張ステータスコードは、アドレス、メールボックス、システム、ルーティング、プロトコル、内容、セキュリティとポリシーの状態について、構造化された`X.Y.Z`の診断を追加します。数値コードとサーバーのテキストはどちらも診断に役立つことがあるため両方を保存しますが、受信者データを含むrawの応答を広く公開してはいけません。一時的な失敗には、ジッター付きの指数バックオフとキューの最大存続期間を適用してください。一時的な宛先の問題が迷惑なトラフィックに変わるほど積極的に再試行してはいけません。アドレスの恒久的な失敗であれば、その宛先への自動送信を止め、サプレッションの状態を更新します。ポリシーや認証の失敗であれば、次の試行の前にID、DNS、認証情報、内容を修正してください。

暗号化され認証されたサブミッションを使う

SMTPは、信頼の前提が異なるネットワーク間の転送プロトコルとして始まったため、安全なサブミッションは拡張機能とデプロイ時のポリシーに依存します。STARTTLSはSMTPの接続をTLSにアップグレードするもので、その後クライアントはハンドシェイク前に得た機能情報を破棄し、改めて`EHLO`を送る必要があります。RFC 8314はサブミッションに関するガイダンスを更新し、平文でのアクセスとサブミッションを廃止されたものとして扱い、サブミッションでの暗黙的TLSについて説明しています。RFC 4954で標準化されたSMTP AUTHにより、サブミッションサーバーは通知したメカニズムを通じてクライアントを認証できます。組み合わせを推測するのではなく、プロバイダーの最新のホスト名、ポート、TLSモード、認証の手順を使ってください。サーバー証明書を検証し、ワークロードに保護されたサブミッションが必要な場合は、黙って平文にフォールバックしないようにします。パスワードやトークンはシークレットマネージャーに保管し、環境ごとに別の認証情報を使い、廃止された認証メカニズムは無効にしてください。TLSが保護するのは接続のひとつのホップであり、後段のすべての受信側に対してメッセージの作成者を認証するものでも、SPF、DKIM、DMARCによるIDのアライメントに取って代わるものでもありません。

アプリケーションメールの失敗をホップごとに診断する

まず、アプリケーションの永続的な送信記録から始めます。プロダクトのイベントは許可されたものだったか、それを取得したキューのジョブは1つだけだったかを確認します。次に、サブミッションを調べます。DNSの名前解決、TCP接続、TLSのネゴシエーション、証明書の検証、認証、エンベロープの送信者の許可、受信者ごとの応答、最後のDATAに対する応答です。サブミッションサービスがメッセージを受け付けていたなら、リクエストをやみくもに再実行するのをやめ、そのメッセージ識別子とイベントストリームを追ってください。プロバイダーが処理した状態と、受信サーバーによる受け付けを区別します。最初に受け付けられた後でも、後から届くバウンスで恒久的な失敗が報告されることがあります。受信サーバーがメッセージを受け付けていた場合は、SMTPの転送の失敗とみなすのではなく、認証の結果、レピュテーション、受信者のポリシー、内容、メールボックスでの分類を調査してください。エンベロープとヘッダーの両方のIDを確認し、タイムスタンプ、応答コード、キューでの試行回数、プロバイダーの識別子を保存します。テストには管理下の受信者を使ってください。本番環境のSMTP認証情報や顧客のメッセージ全体を、チケット、プロンプト、ターミナルの履歴、公開の診断ツールに貼り付けてはいけません。

受け付け、配信、受信トレイへの到達を区別する

プロダクトのインターフェースでは、プロトコル上の正確さが重要です。アプリケーションによる受け付けは、ローカルのシステムがリクエストを記録したことを意味します。サブミッションでの受け付けは、最初のメールサービスが処理の責任を引き受けたことを意味します。受信サーバーへの配信は、宛先のSMTPサーバーが受け渡しに対して成功を返したことを意味します。受信トレイへの到達は、その後に受信環境の内部で行われるポリシーと分類の判断です。メッセージはある状態を通過しても、次の段階で失敗したり、異なる分類をされたりすることがあります。SMTPは現在のトランザクションについての直接の証拠を与え、後から配信状態通知を生成することもありますが、受信者の最終的なフォルダを明かすことはありません。250の応答をすべて受信トレイへの配信と表示するのではなく、これらの状態を個別に保存してください。宛先のSMTPの成功応答を含むプロバイダーのイベントは、「サーバーへの配信済み」の状態の根拠になります。バウンスは、失敗やサプレッションの処理の根拠になります。どちらも、表示されること、読まれること、エンゲージメントについて約束する根拠にはなりません。このモデルによってステータスを正直に保ち、責任がすでに移った後の安全でない再試行を防げます。

SendHQの文書化されたAPIを使用する

アプリケーションはプロバイダーライブラリを介してSMTPを使用することも、プロバイダーがそのインターフェースの下でインターネットメール転送を処理するHTTPメールAPIを呼び出すこともできます。SendHQは、検証済みドメインチェック、送信および受信メッセージリソース、イベント、サプレッション、インボックス、ワークスペースのリソース境界を備えたワークスペース単位のメールAPIを提供します。そのHTTP APIは、直接SMTPサブミッションとともに構造化されたリクエスト、ID、イベントを提供できます。これは宛先サーバーの動作を変更したり、SMTPでの受け付け、受信トレイ到達率、受信者のエンゲージメントを確立したりするものではありません。

よくある質問

SMTPは何の略ですか?

SMTPはSimple Mail Transfer Protocol(簡易メール転送プロトコル)の略です。メールクライアントとサーバーが、コマンド、応答、エンベロープ、メッセージデータ、そして認証やTLSなどの機能のための拡張を通じて、送信メッセージをサブミッションし転送する方法を定義しています。

SMTPは受信トレイのメールを読むために使われますか?

いいえ。SMTPは主に送信メールのサブミッションと転送のためのものです。受信トレイへのアクセスには、IMAP、POP、プロバイダー固有のメールボックスAPI、または保存された受信メッセージを公開するアプリケーション向けのメールAPIなど、別のインターフェースを使います。

ポート25、587、465の違いは何ですか?

ポート25は、慣例としてサーバー間のリレーに使われます。ポート587は標準のメッセージサブミッション用サービスで、一般にTLSをネゴシエートします。ポート465は、暗黙的TLSによるサブミッション用に登録されています。ポートを試行錯誤で切り替えるのではなく、プロバイダーが文書化しているエンドポイントとセキュリティモードに従ってください。

SMTPの成功は、メールが受信トレイに届いたことを証明しますか?

いいえ。成功の応答が証明するのは、応答したSMTPサーバーが該当するコマンドを受け付けた、またはメッセージの責任を引き受けたということだけです。受信システムはその後もポリシーを適用したり、遅延した失敗を生成したり、受け付けたメールをメインの受信トレイ以外に分類したりすることがあります。

アプリケーションはSMTPの4xxの応答をすべて再試行すべきですか?

4xxのコードは一時的な否定の結果を示しますが、再試行には、永続的なキュー、ジッター付きの指数バックオフ、有限の存続期間、受信者を考慮した試行回数の上限を使うべきです。一時的な失敗が繰り返される場合は、無期限に再試行するのではなく調査してください。

HTTPのメールAPIはSMTPの代わりになりますか?

アプリケーションのコードではSMTPの代わりになりますが、プロバイダーは通常、受信者のメールシステムとの通信には引き続きSMTPを使います。APIは、転送層の上に、構造化された認証、ペイロード、リソースのスコープ、識別子、イベント処理を追加するものです。

出典