SPF・DMARC でなりすましメールを防ぐ
メールの差出人は、誰でも自由に名乗れます。あなたの会社のドメインを差出人にしたフィッシングメールを、第三者が今この瞬間に送れる状態かもしれません。SPF と DMARC はそれを止める仕組みです。メールを 1 通も送っていないドメインでも必要な理由から説明します。
なりすましメールは、なぜ送れてしまうのですか?
メール送信の規格(SMTP)に、差出人を確認する仕組みが最初から無いからです。差出人欄は封筒の裏に書く住所と同じで、送る側が自由に名乗れます。SPF・DKIM・DMARC は、この欠陥を後から DNS で補うために作られた仕組みです。
SMTP が設計された 1980 年代、インターネットは互いに顔の見える研究機関の集まりでした。差出人を詐称する動機が誰にも無かったため、差出人が本物かを確認する仕組みは、そもそも規格に入っていません。 今日でも、メールサーバーに接続して「私は president@example.com です」と名乗れば、そのまま通ります。
ここで、実際のメールには 2 つの差出人があることを押さえてください。この区別が、後の話の全ての土台になります。
| 種類 | 実体 | 受信者に見えるか | SPF が見るのは |
|---|---|---|---|
| 封筒の差出人 | MAIL FROM / Return-Path。配送エラーの返送先 | 見えない(ヘッダを開かない限り) | こちら |
| ヘッダの差出人 | From:。メールソフトが表示する差出人 | これが見える | 見ていない |
SPF が検査するのは、受信者に見えないほうの差出人です。この一点が、後で説明する「SPF だけでは防げない」の正体です。
SPF とは何ですか?
SPF は「このドメインからのメールは、これらのサーバーからしか送られません」という宣言を DNS の TXT レコードに書いておく仕組みです。受信側は接続元 IP がその一覧に含まれるかを照合し、含まれなければ偽物の可能性が高いと判断できます。
; メールを送るドメインの SPF。送信に使うサービスを include で並べる
example.com. IN TXT "v=spf1 include:_spf.google.com include:spf.brevo.com ~all"
; ★ SPF レコードは 1 ドメインに 1 本だけ。
; "v=spf1" で始まる TXT が 2 本あると permerror になり、**SPF 判定そのものが無効化**される。
; Google Workspace 導入時と配信サービス導入時に別々の担当が足して 2 本になる、が定番の事故。
; 正: 1 本にまとめて include を並べる
; 誤: "v=spf1 include:_spf.google.com ~all" と "v=spf1 include:spf.brevo.com ~all" の 2 本末尾の all 修飾子が本体
; 末尾の all 修飾子 — 一覧に載っていない IP から来たときどうするか
"v=spf1 include:_spf.google.com -all" ; hardfail: 拒否してよい(最も厳格)
"v=spf1 include:_spf.google.com ~all" ; softfail: 怪しいが受け取る(DMARC 併用時の実用的な既定)
"v=spf1 include:_spf.google.com ?all" ; neutral: 判定しない = 対策になっていない
"v=spf1 include:_spf.google.com +all" ; ★ どこからでも許可。SPF が無いより悪い。絶対に書かないDMARC と併用する場合、~all(softfail)で十分です。最終的な処遇は DMARC のポリシーが決めるためで、 SPF 側を -all にすると、後述する転送の問題が悪化することがあります。メールを送らないドメインだけは、迷わず -all にしてください。
DNS ルックアップ 10 回の上限
SPF の評価では include・a・mx・redirect などが DNS 問い合わせを発生させ、その合計が 10 回を超えると permerror となり、SPF の判定そのものが無効になります。 しかも include の先がさらに include していれば、それも合算されます。
つまり「送信サービスを足していったら、ある日突然 SPF が全部効かなくなる」ことが起きます。 自分のレコードには include が 4 つしか無くても、その先が展開されて 11 回になっている、というのが典型です。本ツールはこの回数超過も検出します。
メールを送らないドメインにも SPF・DMARC が必要なのはなぜですか?
何も宣言していないドメインは、受信側にとって「偽物と判定する根拠が無い」ドメインだからです。つまり第三者があなたのドメインを名乗り放題になります。むしろメールを使っていないドメインのほうが、正当な送信との誤判定を心配せずに、最初から最も厳しい設定にできます。
これは実務で最も多い誤解です。「うちはこのドメインでメールを送っていないから、SPF は関係ない」——逆です。狙われるのは、まさにそういうドメインです。
攻撃者から見れば、SPF も DMARC も無いドメインは「安全に騙れるドメイン」です。 受信側には偽物と判定する根拠が一切無いので、invoice@あなたの会社.co.jp を名乗る請求書偽装メールが、そのまま取引先の受信箱に届きます。 しかも、あなたはメールを運用していないのでその事実に気づくことすらできません。
そして、メールを送っていないドメインには大きな利点があります。誤爆の心配が原理的に存在しないため、段階導入すら不要で、初日から最強の設定を入れられます。
; ── メールを一切送受信しないドメインの「完全防御」セット ──
; コーポレートサイト専用ドメイン、リダイレクト用ドメイン、旧ブランドのドメインなど
; 1. このドメインからメールは 1 通も出ない
example.com. IN TXT "v=spf1 -all"
; 2. このドメインはメールを受け取らない(RFC 7505 の null MX)
; 「設定漏れ」ではなく「明示的な宣言」として受信側に伝わる
example.com. IN MX 0 .
; 3. 認証に失敗したものは全部拒否。送っていないのだから誤爆しようがない
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
; 4. どのセレクタの DKIM 鍵も無効(p= が空 = 失効を意味する)
*._domainkey.example.com. IN TXT "v=DKIM1; p="この 4 行を入れるだけで、そのドメインを騙るメールは受信側でほぼ確実に拒否されます。所要時間は 5 分、リスクはゼロです。リダイレクト用に取っただけの旧ドメインや、キャンペーン用ドメインこそ、今すぐこれを入れてください。
SPF だけではなぜ不十分なのですか?
SPF が照合するのは、受信者には見えない「封筒」側の差出人だからです。攻撃者は封筒に自分のドメインを書いて SPF を通過させ、画面に表示される From: だけをあなたのドメインに偽装できます。この 2 つが一致しているかを検査する仕組みが DMARC で、これが無いと SPF は素通りされます。
攻撃者は SPF を「通過させた上で」偽装する
手口はこうです。SPF に違反すらしません。
- 攻撃者が自分のドメインを用意する — evil.example という自前ドメインを取り、正規に SPF を設定する。ここは何も嘘をついていない
- 封筒の差出人は自分のドメインにする — MAIL FROM: bounce@evil.example。SPF はこれを照合するので、当然 pass する
- From: だけをあなたのドメインにする — From: president@あなたの会社.co.jp。SPF はこのヘッダを見ていないので、何のエラーにもならない
- 受信者には、あなたからのメールとして表示される — SPF は pass。受信箱には社長からのメールが届く。これが SPF 単体の限界
封筒とヘッダが一致しているかを、誰も検査していない——これが穴です。そこを塞ぐのが DMARC のアライメント検査です。
転送されると SPF は壊れる
もう 1 つの限界です。メーリングリストや .forward で転送されると、受信側から見た接続元 IP は転送サーバーの IPになります。当然あなたの SPF には載っていないので、正当なメールなのに SPF が fail します。
ここで DKIM が効きます。DKIM はメール本文とヘッダへの電子署名なので、転送されても署名は生き残ります(本文や件名が改変されなければ)。 そしてDMARC は SPF と DKIM の「どちらか一方」が通ればよい設計です。だから両方入れる価値があります。
DMARC とは何ですか?
DMARC は 2 つの役割を持ちます。1 つは、SPF や DKIM で認証されたドメインと、画面に表示される From: のドメインが一致しているかを検査すること(アライメント)。もう 1 つは、認証に失敗したメールをどう扱うかを、ドメイン所有者側から受信側に指示することです。
| 検査 | 比較するもの | 通過条件 |
|---|---|---|
| SPF アライメント | 封筒の差出人ドメイン と From: のドメイン | SPF が pass し、かつ両者が一致 |
| DKIM アライメント | 署名の d= ドメイン と From: のドメイン | 署名が検証でき、かつ両者が一致 |
この 2 つのうち、どちらか一方でも通れば DMARC は passです。両方失敗して初めて、p= で指定した処遇(隔離・拒否)が発動します。
先ほどの攻撃を当てはめてみてください。封筒は evil.example、From: は あなたの会社.co.jp でした。 SPF は pass しますがアライメントは一致しません。DKIM 署名も、あなたの秘密鍵が無いので作れません。よって DMARC が fail し、拒否できます。SPF を「意味のある防御」に変えているのは DMARC のほうです。
なぜ p=none では何も防げないのですか?
p=none は「認証に失敗しても、これまでどおり配送してください」という指示だからです。レポートは届くようになりますが、なりすましメールは今までどおり受信箱に入ります。DMARC を設定したのに効果が無いという場合、ほぼ確実にこれが原因です。
p=none は監視モードです。受信側は認証結果をレポートで教えてくれますが、処遇は今までどおり——つまりなりすましメールは受信箱に届き続けます。
本ツールが p=none を pass ではなく警告として扱うのはこのためです。設定されてはいますが、防御としては機能していません。「DMARC 設定済み」と「なりすましを防げている」は別です。
とはいえ p=none は無意味ではありません。正当な送信元を洗い出すための必須の準備段階です。 問題なのは、ここで満足して止まってしまうことです。実際、DMARC を設定した多くのドメインが p=none のまま何年も放置されています。
p=reject へはどう進めればよいですか?
p=none で 2〜4 週間レポートを集め、正当な送信元をすべて洗い出すところから始めます。次に p=quarantine を一部の割合から適用し、問題が出なければ 100% へ、最後に p=reject へ進みます。順番を飛ばすと、請求書や問い合わせ通知が静かに消え始めます。
; ── 段階導入 ──
; 【第 1 段階】監視のみ。2〜4 週間。**この時点では何もブロックされない**
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1"
; 【第 2 段階】隔離を一部から。まず 10%、問題なければ 25 → 50 → 100 と上げる
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=10; rua=mailto:dmarc@example.com"
; 【第 3 段階】拒否。サブドメインにも同じ扱いを適用する
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@example.com"
; ── 主なタグ ──
; p 必須。none / quarantine / reject
; rua 集約レポートの宛先。**実質必須**。これが無いと現状を把握できない
; sp サブドメイン用のポリシー。未指定なら p を継承
; pct ポリシーを適用する割合。段階導入用(一部の受信側は正しく扱わない点に注意)
; fo 失敗レポートの条件。fo=1 は SPF/DKIM いずれかが失敗したら報告
; adkim / aspf アライメントの厳格さ。r=緩い(既定)/ s=厳格飛ばしてはいけない理由
いきなり p=reject を入れると、「自分たちが送っていることを忘れていた正当なメール」が消えます。 これは静かに起きるので、気づいたときには数週間ぶんの機会損失になっています。rua レポートで洗い出すべき、忘れられがちな送信元の例です。
- 会計ソフト・請求書発行サービスからの自動送信
- 採用管理システム、問い合わせフォームの自動返信
- 営業部門が個別に契約した MA ツールやメール配信サービス
- 古いサーバーに残っている cron のアラートメール
- 他社に委託しているメールマガジン
rua レポートは XML の圧縮ファイルで届き、そのまま読むのはかなり厳しいものです。無料のレポート解析サービスを使うか、量が少なければ手元で展開して構いません。重要なのは、レポートの宛先を設定していないと、この洗い出しが原理的にできないということです。rua は必ず入れてください。
DKIM はこのツールで判定できますか?
断定できません。DKIM の設定は「セレクタ」という名前の DNS レコードにありますが、この名前は送信側が自由に決められ、DNS から一覧を取得する方法が存在しないためです。本ツールはよく使われる 15 種類を推測で照会し、見つからなくても「未設定」とは判定しません。
理由は DNS の構造にあります。DKIM の公開鍵は <セレクタ>._domainkey.example.com という名前の TXT レコードに置かれますが、この「セレクタ」の部分は送信側が自由に決められます。google かもしれないし、s7f3k かもしれません。
そして DNS には、あるドメイン配下のレコードを列挙する仕組みがありません(ゾーン転送は通常拒否されます)。つまり名前を知らないレコードは、外部から発見しようがないのです。 SPF が example.com、DMARC が _dmarc.example.com と場所が固定なのとは対照的です。
本ツールが実際に照会している 15 種類は、次のとおりです。
defaultgoogleselector1selector2k1dkimmails1s2brevosendgridzohomandrilleverlytickey1smtp
これで見つからなかった場合、本ツールは 「未設定」ではなく「確認できませんでした」と表示します。 独自のセレクタ名で正しく運用されている可能性が十分にあるからです。DKIM が「無い」ことを外部から証明する方法は存在しません。できない判定を、できたふりで断定するくらいなら、正直に分からないと言うべきだと考えています。
自社の DKIM 設定を確認したい場合は、外から探すのではなく、メール送信サービス(Google Workspace / Microsoft 365 / Brevo / SendGrid など)の管理画面を見てください。 セレクタ名はそこに書いてあります。
設定できているか確認するには?
dig コマンドで実際の DNS レコードを直接引くのが最も確実です。管理画面上は正しく見えても、実際には反映されていないことがあります。本ツールの診断でも SPF・DMARC・MX の実レコードと、その内容の妥当性まで判定します。
# SPF(v=spf1 の TXT が 1 本だけあるか)
dig +short TXT example.com | grep spf1
# DMARC(_dmarc サブドメインの TXT)
dig +short TXT _dmarc.example.com
# MX(null MX なら "0 ." が返る)
dig +short MX example.com
# DKIM は **セレクタ名を知っていないと引けない**。
# Google Workspace なら通常 "google"、Microsoft 365 なら "selector1" / "selector2"
dig +short TXT google._domainkey.example.comDNS の変更は即座には広まりません。TTL のぶんだけ古い値がキャッシュされ続けるので、変更直後に確認して「反映されていない」と慌てないでください。TTL を短くしてから作業すると楽になります。
本ツールの診断では、SPF・DMARC・DKIM・MX の 4 項目を実レコードから判定します。+all や p=none のような「設定はあるが効いていない」状態も個別に警告します。 あわせて DNSSEC・CAA・ネームサーバーも確認できます。
仕様の一次情報は RFC 7208(SPF)、RFC 7489(DMARC)、RFC 7505(null MX) です。Gmail への到達要件は Google の送信者ガイドライン にまとまっています。Web 側のセキュリティ設定については セキュリティヘッダ 7 種の意味と設定 と CSP の導入手順 を参照してください。