本ページの位置づけ
「送信ボタンを押してから、相手の画面にメールが表示されるまで」の間に起きている通信を、DNS・TCP・TLS・SMTP・DKIM・SPF・DMARCといった要素技術ごとに分解して解説したページです。前半(2〜4章)は実際のPostfixログに基づく技術的な手順、後半(5〜6章)は「手紙の受け渡し」に例えた会話形式で、Brevoから受信サーバーまでの最終区間と、受信者に届くまでを紹介します。文中のメールアドレスは伏字(you@yama.mydns.jp)に置き換えています。
目次
1. シーケンス図(全体像)
Phase 0〜15までの全通信を、役割ごとのレーン(クライアント/ネット/Brevo/Mydns/ISP(DNS等)/FW/サーバー、および受信側のmailサーバー/DNSサーバー等)に分けて描いた図です。以降の章では、この図の内容をフェーズごとに文章で解説しています。
2. 全体の流れ(5つのフェーズ)
あなたが Thunderbird(またはスマホ)から you@yama.mydns.jp でメールを送信したとき、裏側では以下の順番で通信が行われています。
| フェーズ | 内容 |
|---|---|
| Phase 0 | 名前解決(DNS問い合わせ) |
| Phase 1 | 接続確立(TCP 3-way Handshake) |
| Phase 2 | 暗号化トンネル(STARTTLS) |
| Phase 3 | 認証(SASL AUTH) |
| Phase 4 | 手紙の送信(DATA) |
| Phase 5 | リレーと最終目的地(Postfix → Brevo → 受信サーバー → 受信者への通知) |
3. Phase 0〜4:あなたの端末からPostfixに預けるまで
Phase 0:名前解決(DNS問い合わせ)
- クライアント(PC/スマホ):「
yama.mydns.jpのIPアドレスを教えて!」とDNSサーバー(1.1.1.1やISPのDNS)に聞く - DNSサーバー:MyDNS.jpのサーバーまで探しに行き、現在の自宅のグローバルIPアドレスを回答する
- 結果:PCは「
yama.mydns.jpは125.205.151.xxxだ」と理解する
Phase 1:接続確立(TCP 3-way Handshake)
- クライアント:判明したIPアドレスの587番ポートに対して「接続していい?」(SYN)を送る
- FortiGate:「いいよ」(SYN/ACK)を返す
- クライアント:「ありがとう」(ACK)を返す
👉 ここで、初めてTCP接続(通信の道)が完成します。
Phase 2:暗号化トンネル(STARTTLS)
- クライアント:SMTPの挨拶をする(
EHLO) - Postfix:「私は暗号化をサポートしているよ。暗号化を始めるなら
STARTTLSコマンドを送ってね」と伝える - クライアント:
STARTTLSコマンドを送る - TLSハンドシェイク:Let's Encryptの証明書を使って、安全な暗号化トンネルを作成する
👉 これ以降、流れるデータは全て暗号化されます。
Phase 3:認証(SASL AUTH)
- クライアント:「ログインさせてくれ」(
AUTH PLAIN ...) - Postfix:Dovecotに「パスワードが合っているか確認して」と依頼
- Dovecot:ユーザー情報を調べて「OK」を返す
- Postfix:「認証OK、手紙の中身をどうぞ」と許可を出す
Phase 4:手紙の送信(DATA)
- クライアント:
MAIL FROM、RCPT TO、DATAコマンドで、手紙の中身を流し込む
👉 ここで初めてメール本文がサーバーへ渡ります。
4. Postfix内部の詳細処理とポート587を使う理由
Postfixは、外部への送信時に「SMTPクライアント」という別のプログラムを起動して、Brevo(リレーサーバー)へ手紙を運びます。あなたが「送信」を押した直後、サーバー内部では以下の順で処理が進みます。
| 順序 | 処理主体 | 内容 | 解説 |
|---|---|---|---|
| 1 | Cleanup | sender_canonical 実行 | 送信元アドレスを you@yama.mydns.jp に書き換える |
| 2 | OpenDKIM | 電子署名(DKIM) | yama.mydns.jp の実印をメールのヘッダーに埋め込む |
| 3 | Qmgr | キュー管理 | 送信待ちリスト(Queue)にメールを入れ、送り出す順番を待つ |
| 4 | SMTP Client | Brevoへの接続 | ポート587を使い、リレーサーバーへ接続 |
| 5 | Auth/TLS | Brevo認証&暗号化 | sasl_passwd を使い、Brevoにログインする |
| 6 | Delivery | 手紙の転送 | 認証完了後、メール本文をBrevoへ送り出し、完了! |
なぜポート587を使うのか
通常、メールサーバー同士は25番ポートで通信します。しかし利用中のISP回線では25番がブロックされているため、relayhost = [smtp-relay.brevo.com]:587 という設定により、Postfixは以下の動作を強制されます。
- 宛先:smtp-relay.brevo.com の587番ポート
- 通信のルール:「配送業者(Brevo)に対して一人のユーザーとしてログインし、認証(AUTH)を受けてから荷物(メール)を預ける」というクライアント・サーバー形式
- メリット:自宅サーバーのIPアドレスの評判に関わらず、信頼されたBrevoのサーバーからメールが発送されるため、到達率が劇的に高まる
ログで見る「成功の会話」
sudo tail -n 20 /var/log/maillog を見たとき、以下のログがPhase 5の成功を証明しています。
postfix/smtp[9999]: ... relay=smtp-relay.sendinblue.com[(Brevo割当IP)]:587, ... status=sent (250 2.0.0 OK...)
relay=...:587:「587番ポートを使って、Brevoのリレーサーバーに接続したぞ」と宣言しているstatus=sent:「Brevoサーバーがメールを受け取り、配送を確約した」という、技術的な成功報告コード
5. Brevoから受信サーバーへの最終配送(SPF/DKIM/DMARC判定)
ここからは、Brevoがあなたに代わって受信サーバー(Gmail等)に手紙を届ける区間です。「手紙の受け渡し」に例えると、次のような会話が交わされています。
接続とあいさつ
- Brevo:受信サーバーのMXレコードをDNSに問い合わせ、届け先ホストとそのIPアドレスを教えてもらう
- Brevo:受信サーバーへTCP接続を確立し、TLSで暗号化トンネルを開始する
- 受信サーバー:接続を受け付け、「手紙を届けるよ」というBrevoの挨拶を受諾する
SPFの検証
- Brevo:差出人(エンベロープFrom)を宣言してデータを送信
- 受信サーバー:差出人ドメインのSPFレコードをDNSに問い合わせ、「Brevoの接続元IPが許可リストに載っているか」を照合する
- 受信サーバー:照合の結果、チェック通過(SPF PASS)
DKIMの検証
- Brevo:宛先を指定し、本文(DKIM署名入りヘッダーを含む)を送信
- 受信サーバー:署名に使われたドメイン(yama.mydns.jp)の公開鍵をDNSに問い合わせる
- 受信サーバー:取得した公開鍵で署名を計算し直し、改ざんされていないか・本当にそのドメインが署名したかを判定(DKIM PASS)
DMARCの最終判定
全部合格 🎉
受信サーバーはSPF・DKIMそれぞれの判定結果と、Fromヘッダーのドメインとのアライメント(一致)を統合して、DMARCの最終判定を下します。SPF・DKIMのいずれかがPASSし、かつそのドメインがFromヘッダーのドメインと一致していれば、メールは「なりすましではない」と判断され、受信トレイに届きます。
6. 受信者への通知とメール本文の取得
受信サーバーがメールを受け取ると、いよいよ受信者のスマホに届きます。
- 受信サーバー:新着メールを検知し、スマホの通知センターへプッシュ通知を送る
- 受信者:通知をタップしてメールアプリを開く
- スマホのメールアプリ:受信サーバーへ接続し、TLSハンドシェイクを開始する
スマホ側のTLSハンドシェイク
- 暗号化アルゴリズムの候補と、鍵生成用のデータを送信
- 受信サーバー:選定した暗号方式を通知し、鍵生成用のデータを返送
- 受信サーバー:デジタル証明書を提示し、秘密鍵による署名で「証明書の所有者本人である」ことを証明
- 双方:「ハンドシェイク完了、ここから先は暗号化通信にするよ」という合図を送り合う
ハンドシェイクが完了すると、暗号化トンネルの中でメールアプリが本文取得のリクエストを送り、受信サーバーがレスポンスとしてメール本文データを返します。こうして、あなたが送信ボタンを押してから0.数秒〜数秒後には、相手の画面にメールが表示されます。
7. 豆知識:DNSキャッシュの罠
なぜメールサーバー管理者にとって「名前解決」(Phase 0)が重要なのか。それは「DNSには寿命(TTL: Time To Live)があるから」です。
問題・トラブル・解決策
- 問題:MyDNSでIPを更新しても、PCやスマホ、DNSサーバーは「古いIP」を数分〜数時間記憶(キャッシュ)していることがある
- トラブル:「さっきまで繋がっていたのに、繋がらなくなった」という場合、多くのケースで「DNSのキャッシュが古いIPを掴んだままになっている」ことが原因
- 解決策:繋がらない時は
ipconfig /flushdns(Windows)を実行する、または別の端末で試すことで「古い住所録」を回避できる
8. トラブルが起きたときの確認手順
もし「送れない!」となったら、以下の順で確認します。
- Postfixがメールを預かっているか? →
sudo mailqを実行し、件数が表示されたら、Postfixは手紙を受け取ったが何らかの理由で中継所に運べていない - 接続先(Brevo)まで届いているか? → ログに
status=sentがあれば、サーバーのネットワーク設定・認証設定は100%成功。status=bouncedでAuthentication failedならsasl_passwdのパスワードが間違っている - なぜ届かないか? → ここまで成功していれば、原因は「宛先サーバー(Gmail/Yahoo等)の迷惑メールフィルター」しかない。
mail-tester.comでスコアを確認するのが解決の近道
送信〜受信までの全通信ドラマ、これで一通り解説完了 🎉
自分の手で組み立てたサーバーの裏側で、DNS・TCP・TLS・SASL認証・DKIM署名・SPF/DMARC判定という一連のドラマが0.数秒で行われています。実際の受信ヘッダーでの確認は「Gmailにて受信したメールヘッダ(SPF/DKIM/DMARC確認)」もあわせてご参照ください。