SMTP(Simple Mail Transfer Protocol)
概要
SMTP(Simple Mail Transfer Protocol) は、インターネット上でメールを送信・中継するための標準プロトコルです。RFC 5321(2008年)で現行仕様が定義されており、メールシステムの根幹を担っています。送信者のメールクライアントからメールサーバーへ、そしてメールサーバー間でメッセージを転送する役割を持ちます。
SMTP はメールの「送る」部分だけを担当します。受信側のメールボックスからメールを取り出すのは IMAP(RFC 9051)や POP3(RFC 1939)の役割です。この役割分担を理解しておくと、メール配信の問題を切り分けやすくなります。
SMTP が最初に標準化されたのは 1982 年の RFC 821 です。その後、拡張 SMTP(ESMTP、RFC 1869)で EHLO コマンドや機能拡張の仕組みが導入され、RFC 5321 で現在の仕様に統合されました。約 40 年にわたって基本的なコマンド体系が維持されており、インターネットで最も長寿なプロトコルの一つです。
仕組み
SMTP はテキストベースのコマンド・レスポンス方式で動作し、ポート・暗号化方式・レスポンスコードの使い分けが運用の基本です。
SMTP セッションの流れ
SMTP の通信はテキストベースのコマンドとレスポンスで構成されます。送信サーバー(クライアント)が受信サーバーに TCP 接続し、以下の手順でメッセージを転送します。
- TCP 接続を確立する(ポート 25、587、または 465)
- サーバーが
220レスポンスで接続を受け付ける - クライアントが
EHLO mail.example.comで自身を名乗る - サーバーが対応する拡張機能(STARTTLS、AUTH 等)のリストを返す
- 必要に応じて
STARTTLSで TLS 暗号化を開始する MAIL FROM: <sender@example.com>で送信元(エンベロープ From)を宣言するRCPT TO: <recipient@example.net>で宛先(エンベロープ To)を宣言するDATAコマンドでメールヘッダーと本文を送信する.(ピリオド単独行)でメッセージの終了を示す- サーバーが
250 OKでメッセージ受理を通知する QUITで接続を閉じる
手順 6 の MAIL FROM で渡されるアドレスがエンベロープ From です。SPF はこのドメインを検証対象にします。手順 8 で送信される From: ヘッダー(ヘッダー From)はメールクライアントに表示されるアドレスで、SMTP プロトコル上は単なるデータの一部です。
ポートの使い分け
SMTP は用途に応じて 3 つのポートを使い分けます。
| ポート | 用途 | 暗号化 | RFC |
|---|---|---|---|
| 25 | サーバー間のメール中継(リレー) | STARTTLS(任意) | RFC 5321 |
| 587 | メールクライアントからサーバーへの送信(サブミッション) | STARTTLS(必須) | RFC 6409 |
| 465 | メールクライアントからサーバーへの送信(暗黙的 TLS) | TLS(接続時から暗号化) | RFC 8314 |
ポート 25 はサーバー間通信用で、エンドユーザーのメールクライアントからの送信には使いません。多くの ISP やクラウドプロバイダーはポート 25 のアウトバウンド接続をブロックしています(OP25B)。メールクライアントからの送信にはポート 587 または 465 を使います。
ポート 587 は RFC 6409 で「Message Submission」として標準化されています。接続後に STARTTLS で TLS にアップグレードし、SMTP AUTH で認証を行います。ポート 465 は RFC 8314(2018年)で「Submissions(Submission over TLS)」として再標準化されました。接続開始時から TLS で暗号化されるため、STARTTLS のネゴシエーション手順が不要です。
STARTTLS と暗黙的 TLS
STARTTLS は、平文で始まった SMTP 接続を途中から TLS 暗号化に切り替える仕組みです。RFC 3207 で定義されています。ポート 25 や 587 で使われます。
暗黙的 TLS(Implicit TLS)は、接続の最初から TLS ハンドシェイクを行います。ポート 465 で使われ、平文の通信が一切発生しません。RFC 8314 は暗黙的 TLS を推奨しており、STARTTLS よりもセキュリティ上の利点があります。STARTTLS はダウングレード攻撃(TLS への切り替えを妨害して平文通信を強制する攻撃)の影響を受ける可能性がありますが、暗黙的 TLS にはこのリスクがありません。
SMTP レスポンスコード
SMTP サーバーはコマンドに対して 3 桁の数字コードで応答します。先頭の桁で結果の分類が分かります。
| コード | 意味 | 例 |
|---|---|---|
| 2xx | 成功 | 250 OK — コマンド正常完了 |
| 3xx | 中間応答(追加データ待ち) | 354 Start mail input — DATA 入力待ち |
| 4xx | 一時的エラー(再試行可能) | 421 Service not available — サーバー過負荷 |
| 5xx | 永続的エラー(再試行不可) | 550 Mailbox not found — 宛先不存在 |
4xx 系のエラーはソフトバウンスに対応します。送信サーバーは一定間隔で再試行し、規定回数または期間を超えると送信を断念します。5xx 系のエラーはハードバウンスで、即座に配送を断念し、エンベロープ From のアドレスにバウンス通知を返します。
確認方法
SMTP 接続を手動でテストするには openssl s_client を使います。ポート 465(暗黙的 TLS)への接続例です。
openssl s_client -connect smtp.gmail.com:465 -quiet
接続に成功すると 220 レスポンスが返ります。続けて EHLO コマンドを入力すると、サーバーが対応する拡張機能を一覧で返します。
ポート 587(STARTTLS)の場合は -starttls smtp オプションを付けます。
openssl s_client -connect smtp.gmail.com:587 -starttls smtp -quiet
MX レコードからメールサーバーを特定し、そのサーバーのポート 25 に接続することで、サーバー間の SMTP 中継経路を確認できます。
dig MX example.com +short
openssl s_client -connect mx1.example.com:25 -starttls smtp -quiet
外部の視点からも確認したい場合は、Labee Dev Toolbox の Mail Auth API を使うと、外部の視点から見た結果を取得できます。
curl "https://labee.dev/api/mail-auth?domain=example.com"
レスポンスは次の形式で返ります。
{
"success": true,
"data": {
"spf": {
"record": "v=spf1 include:_spf.google.com ~all",
"exists": true
},
"dkim": {
"record": null,
"exists": false,
"selector": "default"
},
"dmarc": {
"record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
"exists": true
},
"bimi": {
"record": null,
"exists": false
}
},
"error": null,
"meta": { "responseTime": 120 }
}
data.spf.exists が true であれば SPF レコードが設定されています。data.dkim.exists と data.dmarc.exists も合わせて確認すると、SMTP で送信したメールが認証を通過するかどうかの見通しが立ちます。
よくある問題
SMTP の運用では、ポート 25 のブロック、STARTTLS の不備、認証情報の漏洩、バウンスメールの未受信が頻出するトラブルです。
ポート 25 がブロックされていてメールを送信できない
多くの ISP やクラウドプロバイダー(AWS、GCP、Azure 等)は、スパム対策としてポート 25 のアウトバウンド接続をブロックしています。この制限は OP25B(Outbound Port 25 Blocking)と呼ばれます。自社サーバーから直接メールを送信する場合、プロバイダーに申請してブロックを解除するか、メール配信サービス(SendGrid、Amazon SES 等)を経由して送信します。
メールクライアントからの送信にはそもそもポート 25 を使いません。ポート 587 または 465 を設定します。
STARTTLS が使えずメールが平文で送信される
サーバー間の SMTP 通信(ポート 25)では、STARTTLS の対応は任意です。受信サーバーが STARTTLS に対応していない場合、メールは平文で送信されます。この状態を「日和見 TLS(Opportunistic TLS)」と呼びます。
MTA-STS を設定すると、送信サーバーに対して「このドメインへのメールは必ず TLS を使うこと」と宣言できます。TLS が確立できない場合、メールの送信自体を中止するため、平文での送信を防げます。
SMTP AUTH の認証情報が漏洩する
ポート 587 や 465 で使う SMTP AUTH の認証情報(ユーザー名とパスワード)は、TLS で暗号化された接続内で送信されます。TLS なしで SMTP AUTH を使うと、認証情報が平文でネットワークを流れます。メールクライアントの設定で「SSL/TLS を使用する」や「STARTTLS を使用する」が有効になっていることを確認します。
アプリケーションから SMTP 送信する場合も、TLS を明示的に有効化します。開発環境やステージング環境で TLS を無効にしたまま本番に持ち込むケースがあります。
バウンスメールが返ってこない
SMTP の MAIL FROM(エンベロープ From)に指定したアドレスが存在しない、またはメールを受信できない状態だと、バウンス通知が失われます。配送エラーに気づけず、無効なアドレスへの送信を続けることになります。エンベロープ From には実在するアドレスを指定し、バウンス処理の仕組みを整えます。
メール認証との関係
SMTP 自体には送信者の身元を検証する仕組みがありません。MAIL FROM にも From: ヘッダーにも、任意のアドレスを書くことができます。この設計上の脆弱性を補うために、SPF、DKIM、DMARC が策定されました。
SPF は MAIL FROM のドメインに対して、送信元 IP アドレスが許可されているかを検証します。DKIM はメールのヘッダーと本文に電子署名を付与し、改ざんがないことを保証します。DMARC は SPF と DKIM の結果をヘッダー From のドメインと照合し、なりすましを判定します。
SMTP でメールを送信する際、これらの認証が pass するかどうかは、DNS レコードの設定と送信経路の構成に依存します。メール配信サービスを利用する場合は、サービスが提供する SPF の include 設定や DKIM 署名の設定を正しく行うことで、SMTP 経由のメールが認証を通過するようになります。