2026年6月5日

2026年6月5日

DKIMの検証手順|DNSの公開鍵・署名ヘッダー・受信側の判定結果を順に確かめる

DKIM が正しく動いているかは、「DNS に公開鍵が正しく載っているか」「送信メールに DKIM-Signature ヘッダーが付いているか」「受信側が dkim=pass と判定しているか」の3点を、この順に確かめると切り分けられます。この記事では、dig による公開鍵の確認、opendkim-testkey や dkimpy を使った検証、Gmail などで受信したメールの Authentication-Results ヘッダーの読み方、そして fail になったときの原因と直し方を、確認しやすい順に解説します。DKIM の初期設定そのものは扱わず、「設定したはずだが本当に効いているか」を確かめたい人向けの内容です。

DKIMの検証で見る3つのポイント

DKIM は、送信サーバーがメールの一部のヘッダーと本文から署名を作り、受信サーバーが DNS に公開された公開鍵でその署名を検証する仕組みです。検証が失敗する場所は、大きく次の3つに分かれます。

  1. DNS 側:セレクタ名の TXT レコードが無い、値が壊れている、反映前である
  2. 送信側:署名が付いていない、付いていても想定と違うドメイン(d=)やセレクタ(s=)で署名している
  3. 経路・受信側:署名後にメールの本文やヘッダーが書き換えられ、検証が合わなくなる

どこで失敗しているかによって直す場所がまったく違うため、いきなり鍵を作り直すのではなく、上から順に確認していくのが近道です。

手順1:DNSに公開鍵が載っているか確かめる

DKIM の公開鍵は セレクタ._domainkey.ドメイン という名前の TXT レコードに置かれます。セレクタ名は送信サービスや OpenDKIM の設定で決めた文字列で、default、mail、selector1 などがよく使われます。まず送信側の設定画面や設定ファイルで、実際に使っているセレクタ名を確認してください。

# セレクタ名が "mail"、ドメインが example.com の場合
dig +short TXT mail._domainkey.example.com

# 公開DNSと権威DNSの両方に聞いて、結果が同じか比べる
dig +short TXT mail._domainkey.example.com @8.8.8.8
dig +short NS example.com
dig +short TXT mail._domainkey.example.com @ns1.example.net

正しく載っていれば、次のような文字列が返ります(値はダミーです)。

"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA" "...公開鍵の続き...IDAQAB"

ここで確認するのは次の点です。

  • 何も返らない:セレクタ名の綴り、レコードを登録したドメイン(サブドメインと取り違えていないか)、反映待ちかどうかを確認します。権威 DNS では返るのに公開 DNS で返らない場合は、キャッシュの期限切れを待つ段階です。
  • CNAME が返る:Microsoft 365 や一部のメール配信サービスは、鍵を CNAME で委任する方式です。CNAME の先で TXT が返れば問題ありません。
  • 文字列が複数に分かれている:2048 ビット鍵は1つの文字列(255 バイトまで)に収まらないため、上の例のように引用符で区切られた複数の文字列になります。これは正常で、受信側は連結して読みます。問題になるのは、管理画面に貼り付けたときに途中で改行や余計な空白、引用符が混ざって鍵が壊れたケースです。
  • **p= が空**:鍵が失効扱いになっています。古いセレクタを無効化した状態なので、送信側が新しいセレクタで署名しているか確認します。
  • **t=y が付いている**:テストモードの印です。受信側によっては検証結果を重く扱わないことがあるため、検証が済んだら外すことを検討します。

OpenDKIM を使っている場合は、サーバー上の秘密鍵と DNS の公開鍵が対になっているかを opendkim-testkey で確かめられます。

opendkim-testkey -d example.com -s mail -vvv

key OK と出れば一致しています。key not secure と表示されることがありますが、これはそのゾーンが DNSSEC で署名されていないという意味で、鍵自体の不一致ではありません。

手順2:送信メールに署名が付いているか確かめる

DNS が正しくても、送信側が署名していなければ DKIM は機能しません。自分宛てにテストメールを送り、受信したメールのヘッダー全体を表示します。Gmail では各メールのメニューにある「メッセージのソースを表示」に相当する項目から確認できます(表記は変わることがあります)。

ヘッダーに次のような行があるかを探します。

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mail;
 h=from:to:subject:date:message-id; bh=...; b=...

各タグの意味と見るべき点は次のとおりです。

  • d=:署名したドメインです。DMARC で合格させたい場合は、From ヘッダーのドメインと一致する(または同じ組織ドメインのサブドメインである)必要があります。メール配信サービスの既定のドメインで署名されていると、DKIM 自体は pass でも DMARC の整合性が取れません。
  • s=:セレクタです。手順1で調べた名前と一致しているか確認します。
  • h=:署名の対象にしたヘッダーの一覧です。仕様上、From ヘッダーは署名対象に含めることが求められています。
  • bh= と b=:本文のハッシュと署名本体です。
  • c=:正規化の方式です。relaxed/relaxed は空白の揺れなどに寛容で、経路での小さな書き換えに強くなります。

