メール・到達率

メールヘッダーの読み方と、そこから何が証明できるか

読んでいるメッセージの上には、送った本人ではなく機械が書き込んだ行の塊があります。そのほとんどは雑音ですが、4つのフィールドだけは違い、そのうちのただ1行は偽者には書けない行です。この記事では、その塊をどこで見つけるか、どちらの向きに読むか、そして実際に読んだときに何が証明されるのかを説明します。

  • 初級
  • 読了21分
青い封筒の後ろから灰色の長い紙テープが伸びており、そこには単語の代わりにダッシュが記され、上からは灰色の虫眼鏡がのぞき込んでいる

ヘッダーブロックの正体

どのメッセージも、1行の空行で区切られた2つの部分でできています。Name: valueという形式の行が並ぶブロックと、実際に読む本文です。RFC 5322はこの最初の部分をヘッダーと呼び、そこにある行の1つ1つをフィールドと呼んでいて、その数に上限は設けていません。普段使っているメールアプリが見せてくれるのは4つか5つです。3台のサーバーを経由したメッセージには、たいてい30から60ほどのフィールドが含まれています。

メッセージのソース(抜粋)
Return-Path: <bounces+2841@mail.example.com>
Delivered-To: signup-2026@example.org
Received: by mx.example.org (Postfix) with LMTP id 4c8f21
        for <signup-2026@example.org>; Fri, 5 Sep 2026 09:14:22 +0000 (UTC)
Received: from out-17.mail.example.com (out-17.mail.example.com [198.51.100.17])
        by mx.example.org (Postfix) with ESMTPS id 9a31b0
        for <signup-2026@example.org>; Fri, 5 Sep 2026 09:14:21 +0000 (UTC)
Authentication-Results: mx.example.org;
        spf=pass smtp.mailfrom=mail.example.com;
        dkim=pass header.d=example.com;
        dmarc=pass header.from=example.com
From: "Example Support" <support@example.com>
To: signup-2026@example.org
Subject: Confirm your email address
Date: Fri, 5 Sep 2026 09:14:19 +0000
Message-ID: <20260905091419.9a31b0@mail.example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="b1_4c8f21"

上から下まで読むと機械的な雑音のように見えますし、実際そのほとんどは雑音です。情報のほぼすべてを運んでいるのは4つのフィールドであり、それがこのガイドで扱う4つ、ReceivedFromReturn-PathAuthentication-Resultsです。

完全なヘッダーはどこに隠れているか

以下に挙げるものはどれも、専用のツールも拡張機能もアカウントも必要としません。どのメールクライアントも、生のメッセージをメニュー項目の裏に持っており、探すべき言葉はいつもソースオリジナルrawのいずれかです。

メールを読んでいる場所何を開くか何が表示されるか
ブラウザーのGmail開いたメッセージの三点リーダーメニュー → メッセージのソースを表示ヘッダーブロック全体に加えて、その上にはSPF・DKIM・DMARCをあらかじめ判定済みのサマリーパネルも表示されます。
ブラウザーのOutlook.com三点リーダーメニュー → 表示View message source届いたメッセージそのものを、プレーンテキストとして丸ごと表示。
Outlookのデスクトップアプリメッセージを専用ウィンドウで開く → ファイルプロパティダイアログ下部のボックスに、ヘッダーブロックだけが表示されます。
Macで使うApple Mail表示メッセージRaw Sourceヘッダーと本文がまとめて、専用のウィンドウに表示されます。
どの環境でも使えるThunderbird表示Message Sourceメッセージ全体が、先頭にヘッダーブロックを添えて表示されます。
ブラウザーのProton Mailメッセージの三点リーダーメニュー → View headers本文抜きで、ヘッダーブロックだけが表示されます。
ブラウザーのYahoo MailMoreView raw message配信されたときのままの、メッセージ全体。
誰かから送られてきたファイル、または自分でエクスポートしたファイル.emlファイルを、任意のテキストエディタで開くすべてです。.emlとは、ヘッダーブロックと本文だけでできたファイルだからです。

これらのメニューの場所は2026年9月5日時点のものであり、だいたい年に1度ほど移動します。だからこそ表そのものより、その上に書いた1文のほうが大切です。今の時期にその項目が何と呼ばれていようと、そこには必ずソースオリジナルrawのどれかが入っています。

