エラーメッセージ
dkim=fail reason="signature verification failed"
別の表記
- dkim=fail (bad signature)
OpenDKIM は、ヘッダーの変更でも本文の変更でも `dkim=fail reason="signature verification failed"` と記録します(OpenDKIM 2.11.0 で再現)。mailauth は両者を区別し、ヘッダーの場合は「bad signature」、本文の場合は「body hash did not verify」とします。
このエラーの意味
受信サーバーは DKIM の鍵を見つけ、届いたままのメッセージに対して署名を計算しましたが、一致しませんでした。送信者が署名した後に署名対象のヘッダー(OpenDKIM の場合は本文も)が変更されたか、公開されている鍵が署名鍵と対になっていません。DKIM は正規化後の正確なバイト列に署名するため、件名へのタグ追加、フッター、MIME パートの再エンコードなど、中継サーバーによる書き換えがあれば署名は壊れます。DMARC では、これは DKIM チェックの失敗として扱われます。
発生する理由
中継サーバーが署名対象のヘッダーを変更した
よくある件名にタグ(`[team]`)を付けるメーリングリスト、`From` や `To` を書き換えるゲートウェイ、`Content-Type` を変更するセキュリティアプライアンスが該当します。`h=` に列挙されたヘッダーは、すべて署名の対象です。
フッター、免責事項、再エンコード
よくある免責事項の追加、リンクの書き換え、ウイルス対策のバナー、8 ビットのコンテンツから quoted-printable への変換は、本文を変えてしまいます。`l=` がない場合は、すべてのバイトが対象になります。
DNS の鍵が署名鍵と一致しない
ときどき鍵のローテーション後もセレクターの TXT レコードに古い公開鍵が残っているか、2 台のサーバーが同じセレクターを使いながら異なる秘密鍵で署名しています。
署名者が署名後にメッセージを変更した
ときどきコンテンツフィルターがヘッダーを追加したりメッセージを書き換えたりする前に署名している(Postfix の milter の順序)、または署名してから改行コードを変更する送信者側のライブラリが原因です。
修正方法
- 1.
署名されたヘッダーと受信したヘッダーを比較する
`h=` タグには、署名された内容が列挙されています。受信したコピーのそれらのヘッダーを、送信者側で取得したコピー(送信済みフォルダー)と比較してください。
bash # Which headers did the signature cover, and what do they look like now? grep -i "^DKIM-Signature" -A4 received.eml | grep -o "h=[^;]*" grep -iE "^(From|To|Subject|Date|Message-ID|Content-Type):" received.eml - 2.
メーリングリストと転送サービス:ARC と再署名
メッセージを変更せざるを得ない中継者は、ARC ヘッダーを追加し、自身のドメインで署名すべきです。そうすれば、受信側は元の認証結果を引き続き評価できます。
text # Mailing list / forwarder: add ARC and re-sign with the list's own domain (Mailman 3 example) [ARC] enabled: yes authserv_id: lists.example.org domain: lists.example.org selector: arc2026 privkey: /etc/mailman3/arc.private - 3.
DNS の鍵と秘密鍵の対応を検証する
`opendkim-testkey` を使うと、セレクターについて公開されているレコードが、署名者の使う鍵と一致しているかを確認できます。
bash opendkim-testkey -d example.com -s sel -k /etc/opendkim/keys/sel.private -vvv # DNS record matches the private key?