DKIM-Signature 行が無い場合は、送信経路を確認します。WordPress から送るメールが、署名を行う SMTP サーバーや配信サービスを経由せず、Web サーバーのローカルの sendmail から直接出ていることはよくあります。SMTP 送信用のプラグインで送信先を切り替えているか、プラグインの設定とメールログを見て確かめてください。

手順3:受信側の判定結果を読む

受信サーバーは、検証結果を Authentication-Results ヘッダーに記録します。Gmail で受信した場合は、次のような行になります。

Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=mail header.b=AbCdEf12;
       spf=pass smtp.mailfrom=bounce.example.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com

dkim=pass で、かつ header.i のドメインが From のドメインと揃っていれば、DKIM は期待どおりに動いています。結果の値ごとの意味は次のとおりです。

  • pass:署名の検証に成功
  • fail / neutral:署名はあるが検証に失敗。括弧内に body hash did not verify などの理由が出ることがあります
  • temperror:DNS の一時的なエラー。時間をおいて再送して変わるか確認します
  • permerror:鍵の書式が壊れているなど、恒久的なエラー
  • none:署名が無い

複数の DKIM 署名が付いているメールでは、dkim=pass が複数行並ぶこともあります。どの d= の署名が pass しているのかを見分けてください。

保存したメールをコマンドで検証したい場合は、Python の dkimpy パッケージに含まれる dkimverify が使えます。

pip install dkimpy
# .eml 形式で保存したメールを標準入力から渡す
dkimverify < message.eml

signature ok と出れば、その時点の DNS の鍵で検証に成功しています。受信後にメールソフトが改行コードを変えて保存していると失敗することがあるため、結果が受信サーバーの判定と食い違うときは保存方法も疑ってください。

dkim=failになるときの原因と確認方法

よくある原因を、起こりやすい順に並べます。

1. 署名後に本文やヘッダーが書き換えられている

body hash did not verify と出る場合の多くはこれです。メーリングリストのフッター追加、セキュリティ製品による件名へのタグ付けや本文の書き換え、転送サービスでの変換などが該当します。経路を通さずに直接 Gmail 宛てに送って pass になるなら、途中の仕組みが原因です。正規化を relaxed/relaxed にする、書き換えを行う装置より後で署名する、といった対策を検討します。

2. セレクタやドメインの取り違え

ヘッダーの s= と DNS に登録したセレクタ名、d= と TXT を置いたドメインが一致しているかを確認します。複数の送信サービスを併用していて、それぞれ別のセレクタを使う構成では特に起きやすい誤りです。

3. 公開鍵と秘密鍵が対になっていない

鍵を作り直したのに DNS だけ古いまま、またはその逆の状態です。opendkim-testkey で一致を確認し、作り直した場合は新しいセレクタ名で公開してから送信側を切り替えると、反映待ちの間に失敗が出にくくなります。

4. DNSの値が壊れている・反映前

手順1の確認に戻ります。TTL が長いまま値を変えた場合は、古い鍵がキャッシュに残っている間は検証に失敗することがあります。

運用で気をつけたいこと

鍵の長さは 2048 ビットの RSA が現在の一般的な選択です。1024 ビットは受信側によって弱いと扱われる可能性があります。Ed25519 による DKIM 署名も仕様化されていますが、受信側の対応状況にはばらつきがあるため、使う場合は RSA 署名と併用する構成が無難です。

また、Gmail や Yahoo などの大手メールサービスは、送信者に SPF・DKIM の設定を求め、大量送信者には DMARC の設定も求める方針を公表しています(2026年10月現在)。要件や対象の基準は改定されることがあるため、各社の送信者向けガイドラインを確認してください。DKIM を検証して pass を確認したら、次は DMARC のレポートで、自社ドメインを名乗る送信が全体として pass しているかを継続的に見ていくと、設定漏れの送信経路にも気付けます。

まとめ

  • DKIM の検証は「DNS の公開鍵」「送信メールの署名」「受信側の判定」の順に確認すると切り分けやすい
  • 公開鍵は dig TXT セレクタ._domainkey.ドメイン で確認し、権威 DNS と公開 DNS の両方の結果を比べる
  • DKIM-Signature の d= と s= が想定どおりか、d= が From のドメインと揃っているかを見る
  • 受信側の Authentication-Results で dkim=pass を確認し、fail のときは理由の文言から原因を絞る
  • body hash did not verify は経路での書き換えが多く、鍵の作り直しでは直らない

お気軽にご相談ください

お見積りへ お問い合わせへ
▲