Receivedチェーンを下から読む

メッセージを受け取った各サーバーはReceived:行を1行書き込み、それまであった内容すべての先頭に置きます。このたった1つの習慣が、ヘッダーについて最も役に立つ事実を生み出しています。最後のホップが最初に目にする行であり、メッセージの旅は逆向きに書き記されているのです。

自分のプロバイダ書かれたのは最後途中のリレー書かれたのは2番目送信元のサーバー書かれたのは最初この行は信頼できるこれは単なる申告にすぎない旅はこの向きで読む
3つのホップ、3つの行、しかし順序は逆です。自分のプロバイダが書いた行が一番上にあり、それが頼りにできる行です。一番下の行は、送信元のマシンが自分自身について語ることを選んだ内容にすぎません。
同じメッセージのReceivedチェーン
Received: by mx.example.org (Postfix) with LMTP id 4c8f21
        for <signup-2026@example.org>; Fri, 5 Sep 2026 09:14:22 +0000 (UTC)
Received: from out-17.mail.example.com (out-17.mail.example.com [198.51.100.17])
        by mx.example.org (Postfix) with ESMTPS id 9a31b0
        for <signup-2026@example.org>; Fri, 5 Sep 2026 09:14:21 +0000 (UTC)
Received: from app-3.internal (app-3.internal [192.0.2.53])
        by out-17.mail.example.com (Postfix) with ESMTP id 771c4e
        for <signup-2026@example.org>; Fri, 5 Sep 2026 09:11:58 +0000 (UTC)

どの行も、同じ一握りの単語から組み立てられています。それぞれの名前が分かるようになれば、チェーンはただの壁紙ではなくなります。

from
接続してきたマシンが自分自身をどう名乗ったか、それに続けて角括弧の中に、実際には何だったのか — 受信サーバーがその接続で確認した逆引きDNS名とIPアドレスが書かれています。角括弧の前の名前は単なる申告であり、その中のアドレスは実際に観測されたものです。
by
この行を書いたサーバーです。この行に登場する当事者のうち、何かの責任を問えるのはこのサーバーだけです。
with
そのホップがどう行われたかです。ESMTP、接続が暗号化されていればESMTPS、メールボックスへの最終引き渡しならLMTPSの付かないESMTPとだけ書かれたホップは、メッセージを平文のまま運んだということです。
for
そのホップにおけるエンベロープの受信者 — 転送ルールが何かを書き換える前に、メッセージが本当はどのアドレス宛てに送られたかです。キャッチオールドメインやプラスタグでは、この項目が、流出したアドレスの名前を教えてくれます。
末尾のタイムスタンプ
そのサーバーがメッセージの受け取りを完了した時刻です。ある行の時刻から、その1つ上の行の時刻を引けば、そのホップでの遅延が分かります。これが、遅いメッセージが実際どこで足止めされていたのかを、推測ではなく突き止める方法です。

上のサンプルでは、メッセージは09:11:58にアプリケーションを離れ、その2分23秒後に送信元プロバイダの送信サーバーに到達しています。その後の2つのホップの間は合わせて1秒しかかかっていません。1時間遅れて届くメッセージには、ほぼ必ずどこか1行に1時間分の空白があり、それは最後の行であることはめったにありません。

送信者を名乗る4つのフィールド

「これを送ったのは誰か」という問いには、ヘッダーの中に4つの答えがあり、それらが食い違っていても構いません。たいていの場合、食い違う理由はありふれたものです — メーリングリスト、マーケティング配信基盤、自分で設定した転送ルールなど。食い違い自体は何の証拠にもなりません。証拠になるのは、今見ているのがその4つのうちどれなのかを知っていることです。

