DKIM、SPF、DMARC は、どれか 1 つを選ぶものではありません。3 つの標準はそれぞれ異なる問いに答えるもので、組み合わせて初めて機能します。SPF は、エンベロープのドメインの名義でメールを送信してよいサーバーを列挙します。DKIM は、あるドメインの下で公開された鍵で作成した署名をメッセージに付加します。DMARC は、表示される From: アドレスと一致するドメインについて少なくとも一方の認証が成功することを求め、ドメイン所有者のポリシーとレポートの送付先アドレスを公開します。
比較表
| SPF | DKIM | DMARC | |
|---|---|---|---|
| 仕様 | RFC 7208(2014年) | RFC 6376(2011年)、RFC 8301、RFC 8463 | RFC 9989、9990、9991(2026年5月)、RFC 7489 の後継 |
| 答える問い | この IP はエンベロープのドメインの名義で送信してよいか | このドメインがこの内容に署名し、内容は改変されていないか | 認証されたドメインが From: のドメインと一致するか、一致しない場合はどうするか |
| 確認する識別子 | MAIL FROM(Return-Path)と HELO | DKIM-Signature の d= のドメイン | From: ヘッダーのドメイン |
| 公開場所 | ドメインの TXT レコード | selector._domainkey.domain の TXT レコード | _dmarc.domain の TXT レコード |
| 単純な転送後も成立するか | いいえ(転送サーバーの IP が記載されていないため) | はい(メッセージが改変されていなければ) | はい(DKIM 経由) |
| メッセージを編集するメーリングリストを経由しても成立するか | いいえ | いいえ(本文または署名対象のヘッダーが変わるため) | リストが From: を書き換えるか、受信側が ARC を信頼する場合のみ |
| 厳格な上限 | 1 回の評価につき DNS 問い合わせを伴う項目は 10 個、応答が空のルックアップは 2 回まで | RSA は 1024 ビット以上(2048 ビットを推奨)、rsa-sha1 は禁止 | DNS ツリーウォークは最大 8 回のクエリ |
| 単独での効果 | 結果を示すだけで、判断は受信側 | 結果を示すだけで、判断は受信側 | ドメイン所有者のポリシー:none、quarantine、reject |
| レポート | なし | なし | XML 形式の集約レポート(rua)、失敗レポート(ruf) |
それぞれの仕組み
SPF は SMTP セッションの最中に評価されます。受信側はエンベロープ送信者のドメイン(バウンスメールの場合は HELO のドメイン)を取り出してその TXT レコードを取得し、接続元の IP を、レコードに列挙された ip4、ip6、a、mx、include の各項目と照合します。結果は pass、fail(-all)、softfail(~all)、neutral、none、またはエラーのいずれかです。include、a、mx、ptr、exists、redirect はそれぞれ DNS ルックアップを 1 回消費し、10 回を超えると結果は permerror になります(RFC 7208 §4.6.4)。こうなると、そのドメインのすべてのメールで SPF が機能しなくなります。
DKIM は、正規化した本文(bh=)と列挙したヘッダー(h=)のハッシュを計算し、ドメインの秘密鍵で署名します。受信側は、s= のセレクターと d= のドメインから名前が決まる TXT レコード(たとえば google._domainkey.github.com)から公開鍵を取得し、署名を検証します。RFC 8301 は rsa-sha1 を禁止し、1024 ビット以上の鍵を必須としています。RFC 8463 は ed25519-sha256 を追加しましたが、検証側の対応がまだ不完全なため、通常は RSA 署名と併せて付与されます。
DMARC は両方の後に実行されます。From: とアライメントが取れたドメインで SPF が成功するか、From: とアライメントが取れたドメインの DKIM 署名の検証に成功すれば、DMARC は成功します。アライメントはデフォルトでは relaxed(組織ドメインが同じであればよく、mail.example.com は example.com とアライメントが取れます)で、aspf=s と adkim=s を指定すると strict になります。
次のスクリプトは、実際のレコードを読み取ります(2026年10月20日、dig 9.10.6 と OpenSSL 3.6.5 で実行)。
echo "== SPF: google.com and its include"
dig +short TXT google.com | grep "v=spf1"
dig +short TXT _spf.google.com
echo "== DMARC: google.com and github.com"
dig +short TXT _dmarc.google.com
dig +short TXT _dmarc.github.com
echo "== DKIM: key size behind two github.com selectors"
for sel in google pf2023; do
printf '%s: ' "$sel"
dig +short TXT "$sel._domainkey.github.com" | tr -d '" \n' | sed 's/.*p=//' \
| openssl base64 -d -A | openssl pkey -pubin -inform DER -noout -text | head -1
done
== SPF: google.com and its include
"v=spf1 include:_spf.google.com ~all"
"v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip6:2001:4860:4864::/56 ip6:2404:6800:4864::/56 ip6:2607:f8b0:4864::/56 ip6:2800:3f0:4864::/56 ip6:2a00:1450:4864::/56 ip6:2c0f:fb50:4864::/56 ~all"
== DMARC: google.com and github.com
"v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com"
"v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@github.com; ruf=mailto:dmarc@github.com; fo=1"
== DKIM: key size behind two github.com selectors
google: Public-Key: (2048 bit)
pf2023: Public-Key: (1024 bit)
注目すべき詳細が 3 つあります。Google の SPF は ~all(softfail)で終わっていますが、DMARC ポリシーは reject です。DMARC のポリシーを強制している場合は DMARC の結果で扱いが決まるため、SPF の修飾子はほとんど影響しません。GitHub は今も pct=100 を公開していますが、これは RFC 9989 で削除されたタグです。受信側は未知のタグを無視し、100 はもともとデフォルト値だったので、害はありません。また、GitHub のセレクターの 1 つは今も 1024 ビットの鍵を使っています。これは RFC 8301 が認める最小の鍵長です。メール認証アナライザーでは、任意のドメインについて同じ確認を実行できます。
結果を決めるのはアライメント
次の表は、From: news@example.com のメッセージについて、典型的な経路ごとの結果を示しています。
| 経路 | SPF | DKIM | DMARC |
|---|---|---|---|
自前のサーバーから送信し、example.com として署名 | pass(アライメント一致) | pass(アライメント一致) | pass |
独自のバウンスドメインを持つメール配信サービスが example.com として署名 | 配信サービスのドメインで pass(アライメント不一致) | pass(アライメント一致) | pass(DKIM) |
| 配信サービスが自身のドメインだけで署名 | pass(アライメント不一致) | pass(アライメント不一致) | fail |
| メールボックスのルールにより改変なしで転送 | fail(転送サーバーの IP) | pass(アライメント一致) | pass(DKIM) |
| メーリングリストがフッターや件名タグを追加 | fail またはアライメント不一致 | fail(本文ハッシュ) | fail(From: が書き換えられるか、ARC が信頼される場合を除く) |
他者のサーバーから From: を偽装 | fail または none | none | fail(ポリシーを適用) |
3 行目は、導入時に最もよくある間違いです。送信元は SPF と DKIM には成功しているのに、認証されたドメインがどちらも自分のものではないため、DMARC には失敗します。各配信サービスで、自分のドメインの下にある鍵で署名するよう設定し(通常は配信サービスの鍵を指す CNAME を使います)、SPF のアライメントも取りたい場合はカスタムのバウンスドメインを使ってください。
転送、メーリングリスト、ARC
SPF が認証するのは最後のホップなので、どのような転送でも SPF は失敗します。Sender Rewriting Scheme(送信者書き換え方式)を使えば転送サーバー自身のドメインで SPF が成功するようになりますが、アライメントが取れることはありません。DKIM は内容を認証するため、メッセージに手を加えない中継は通過できますが、メーリングリストがフッターやタグを追加すると失敗します。ARC(RFC 8617、実験的仕様)を使うと、中継者は自分が確認した認証結果に封印(シール)を施すことができ、そのシールの作成者を信頼する受信側は、DMARC に失敗していてもメッセージを受け入れられます。ARC チェーンビューアーでこのチェーンを確認できます。残る弱点は DKIM リプレイです。正しく署名されたメッセージを新しい受信者に再送信できてしまう問題で、IETF のワーキンググループが DKIM2 のドラフトで対処を進めています。
メールボックスプロバイダーの要件
Gmail は 2024年2月1日から、すべての送信者に対して、SPF または DKIM の使用、正引きと逆引きの両方で有効な DNS、TLS、報告された迷惑メール率 0.3% 未満を求めています。個人の Gmail アカウントに 1 日 5,000 通以上を送信する送信者は、さらに SPF と DKIM の両方、DMARC レコード(p=none で十分)、SPF または DKIM とアライメントが取れた From:、マーケティングメールでのワンクリック配信停止(RFC 8058)も必要です。Yahoo も同時期に同様のルールを導入しました。Microsoft は 2025年5月5日から Outlook.com に同じしきい値を適用し、要件を満たさないメールを 550 5.7.515 で拒否しています。BIMI のロゴには、さらに DMARC を quarantine または reject に設定することが必要です。
RFC 9989(2026年5月)によって DMARC は標準化過程(Standards Track)に移り、レコードも変更されました。pct、rf、ri は廃止され、テスト用には pct=0 の代わりに t=y を使います。np は存在しないサブドメインに対するポリシーを設定し、psd はパブリックサフィックスのドメインであることを示します。また、組織ドメインの特定には、Public Suffix List の代わりに DNS ツリーウォークを使います。
それぞれの用途
- SPF:自分の送信サーバーと、自分のドメインをバウンスアドレスに使う配信サービスを許可します。メールを送信しないドメインとサブドメインには
v=spf1 -allを公開します。 - DKIM:配信サービス経由で送るメールも含め、すべての送信メールに自分のドメインで署名します。セレクターは少なくとも年に 1 回ローテーションし、1024 ビットの鍵は 2048 ビットの鍵に置き換えます。
- DMARC:まずレポートを収集し、その後でポリシーを強制します。
np=reject(またはsp=reject)を追加して、攻撃者が架空のサブドメインを使えないようにします。 - パークドメイン:
v=spf1 -allとv=DMARC1; p=reject;を公開し、DKIM セレクターは置きません。 - 通信経路の保護と内容の保護は別の問題です。サーバー間の TLS には MTA-STS を、エンドツーエンドの署名には S/MIME または OpenPGP を使います。
移行時の注意点
- 送信元を洗い出します。
p=noneのまま 2〜4 週間、DMARC の集約レポートを使って確認します。正規の送信元はすべて、アライメントの取れた DKIM、アライメントの取れた SPF、またはその両方を示している必要があります。 - まず DKIM を修正します。各配信サービスで独自ドメインによる署名を有効にし、2048 ビットの鍵を公開して(DKIM レコード生成ツールは鍵を 255 文字ずつの文字列に分割します)、DKIM デバッガーで検証します。
- SPF を整理し、使われていない include を削除してルックアップを 10 回未満に抑えます。IP アドレス範囲へのフラット化は、自動で更新し続けられる場合に限ってください。
- 段階的に強制します。まず
t=y付きのp=quarantineで様子を見て、次にp=quarantine、最後にp=rejectへ移行します。ruaレポートは受け取り続けてください。 spまたはnpでサブドメインを保護し、メールを送信すべきでないすべてのドメインに null レコードを公開します。