メールの差出人は、実は誰でも自由に名乗れます。SMTPというプロトコルには、差出人が本人かどうかを確認する仕組みがもともと入っていません。この欠陥を後付けで埋めるために作られたのが SPF・DKIM・DMARC の3点セットです。
3つとも「なりすまし対策」と説明されるため混同されがちですが、検証している対象がそれぞれ違います。この記事では、何をどう検証しているのかを整理したうえで、設定の順序、p=none から p=reject へ安全に移行する手順、そして「設定したのに認証に失敗する」という典型的なつまずきどころまで扱います。
3つの仕組みは、それぞれ別のものを見ている
| 何を検証するか | どこに設定するか | 弱点 | |
|---|---|---|---|
| SPF | 送信元IPアドレスが、そのドメインの許可リストに載っているか | DNSのTXTレコード | 転送されるとIPが変わり失敗する |
| DKIM | メールに付いた電子署名が正しいか(改ざんされていないか) | DNSのTXTレコード+送信側で署名 | 本文が書き換わると失敗する |
| DMARC | 上の2つの結果と表示される差出人が食い違っていないか、失敗時にどう扱うか | DNSのTXTレコード | SPFかDKIMが正しく動いていることが前提 |
重要なのはDMARCが単体では機能しないことです。DMARCはSPFとDKIMの結果を受け取って判定する仕組みなので、土台となる2つを先に整える必要があります。
SPF:どのサーバーから送ってよいかを宣言する
SPFは「このドメインのメールは、これらのIPアドレスからしか送りません」という宣言をDNSに書いておく仕組みです。受信側は接続元IPがリストに含まれるかを確認します。
設定でつまずきやすいのがDNSルックアップ10回の上限です。include: で外部サービスを次々に追加していくと、それぞれが内部でさらに include を持っているため、気づかないうちに上限を超えます。超えると結果は permerror となり、SPFは無効として扱われます。送信サービスを増やしたあとにメールが届かなくなった場合は、まずこの上限を疑ってください。
もう一つ、末尾の指定にも意味があります。-all(ハードフェイル)はリスト外からの送信を拒否させる指定、~all(ソフトフェイル)は「怪しいが受け取ってよい」という指定です。移行期間中は ~all で様子を見て、送信元を把握しきってから -all にするのが安全です。
DKIM:本文とヘッダーに署名する
DKIMは送信時にメールへ電子署名を付け、受信側がDNSに公開された鍵で検証する仕組みです。IPアドレスではなくメールそのものを検証するため、転送されても署名は有効なままです。ここがSPFとの決定的な違いです。
署名の仕組みは公開鍵暗号そのものなので、原理を押さえたい方は 公開鍵暗号の基本 を、ハッシュの役割については Hash Generator で実際に値の変化を見てみると理解が早くなります。本文が1文字でも変われば署名検証は失敗する、という性質はハッシュの雪崩効果に由来します。
注意点は鍵長です。1024ビットの鍵はまだ広く使われていますが、可能なら2048ビットを選びます。またセレクタ(selector._domainkey.example.com の先頭部分)を使い分けることで、送信サービスごとに別の鍵を持てます。鍵のローテーションもセレクタを切り替えることで無停止に行えます。
DMARC:表示される差出人との一致まで見る
SPFとDKIMには共通の穴があります。受信者が実際に画面で見る差出人(ヘッダーFrom)を検証していないのです。攻撃者は自分が管理するドメインで正しくSPFとDKIMを通したうえで、表示上の差出人だけを有名企業のアドレスに偽装できます。認証は通っているのに、見た目は正規のメールという状態です。
この穴を塞ぐのがDMARCのアライメントという考え方です。DMARCは、SPFやDKIMで検証されたドメインと、受信者が見るヘッダーFromのドメインが一致しているかまで確認します。
DMARCが「合格」になる条件
ここが最も誤解されやすい部分です。DMARCの判定は次の条件になっています。
- SPFの認証に成功し、かつSPFのアライメントも成立している、または
- DKIMの認証に成功し、かつDKIMのアライメントも成立している
どちらか一方が満たされればDMARCは合格です(両方は必要ありません)。逆に言えば、SPFが通っただけでは不十分で、アライメントまで成立して初めて意味を持ちます。「SPFもDKIMも設定したのにDMARCが失敗する」という相談の大半は、認証そのものではなくアライメントが原因です。
典型的なのが、メール配信サービスを使っているケースです。配信サービスのドメインでSPFが通っていても、ヘッダーFromが自社ドメインのままなら、両者は一致せずアライメントが成立しません。この場合は、配信サービス側で自社ドメインのDKIM署名を設定するか、Return-Pathを自社のサブドメインに向ける設定が必要になります。
p=none から reject への移行手順
DMARCレコードのポリシーは3段階あり、いきなり最も強い設定にすると正規のメールまで届かなくなります。必ず段階を踏んでください。
| ポリシー | 認証失敗時の扱い | 使う場面 |
|---|---|---|
p=none | 何もしない(通常どおり配信) | 最初に必ずここから。レポートで送信元を洗い出す監視モード |
p=quarantine | 迷惑メールフォルダへ隔離 | 中間段階。影響を確認しながら強度を上げる |
p=reject | 受信を拒否(配信されない) | 最終目標。なりすましを実際に止められる状態 |
p=none は「対策していない状態」ではなく、自社ドメインから誰が何を送っているかを可視化する段階です。DMARCレポートを受け取る設定(rua=)を必ず入れてください。ここで、情報システム部門が把握していなかった送信元が見つかることがよくあります。営業部門が個別契約したメール配信サービス、古い業務システムからの通知メール、といったものです。これらを洗い出さずに強いポリシーへ進むと、業務メールが止まります。
レポートを見て送信元を全部把握し、それぞれSPF/DKIMを整えてからquarantineへ、さらに問題がなければrejectへ、という順序が安全です。急がず数週間から数か月かける前提で計画してください。
Gmailの送信者ガイドライン(2024年2月以降)
メール認証が「推奨」から「実質必須」に変わったのは、GoogleとYahooが送信者要件を厳格化したことがきっかけです。Gmail宛にメールを送るなら、以下は満たしておく必要があります。
すべての送信者に求められる要件
- 送信元ドメインにSPFまたはDKIMを設定していること
- 送信元のドメインまたはIPに、有効な正引き・逆引きDNSレコード(PTR)があること
- メール送信にTLS接続を使うこと
- Postmaster Toolsで報告される迷惑メール率を0.3%未満に維持すること
- RFC 5322に準拠した形式であること、Gmailのドメインを差出人に偽装しないこと
1日5,000件以上を送る場合の追加要件
- SPFとDKIMの両方を設定すること(どちらか一方では不可)
- DMARCを設定すること。ただしポリシーは
p=noneでも要件を満たす - ヘッダーFromのドメインが、SPFまたはDKIMのドメインと一致していること(アライメント)
- マーケティング目的のメールにはワンクリックでの登録解除を実装すること(
List-Unsubscribe-PostとList-Unsubscribeヘッダー)
迷惑メール率0.3%というしきい値は、体感よりかなり厳しい数字です。1,000通に3通で上限に達します。配信リストの整理(反応のないアドレスの除外、退会処理の確実な反映)まで含めて運用する必要があります。
設定したのに失敗する、よくある原因
メール転送でSPFが壊れる
SPFは接続元IPを見る仕組みなので、転送されると送信元IPが転送サーバーのものに変わり、必ず失敗します。大学や企業の転送アドレス、メーリングリストを経由するとこれが起きます。DKIMは署名がメールに付いて回るため転送されても残ります。DMARCがSPFとDKIMのどちらか一方でよい設計になっているのは、この転送問題があるためです。逆に言えば、転送されうる環境ではDKIMが実質的に必須になります。
メーリングリストで本文が書き換わりDKIMが壊れる
メーリングリストの中には、件名に [list-name] を付けたり、本文末尾にフッターを追加したりするものがあります。これらはメールを改変するためDKIM署名の検証に失敗します。SPFも転送で失敗するため、両方落ちてDMARCも失敗します。この問題への対処としてARCという別の仕組みがありますが、対応状況はまちまちです。p=reject へ進む前に、社内のメーリングリスト運用を確認しておいてください。
SaaSからの送信で認証が通らない
請求システム、問い合わせフォーム、SFA、監視ツールなど、自社ドメインを差出人にして送信するSaaSは想像以上に多いものです。それぞれについてSPFへの追加やDKIM署名の設定が必要になります。前述のSPF10回制限に引っかかりやすいのもこのケースです。p=none の期間にDMARCレポートを読んで、把握していない送信元を全部洗い出すのが唯一の確実な方法です。
なりすまし対策としての限界
DMARCを p=reject まで進めても、防げるのは自社ドメインを騙るなりすましだけです。攻撃者はよく似た別ドメイン(examp1e.co.jp のような紛らわしい綴り、あるいは example-support.com のような追加語)を取得して送ってきます。これは自社のDMARCでは止められません。
受信側での見分け方については QRコードを悪用したフィッシング や ClickFix(偽CAPTCHA)の手口 で扱っています。紛らわしいドメインやURLの構造を確認するには URL Parser が使えます。実際に接続されるホスト名を分解して表示するので、@ を使った偽装やpunycodeによるホモグラフ詐欺の判別に役立ちます。
また、DMARCはメール本文の内容までは検証しません。正規ドメインのアカウントが乗っ取られて送信された場合、認証はすべて合格します。認証情報の窃取については インフォスティーラーとセッション乗っ取り を、多要素認証による防御は MFA / TOTP / FIDO2 の違い を参照してください。
設定チェックリスト
- ☐ SPFレコードを設定し、DNSルックアップが10回を超えていないことを確認した
- ☐ DKIM署名を設定した(鍵長は可能なら2048ビット、送信サービスごとにセレクタを分けた)
- ☐ DMARCを
p=noneで公開し、rua=でレポート受信先を指定した - ☐ 数週間レポートを読み、自社ドメインで送信している全サービスを洗い出した
- ☐ 洗い出した送信元すべてでアライメントが成立するよう設定した
- ☐ 社内のメーリングリスト・転送設定への影響を確認した
- ☐
p=quarantineへ移行し、正規メールが隔離されていないか確認した - ☐
p=rejectへ移行した - ☐ 1日5,000件以上送る場合、ワンクリック登録解除を実装した
- ☐ 迷惑メール率が0.3%を下回っているかPostmaster Toolsで継続確認している
実体験:DNSの設定はサイト運営でも避けて通れなかった
本サイトを独自ドメインで運用し始めたとき、最初につまずいたのがDNSレコードの設定でした。ドメインを取得してもすぐには反映されず、設定が正しいのか、単に浸透待ちなのかの区別がつかず戸惑ったのを覚えています。TXTレコードについては、Google Search Consoleの所有権確認で実際に設定しました。SPFもDKIMもDMARCも同じTXTレコードに書く仕組みなので、「DNSに文字列を置いて、それを第三者が読みに来て検証する」という構造は共通だと理解できたのは、この作業を通じてでした。
メール認証を調べていて意外だったのは、DMARCがSPFとDKIMの「どちらか一方でよい」設計になっている理由です。当初は両方必須にした方が安全ではないかと考えていましたが、転送するとSPFが必ず壊れるという現実があるため、両方を必須にすると正規のメールが大量に弾かれてしまう。厳しくしすぎると使い物にならなくなるので、実運用に耐えるところで妥協している、という設計判断がそこにありました。セキュリティの仕組みは「理論上最も強い設定」ではなく「運用が回る範囲で最も強い設定」で作られている、という例として腑に落ちた部分です。
本サイトは現在メール配信を行っていないため p=reject の運用経験はありませんが、逆に言えばメールを送らないドメインこそ、なりすまし対策としてDMARCを設定する価値があります。送信実績がなければ正規メールを止めてしまう心配がないので、最初から強いポリシーを設定できるからです。使っていないドメインが放置されて、なりすましメールの発信元として使われる事故は実際に起きています。
参考にした一次情報
- Google「メール送信者のガイドライン」(Gmail ヘルプ)— 全送信者の要件、5,000件以上の追加要件、迷惑メール率0.3%、ワンクリック登録解除
- RFC 7208(SPF)・RFC 6376(DKIM)・RFC 7489(DMARC)— 各仕様の定義
送信者要件は改定されることがあります。実際の設定前に、Google および Yahoo の最新のガイドラインを確認してください。
おわりに
3つの仕組みは役割が分かれています。SPFはIPを、DKIMはメールそのものを、DMARCは表示される差出人との一致と失敗時の扱いを決めています。この分担さえ押さえておけば、設定でつまずいたときにどこを見ればよいかの見当が付きます。
そして最も重要なのは順序です。p=none でレポートを読み、送信元を全部把握してから強度を上げる。この手順を飛ばすと、なりすましではなく自社の業務メールが止まります。急がず進めてください。