From:
送信者が表示させたいアドレスと、自由記述の表示名です。どちらも検証されません。これはメールアプリがメッセージ一覧に表示するフィールドであり、スマートフォンではたいてい、アドレスは表示名の裏に完全に隠れています。
Return-Path:
エンベロープ送信者であり、メッセージを受け取ったサーバーが、SMTPのやり取りの中で実際に交わされた内容をもとにヘッダーへ書き込みます。バウンスの戻り先であり、SPFが照合する相手のアドレスでもあります — だからこそ、まったく無関係なFrom:を掲げたままメッセージがSPFに合格することもあるのです。
Reply-To:
返信の宛先であり、メッセージの送信元と同じである必要はありません。普通の送信者はサポート窓口やノーリプライアドレスのためにこれを使います。同時に、この業界で最も古い手口の1つでもあります。注意深い読み手ほど送信者を確認して問題ないと判断し、それから返信ボタンを押すからです。
Delivered-To:X-Original-To:
自分のどのアドレスが使われたかです。キャッチオールドメインプラスタグでは、この項目が、実際に渡したアドレス — つまり誰がそれを漏らしたのかを特定するアドレス — の名前を教えてくれます。
表示名とアドレスが食い違っている例
From: "Example Support <support@example.com>" <billing@example.net>
         ^-- the display name, which is free text and is all a phone shows
                                              ^-- the address, which is not

表示名は任意のテキストなので、そこには他人の完全なアドレスをまるごと書き込むことができます。世界中のどのメールクライアントも、引用符の中の部分を表示し、山括弧の中の部分は隠します。攻撃の正体はこれだけです。書くのに何のコストもかからず、しかも読み手が必ず目にすると保証されているフィールドに効くのです。

SPF、DKIM、DMARCを1行で

ブロックの中で、1つのフィールドだけが他のすべてと違います。Authentication-Results:は、メッセージを受け取ったサーバー — つまり自分のプロバイダ — が書き込むものであり、同じ名前で届いた別の行は、目にする前に取り除かれるか名前を変えられます。これはヘッダーの中で唯一、偽者には書けない行です。

自分のプロバイダが記録した判定結果
Authentication-Results: mx.example.org;
        spf=pass (sender IP is 198.51.100.17) smtp.mailfrom=mail.example.com;
        dkim=pass header.d=example.com header.s=s1 header.b=Qk3vR2mA;
        dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

その行には3つのチェックが並んでおり、それぞれ違う問いに答えています。2度読む価値があるのは4つ目の列です。

チェックpassが意味することfailがたいてい意味することどちらも証明しないこと
spf=メッセージを渡してきたマシンが、エンベロープ送信者のドメインがDNSで公開しているリストに載っている、ということです。偽者であるか、あるいはごく普通の転送のどちらかです。第三者がメッセージを中継すると、SPFはそのたびに壊れます。それは欠陥ではなく、日常的に起きていることです。From:のアドレスに関することは何一つ証明しません。SPFはそれを一切見ないからです。
dkim=メッセージに施された暗号署名が、署名側のドメインが公開している公開鍵と一致している、ということです。メッセージが途中で改変されたか — メーリングリストがフッターを追加するだけでも十分です — あるいは、名乗っているドメインによって署名されていなかったかのどちらかです。署名したドメインがFrom:のドメインと同じであることは証明しません。誰でも自分自身のメールに完璧に署名できるからです。
dmarc=SPFかDKIMのどちらかが合格し、かつその合格の対象になったドメインがFrom:のドメインと一致している、ということです。From:のドメインがこのメッセージを許可していなかった、ということです — ヘッダーが「送信者は名乗っている者ではない」と言うことに最も近づく瞬間です。そのメッセージが安全であること、正直であること、望まれていることは何一つ証明しません。今朝登録されたばかりのドメインでも、昼までには非の打ちどころのないDMARCを公開できます。

その最後の列こそが要点であり、ヘッダーの読み方の多くがそこで間違えます。dmarc=passが証明するのは、From:に印字されたドメインがそのメッセージを許可した、ということだけです。そのドメインがあなたから何かを受け取るに値するかどうかについては、何一つ語っていません — そして自分でレコードを公開するのは、誰にとっても10分ほどの作業です。

