用語 · SMTPポート
アプリケーションのメール送信にはどのSMTPポートを使うべきですか?
ほとんどのアプリケーションでは、メールプロバイダーが文書化しているサブミッションエンドポイントとポートを使用すべきです。ポート587は標準のメッセージサブミッションポートで、通常は平文SMTPで開始し、その後STARTTLSでアップグレードします。ポート465は暗黙的TLSによるメッセージサブミッションであり、TLSハンドシェイクが直ちに始まります。ポート25は主にサーバー間SMTPリレー用であり、通常の認証済みアプリケーションサブミッション用ではありません。動作する設定では、ホスト名、ポート、TLSモード、認証方法の4つをすべて一致させる必要があります。
SMTPポートはプロトコルの役割と接続モードを決める
ポート番号は、同じサービスに入るための交換可能な入口ではありません。サーバーが提供するSMTPの役割と、接続の始まり方を識別する手がかりになります。メッセージサブミッションは、アプリケーションやユーザーエージェントからサブミッションサービスへの最初の受け渡しです。リレーは、メールサーバー間でのメールの転送です。サブミッションでは、公開のメールリレーとは異なる形で、認証、送信者の認可、メッセージのポリシーチェックが必要になることがあるため、標準規格ではこの2つの役割が分けられています。ポートはまた、クライアントがSMTPコマンドから始めて後でSTARTTLSでアップグレードするのか、すぐにTLSハンドシェイクを始めるのかも示します。プロバイダーのホスト名、ポート、TLSモード、認証の指示は、1組の設定として扱ってください。無関係なプロバイダーのポートをコピーしたり、エラーの後にポートだけを変えたりすると、元の原因は解決しないまま、ネットワークの問題がTLSや認証の失敗に変わってしまうことがあります。
ポート25は主にメールサーバー間のリレー用
ポート25は、あるMTA(Message Transfer Agent)が別のMTAにメールを受け渡すときに使われる、従来のSMTPリレー用ポートです。RFC 6409では、リレーはポート25のまま、新しいメッセージのサブミッションはポート587に分けられています。そのため、アプリケーションは、受信者のメールサーバーにポート25で直接接続することがプロダクトメールを送る通常の方法だと考えるべきではありません。直接リレーするには、キューイング、DNSによるルーティング、バウンス処理、不正利用対策、レピュテーション管理、標準に準拠した再試行の挙動が必要です。ネットワークやホスティングプロバイダーが送信方向のポート25を制限していることもあります。たとえばAWSは、Amazon EC2からのポート25のメールトラフィックをデフォルトでスロットリングすることをドキュメントに記載しています。ポート25がプロバイダーや管理されたインフラの中でドキュメント化された選択肢であることもありますが、使えるからといってサブミッションに適した選択になるわけではありません。責任を持つサービスが、そのエンドポイント、セキュリティモード、運用モデルを明示的にドキュメント化している場合にのみ使ってください。
ポート587はメッセージサブミッションの標準ポート
RFC 6409はポート587をメッセージサブミッション用に予約しており、新しいメッセージを受け付ける前に、認可されていないメールを拒否し、認証を要求し、ポリシーを適用できるサブミッションサービスについて説明しています。ポート587の一般的なセッションは、SMTPで始まり、`EHLO`の後にSTARTTLS拡張を提示し、接続をTLSにアップグレードし、`EHLO`を再度送り、認証してから、メッセージを送信します。「一般的な」という点が重要です。正確な認証方式と要件は、プロバイダーの現行のドキュメントとサーバーの機能によって決まります。安全なクライアントは、想定されるTLSへのアップグレードを必須にし、サーバー証明書を検証するべきで、ネゴシエーションに失敗した後に平文のまま続行してはいけません。最初の暗号化されていないプロトコルの挨拶を、保護されていない認証済みセッションと混同しないでください。STARTTLSは、認証情報やメッセージのデータを送る前にその接続をアップグレードするための仕組みです。ポート587はサブミッションサービスを示すものであり、TLSが確実に適用されるかどうかは、クライアントのポリシーが正しいかどうかにかかっています。
ポート465はサブミッションに暗黙的TLSを使う
ポート465は、暗黙的TLSによるメッセージサブミッション用に登録されています。暗黙的TLSでは、クライアントはTCP接続が開いた直後にTLSハンドシェイクを行い、保護されたチャネルの中でのみSMTPコマンドを送ります。これは、クライアントがまずSMTPの挨拶を受け取ってからアップグレードを要求する、ポート587のSTARTTLSとは異なります。RFC 8314はサブミッションに暗黙的TLSを推奨する一方で、プロバイダーとクライアントがポート465の暗黙的TLSとポート587のSTARTTLSの両方をサポートできる移行期間についても説明しています。このRFCでは、TLSが必須であれば、正しく実装されたクライアントとサーバーはどちらのモードでも実質的に同等のセキュリティを提供できると述べられています。実務上のルールは、どちらかのポートが普遍的に正しいと決めつけないことです。プロバイダーがサポートしているエンドポイントとモードをそのまま使ってください。暗黙的TLSのリスナーに対してSTARTTLSを設定したり、STARTTLSのリスナーに対して暗黙的TLSを設定したりすると、通常は認証の前に失敗します。
プロバイダー固有の代替ポートは明示的な契約である
ネットワークの制限を回避するために代替ポートを提供するプロバイダーもありますが、それらの番号はあらゆるサービスに共通するSMTPの標準ではありません。Amazon SESは現在、STARTTLSをポート25、587、2587で、TLS Wrapper(同社での暗黙的TLSの呼び方)をポート465と2465で提供するとドキュメントに記載しています。SESは暗号化された接続を必須とし、リージョンごとのSMTPエンドポイントを公開しています。これは、ポートを汎用的な一覧からではなく、選択したプロバイダーのドキュメントから取るべき理由をよく示しています。ポート2587がどこでもSTARTTLSを意味するわけではなく、ポート2465が任意のホストで暗黙的TLSのサービスを示すわけでもありません。代替ポートを使っても、送信者の検証、認証情報のスコープ、クォータ、プロバイダーのポリシーを迂回できるわけではありません。本番の設定には出典のURLと確認日を記録しておきましょう。そうすれば運用者は、意図的なプロバイダーの設定と、何年も前に環境変数にコピーされた説明のないマジックナンバーとを区別できます。
ホスト名、ポート、TLS、認証をまとめて設定する
堅牢なSMTPの設定は、プロバイダーのホスト名、ポート、トランスポートセキュリティのモード、証明書の検証ポリシー、認証方式、ユーザー名、秘密情報、接続タイムアウト、送信IDをひとまとまりにしたものです。TLS証明書はホスト名に対して検証され、プロバイダーによってはリージョンごとに異なるエンドポイントを公開しているため、ホスト名は重要です。ポートとTLSモードは一致していなければなりません。認証は意図した保護されたチャネルが確立された後にのみ行い、秘密情報はソースコード、ブラウザのバンドル、ログ、診断出力ではなくシークレットマネージャーに置いてください。ローカルのテストから誤って本番経由で送信しないよう、認証情報と設定は環境ごとに分けます。接続とコマンドのタイムアウトには有限の値を設定しますが、メッセージの再試行は永続的なアプリケーションのキューに任せましょう。`secure`という名前のライブラリのオプションは、あるSDKでは暗黙的TLSを意味し、別のSDKでは単にSTARTTLSを必須にするだけの場合もあります。オプション名に頼らず、ライブラリでの定義を確認し、実際にネゴシエーションされる挙動をテストしてください。
秘密情報を露出させずに、層ごとに接続をテストする
まず、アプリケーションと同じ実行環境のネットワークから、DNSの名前解決とTCPの到達性を確認します。接続前にタイムアウトする場合は、ルーティング、ファイアウォール、プロバイダーの送信方向のポリシー、ホスト名の誤り、閉じたポートが疑われます。次に、想定するTLSモードをテストします。暗黙的TLSの場合、TLSクライアントは証明書を受け取り、その後SMTPの挨拶を受け取るはずです。STARTTLSの場合、SMTPに対応したクライアントは挨拶を受け取り、`EHLO`を送り、STARTTLSが提示されていることを確認し、アップグレードを要求し、証明書を検証して、TLSの後に`EHLO`を再度送るはずです。RFC 3207は、ハンドシェイクの前に得た情報をクライアントとサーバーが破棄することを求めており、2回目の`EHLO`が重要なのはそのためです。そのうえで初めて、管理されたアカウントで認証をテストします。ログを共有する前に、ユーザー名、トークン、受信者のアドレス、サーバーとのやり取りの全文、メッセージのコンテンツを伏せてください。接続の確認に、本番での送信や実際の顧客のアドレスは必要ありません。
実際に失敗した段階で障害を分類する
接続拒否(connection refused)は、TCPの宛先が接続を能動的に拒否したことを意味します。タイムアウトは、制限時間内に有効な応答が届かなかったことを意味します。TLSハンドシェイクのエラーは、モードの不一致、証明書の問題、プロトコルの非互換、通信の傍受、エンドポイントの誤りを示しています。認証エラーはさらに後の段階で発生するもので、ポートを場当たり的に変えて直そうとするのではなく、認証情報、認証方式、アカウント、認可の設定の問題として調査するべきです。`MAIL FROM`、`RCPT TO`、`DATA`の段階でのSMTPの応答コードは、さらに後のポリシーとメッセージに関する判断を表しています。段階、タイムスタンプ、エンドポイント、試行回数、数値の応答コード、プライバシーに配慮してフィルタリングした応答を保存してください。SMTPの4xxの応答は通常一時的なもので、5xxの応答は通常その試行したコマンドにとって恒久的なものですが、再試行には上限を設け、受信者ごとに扱う必要があります。プロバイダーがメッセージのデータを受け付けていた場合、後のアプリケーションのリクエストがタイムアウトしたからといって、やみくもに重複して送信してはいけません。プロバイダーの識別子とイベント履歴を使って突き合わせてください。
ポートへの接続の成功は、メッセージの配信や受信トレイへの到達ではない
TCP接続が成功しても、証明されるのはリスナーが応答したことだけです。TLSハンドシェイクが成功すると、証明書の検証が成功した場合に限り、認証されたエンドポイントへの保護された接続が確立されたことが証明されます。認証の成功は、そのセッションでサーバーが提示されたクライアントのIDを受け入れたことを証明します。メッセージのデータの後のSMTPの`250`応答は、応答したサーバーがプロトコル上の責任を引き受けたことを意味するだけで、人がメッセージを受け取ったり読んだりしたことを意味するものではありません。後のリレーが失敗することもありますし、受信システムがメールを受け付けたうえでメインの受信トレイ以外に振り分けることもあります。アプリケーションの記録と監視では、これらの状態を分けておきましょう。ネットワークの可用性、TLSのネゴシエーション、認証、プロバイダーによる受け付け、宛先サーバーによる受け付け、バウンス、苦情、エンゲージメントは、それぞれ異なる観察結果です。こうして分けておけば、ポートの確認を配信テストと誤って報告することも、受信トレイへの到達を証明できないというだけで受け付け済みのメッセージを再試行することも防げます。
SMTPサブミッションかメールAPIかを意図的に選ぶ
システムにすでに成熟したSMTPクライアントがある場合、必須のプラットフォームがサポート対象の連携としてSMTPを公開している場合、またはプロトコルレベルの制御が特に必要な場合は、SMTPサブミッションを使用してください。構造化されたリクエスト、スコープ付きトークン、冪等性、バッチリソース、機械可読なイベントレコードがワークロードに適する場合、HTTPSメールAPIの方がより良いアプリケーション境界となることがあります。プロバイダーは受信者メールシステムへ到達するために下流でSMTPを引き続き使用できるため、APIがメール転送をなくすわけではありません。APIは、プロバイダー向けの受け渡しにおけるポート、TLS、認証、再試行の責任をアプリケーションのSMTP設定から移します。
よくある質問
アプリケーションではSMTPのポート587と465のどちらを使うべきですか?
プロバイダーのドキュメントに記載されたポートとTLSモードを使ってください。ポート587は通常STARTTLSを使い、ポート465は暗黙的TLSを使います。正しく実装され、TLSが必須になっていれば、どちらもサブミッションを保護できます。クライアントの設定はサーバーのリスナーと一致している必要があります。
SMTPのポート25がブロックされたりタイムアウトしたりするのはなぜですか?
ポート25はメールサーバー間のリレーに使われ、悪用されることも多いため、ホスティングプラットフォーム、ISP、ファイアウォール、宛先のポリシーによって制限されている場合があります。任意のポートで制限を回避するのではなく、ネットワークのポリシーを確認し、プロバイダーのドキュメントに記載されたサブミッション用のエンドポイントを使ってください。
ほかは何も変えずに、ポート587から465に切り替えられますか?
通常はできません。ポート587は一般にSMTPで始まりSTARTTLSでアップグレードしますが、ポート465は接続直後にTLSハンドシェイクを始めます。プロバイダーとライブラリのドキュメントに従い、ポートとクライアントのTLSモードをあわせて変更してください。
ポート587はデフォルトで暗号化されていますか?
ポートが示すのはメッセージサブミッションであり、暗号化されるかどうかはSTARTTLSのネゴシエーションとクライアントのポリシーによって決まります。アップグレードの成功を必須にし、証明書を検証し、保護されたサブミッションを確立できない場合は認証情報やメッセージのデータを送らないよう、クライアントを設定してください。
SMTPの接続拒否(connection refused)とはどういう意味ですか?
SMTPのネゴシエーションの前に、TCPの宛先が接続を拒否したことを意味します。よくある原因は、ホストやポートの誤り、サービスが待ち受けていない、ファイアウォールによる拒否、そのネットワークからプロバイダーのエンドポイントを利用できない、といったものです。
SMTPポートのテストに成功すれば、メールの配信が証明されますか?
いいえ。証明されるのは、TCPやTLSなど、テストで実際に完了した段階だけです。認証、メッセージの受け付け、宛先サーバーによる受け付け、バウンス処理、メールボックスでの分類、受信者のエンゲージメントには別々の証拠が必要で、それぞれ分けて報告しなければなりません。
出典
- RFC 6409:メールのメッセージサブミッション — RFC Editor
- RFC 8314:平文は廃止扱い:メールのサブミッションとアクセスにおけるトランスポート層セキュリティ(TLS)の使用 — RFC Editor
- RFC 3207:TLS上のセキュアなSMTPのためのサービス拡張 — RFC Editor
- RFC 5321:簡易メール転送プロトコル(SMTP) — RFC Editor
- Amazon SESのSMTPエンドポイントへの接続 — Amazon Web Services