DNSSEC の DS レコードと DNSKEY レコードの整合を、RFC 4034 / RFC 4509 の計算式どおりに自分で計算して確かめるスクリプトです。 Python 標準ライブラリだけで動き、外部パッケージのインストールは不要です。
git clone https://github.com/ac5net/dscheck.git
cd dscheck
python3 dscheck.py <ゾーン名> [--json]
例
python3 dscheck.py cloudflare.com
python3 dscheck.py jprs.jp --json
DNS は DoH(dns.google)で引きます。--fixtures <json> を渡すとネットワークに出ず、JSON に書いた応答で動きます(テストと再現用)。
- DNSKEY RRset(type 48)と DS RRset(type 43)を取得する
- 各 DNSKEY の Key Tag を RFC 4034 Appendix B で計算する(アルゴリズム 1 だけ B.1 の別計算)
- 各 DS について、同じアルゴリズム・同じ Key Tag の DNSKEY を探し、
digest = H( 所有者名の正規ワイヤ形式 | DNSKEY RDATA )を計算して突き合わせる(RFC 4034 5.1.4、RFC 4509 2.1) - DS が指す DNSKEY に Zone Key ビットが無ければ、一致していても使わない(RFC 4034 5.2)
- SHA-256 の DS があれば SHA-1 の DS は「無視対象」と表示する(RFC 4509 3)
- 計算できないダイジェスト種別しか無ければ bogus ではなく insecure と判定する(RFC 4509 4)
- アルゴリズムと DS ダイジェスト種別を IANA レジストリの推奨列と照らす (RFC 9904 以降は IANA レジストリが正本。RFC 9905 で RSASHA1 / RSASHA1-NSEC3-SHA1 と SHA-1 ダイジェストは MUST NOT)
- RSA 鍵は RFC 3110 の形式を読んで鍵長(bit)を出す
- 主要30ドメインで DNSSEC 署名あり(DS と DNSKEY の両方が存在): 5 / 30 cloudflare.com, salesforce.com, slack.com, mufg.jp, smbc.co.jp — 5件とも ECDSAP256SHA256(13)、DS は SHA-256
- 参照6ドメイン: ietf.org, iana.org, jprs.jp, nic.ad.jp, soumu.go.jp は署名あり。digital.go.jp は署名なし
- 全10件で DS と DNSKEY が一致(secure)。RSA を使うのは jprs.jp と nic.ad.jp(RSASHA256)
fixtures/live-2026-10-03.json はその日に dns.google から取得した応答です。
fixtures/rfc-examples.json は RFC 4034 5.4 と RFC 4509 2.3 の例(同じ DNSKEY に対する SHA-1 DS と SHA-256 DS)です。
python3 test_dscheck.py
ネットワークに出ないのでオフラインで実行できます。RFC の例の Key Tag(60485)と DS ダイジェスト(SHA-1 / SHA-256)が一致すること、 実データ 36 件の判定、そして実装中に踏んだ落とし穴(指摘の重複、括弧付き提示形式、所有者名のワイヤ形式、 Zone Key ビット無しの鍵、未対応ダイジェスト種別の扱い)を 92 件のアサーションで確認します。
RFC の要件の読み合わせ、36 ドメインの結果、落とし穴の経緯はブログに書いています。
https://ac-5.net/security/dnssec-ds-dnskey-check/
MIT