ヘッダーが教えてくれない5つのこと

  • 送信者がどこにいるか。誰かがメッセージを作成したマシンのアドレスは、たいていブロックのどこにも載っていません。大手ウェブメールプロバイダは何年も前からそれを公開するのをやめており、残っているのは自分たち自身の送信サーバーのアドレスだけで、それはデータセンターの中にあり、教えてくれるのはホスティング会社の名前だけです。
  • 送信者が誰か。ドメインは人ではありません。40分前に取得したばかりのドメインに対するdmarc=passも、まったく正真正銘のpassです。
  • 書かれている内容が本当かどうか。認証が扱うのはエンベロープについてであり、その中身の主張については何も扱いません。請求書は、正しく署名され、正しくアラインメントが取れていながら、中身は完全な作り話ということもあり得ます。
  • 誰かがそれを読んだかどうか。ヘッダーの中にそれを記録するものは何もありません。それを試みるのは本文の中にあるトラッキングピクセルであり、まったく別の仕組みで、対処法も別です。
  • いつ書かれたか。Date:は送信者自身のマシンと、送信者自身の時計から来ています。3時間先の未来のスタンプが押されたメッセージは、興味深い何かである場合よりも、設定を誤ったコンピュータである場合のほうがはるかに多いものです。頼りにできるタイムスタンプは、自分のプロバイダが書いたReceived行の中にあります。

さらに、フィールドのまるごと1つの一族が、その作り自体によって何も証明しません。X-で始まるものはすべて、それを書いた人が勝手に発明した独自拡張であり、送信者は好きなように書くことができます。メッセージの中のX-Spam-Status: Noが意味するのは、そのメッセージが「自分はスパムではない」と自己申告している、ということだけです。

メッセージが一時的なアドレスに届いたとき

このサービスが何を返し、何を返さないのかをはっきりさせておきましょう。ここで読むメッセージは、生のままではなく解析済みの状態で届きます — 送信者、件名、日付、text、HTML、添付ファイル一覧といった、スクリプトが求めるフィールドであり、ヘッダーブロックではありません。ここまでの読み方は、自分の本物のメールを保管しているメールボックスの中で行うものです。

GET /api/v1/message/{id} — 実際に返ってくるもの
{
  "id":           "m_7Kq2fV3xTn",
  "from":         "support@example.com",
  "from_name":    "Example Support",
  "to":           "signup-2026@grabmail.io",
  "subject":      "Confirm your email address",
  "date":         "2026-09-05T09:14:22+00:00",
  "expires_at":   "2026-09-10T09:14:22+00:00",
  "text":         "Confirm your address: <https://example.com/confirm/9a31b0>",
  "text_derived": true,
  "html":         "<!doctype html><html>…",
  "attachments":  []
}

一時的なアドレスが代わりに与えてくれるのは、どのヘッダーフィールドにも太刀打ちできない信号であり、しかも1行も読まないうちから効き始めます。そのアドレスを渡した相手は、ちょうど1つだけだということです。そこに届いたメッセージが別の誰かから来たと主張していても、それは渡した相手が転送したか、その相手がさらに渡した誰かが送ったかのどちらかです。第三の説明はなく、検証すべきことも何もありません。

これはプラスタグが主張しているのと同じ理屈から、タグがコード1行で切り落とされてしまう部分を除いたものです — ここではアドレスそのものが違うので、切り落とすものが何もありません。だからこそ、自分が所有するドメイン上のキャッチオールが、その最も強力な形でもあります。サインアップごとに1つのアドレスを、ドメインを持ち続ける限り保持でき、自分のメールボックスのDelivered-To:が、外に漏れたアドレスの名前を教えてくれます。

それでもできる確認

リンクが何と書いてあるかではなく、どこへ行くのかを見てください。textフィールドは、送信者自身が書いたプレーンテキスト部分か、HTMLをレンダリングしたものかのどちらかであり — どちらなのかはtext_derivedが教えてくれます — レンダリングされたほうは、すべてのリンク先を山括弧の中に残しています。つまり、ボタンが本来連れて行くはずだったアドレスは、ページも画像もピクセルも読み込むことなく、レスポンスの中に丸見えのまま座っているのです。

HTMLのみで届いたメッセージのtextフィールド
Confirm your address: <https://example.com/confirm/9a31b0>

Not you? Ignore this message. <https://example.com/help>

60秒でわかる要約

  1. ソースを開く。使っているクライアントに応じてメッセージのソースを表示View message sourceRaw sourceのいずれかです。
  2. まずAuthentication-Resultsを見つける。自分のプロバイダが書いた1行であり、他の誰にも偽造できない唯一の行です。dmarc=passならFrom:のドメインは本当にそのメッセージを許可しており、dmarc=failならそうではありません。
  3. From:Return-Path:Reply-To:と比べる。ありふれた理由で食い違うことは日常茶飯事です。そして、面白いほうの理由で食い違うこともあります。
  4. Received行を下から上へ読み、自分のプロバイダのものではない最初のマシンのところで、信じるのをやめること。
  5. それから、リンクがどこを指しているかを見る。実際に自分の身に何が起きるかを決めるのは、この部分です。

ここまでの内容はすべて、たった1つの狭い問いに答えているにすぎません。From:のドメインはこのメッセージを許可したのか、という問いです。それは「これは安全か」よりも小さな問いですが、それでも答える価値はあります — ヘッダーがそもそも答えられる問いは、これしかないのですから。

質問

Gmailで完全なヘッダーを見るにはどうすればいいですか?

メッセージを開き、右上の三点リーダーメニューからメッセージのソースを表示を選びます。Gmailは新しいタブを開いて生のメッセージを表示し、その上にはSPF・DKIM・DMARCをすでに判定済みの小さなパネルが表示されます — これはどこよりも早く手に入る判定結果であり、しかも無料です。

メールヘッダーは偽造できますか?

ほとんどの部分は、はい、偽造できます。From:Reply-To:Date:、件名、そしていくらでもでっち上げられるReceived:行は、すべて送信者が入力したものです。偽造できないのは、メッセージが届いたときに自分のプロバイダが書き込んだもの、つまり一番上のReceived行とAuthentication-Resultsです。この2つを読み、残りは証言として扱ってください。

ヘッダーから送信者のIPアドレスは分かりますか?

たいていの場合、思っているものは分かりません。大手ウェブメールサービス経由で送られたメールには、作成に使われたマシンのアドレスではなく、そのサービスの送信サーバーのアドレスが載っています。プロバイダは何年も前から、当然の理由でそちらを公開するのをやめています。アプリケーションや小規模なサーバーが送ったメールでは、一番下のReceived行の角括弧の中に、今でもそれが表示されていることがよくあります — ただし、その行こそがブロックの中で最も偽造しやすい行でもあります。

<code>From:</code>と<code>Return-Path:</code>の違いは何ですか?

From:は送信者が表示させたいものであり、誰にも検証されません。Return-Path:は、サーバーが実際に使ったエンベロープ送信者であり、メッセージを受け取ったマシンによってヘッダーに書き込まれ、バウンスの戻り先になります。SPFが照合するのはReturn-Path:に対してであって、From:に対してでは決してありません。だからこそ、spf=passだけでは、見た目ほどのことは語っていないのです。この2つを揃えることこそが、DMARCの仕事のすべてです。

ヘッダーに<code>dmarc=fail</code>とあります。このメッセージは偽物ですか?

必ずしもそうではありません。転送は設計上SPFを壊しますし、フッターを追加するメーリングリストはDKIMまで壊します。そのため、メーリングリストや大学、あるいは「すべて別のアドレスに転送する」ルールを経由したメールは、完全に本物でありながら日常的にfailします。failが意味するのは、From:のドメインがそのメッセージを支持している証拠が、メッセージの中に何もない、ということだけです。だからこそ、メッセージが何かを求めてきたら、それを確かめる別の経路を用意する価値があります。

<code>Message-ID</code>は何のためにありますか?

これはメッセージの名前です — 一意で、送信サーバーによって割り当てられ、In-Reply-ToReferencesがスレッドを組み立てるために参照する文字列です。実用上の使い道は、サポート窓口やポストマスターが自分たちのログの中でそれを検索できることにあります。Message-IDを添えるかどうかが、「昨日メールが届かなかった」という訴えと、実際に誰かが答えられる質問との違いを生みます。

ここで一時的なアドレスに送られたメールのヘッダーは読めますか?

いいえ — ここで読むメッセージは、送信者、件名、日付、text、HTML、添付ファイル一覧として解析済みの状態で返ってきます。そしてそのフィールドの中に、生のヘッダーブロックは含まれていません。その代わり、使い捨てのアドレスはそれ自体が証拠になります。渡した相手はただ1つなので、他の誰かから届いたメールは、それを外に漏らした相手の名前を、検証すべき署名なしに教えてくれます。メッセージはいずれにせよ5日後に削除されます。

新しいうちに試してみてください

アドレスの取得はワンクリックで、アカウントもカードも不要です。このガイドの内容はすべて、そのアドレスですぐに試せます。

おかえりなさい

受信箱とドメインを、ひとつの場所に。