セキュリティ
DMARCの新タグ「NP」がDNSSECで失敗する理由
Why DMARC's new "NP" tag can fail with DNSSEC (dmarcwise.io)
要約
DMARCの新しいNPタグは、存在しないサブドメインに対するポリシーを指定しますが、DNSSECの「Compact Denial of Existence」の定義と競合し、期待通りに機能しない可能性があります。この問題は、Cloudflareなどの主要DNSプロバイダーを利用し、DNSSECを使用しているドメインに影響を与えます。IETFはこの問題を認識していますが、まだ合意された解決策はありません。
全文翻訳
ブログ最終更新日 2026年7月5日
DMARCの新しい「np」タグがDNSSECで失敗する理由
Matteo 18分読書
RFC 9989として公開された最近更新されたDMARC仕様には、新しいnpタグが導入されました。その目的は、送信者ドメインがDMARCレコードが公開されているドメインの存在しないサブドメインである場合に、受信者が適用すべきポリシーを指定することです。RFC 9989に含まれる「存在しないドメイン」の定義が、RFC 9824(「DNSSECにおけるコンパクトな存在否定」として知られる)という別の最近の仕様と衝突し、npタグが常に期待通りに機能しないことを発見しました。DNSSECの使用はまだ広く普及していませんが、この問題はCloudflare、NS1、AWS Route 53、Azureといった主要なDNSプロバイダーとDNSSECを使用しているすべてのドメインに影響します。私たちはこの問題をDMARCを担当するIETFワーキンググループに提起しました。問題は認識されましたが、合意された解決策はありません。この記事では、この経緯全体を説明し、この非互換性の影響を評価しようとします。
新しいnpタグ
2026年5月、IETFは3つのドキュメントからなるDMARC仕様の更新版を公開しました。RFC 9989は、非存在サブドメインポリシーを意味するnpという新しいDMARCレコードタグを導入しています。DMARCレコードでは、次のように表示されます。
v=DMARC1; p=none; sp=quarantine; np=reject;
pタグで指定されたポリシーはレコードが公開されているドメインに適用され、spタグはポリシー ドメインの既存のサブドメインで、独自のDMARCレコードを公開していないものに適用されます。一方、npタグは存在しないサブドメインに適用されます。未使用のサブドメインで悪意のあるメールを「ブロック」したいが、他のサブドメインではより緩いポリシーを維持したい場合に、異なるポリシーを設定することは役立ちます。
DNSにおける存在しないドメイン
DMARC RFCは、存在しないドメインを次のように定義しています。
DMARCの目的上、存在しないドメインは、RFC8020で説明されている用語の意味と一致します。つまり、ドメイン名のクエリに対して受信した応答コードがNXDOMAINである場合、そのドメイン名およびすべてのサブドメインは存在しません。これは一般的な定義であり、驚くべきことではありません。DNSサーバーは通常、クエリされたドメイン名とそのすべてのサブドメインが存在しないことを示すためにNXDOMAIN応答コードを返します。これは、それらに関連付けられたDNSレコードがないことを意味します。例を挙げます。
~ ❯ dig non-existent-subdomain.rai.it +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 17031
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
上記の例では、non-existent-subdomain.rai.itという名前とそのすべてのサブドメインが存在しないことを判断できます。一方、次の例では、news.rai.itドメインにはMXレコードがありませんが、他のレコードタイプがあるため存在することがわかります。
~ ❯ dig news.rai.it MX +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37891
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
DNSSECの世界では、物事は少し複雑になります。
DNSSECの概要
DNSSECはDNSのセキュリティ拡張機能であり、リゾルバーがDNS応答が認証されており、改ざんされていないことを検証できるようにします。これは、リゾルバーが検証できる暗号署名を追加することによって行われます。次の例では、DNSSEC関連データを返すようにDNSリゾルバーに明示的に要求しています。ANSWERセクションに追加のレコード、タイプRRSIGが含まれていることがわかります。
~ ❯ dig dmarcwise.io +dnssec +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49227
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; ANSWER SECTION:
dmarcwise.io. 892 IN A 94.237.30.173
dmarcwise.io. 892 IN A 94.237.26.215
dmarcwise.io. 892 IN RRSIG A 13 2 900 20260801080000 20260704073000 20768
dmarcwise.io. bPF4BFfnETKC4GGwrmi0xlOzvBaotX8DG5E8/rpmelxoXJ2eA8RJtUrN JVFjFVCq5ZP/Ul9XYgT86c8Vw5Y4Sw==
RRSIGレコードには、リゾルバーが検証する署 が含まれています。検証プロセスでは、ゾーン内の他のレコード(DNSKEY)、および親ゾーン(DS)をクエリし、DNS階層をルートゾーンに到達するまで上に移動します。
DNSSECにおける存在否定
標準DNSでは、存在しないドメインに対するクエリは、前述のように空のANSWERセクションを持つ応答を生成します。これはDNSSECとはうまく機能しません。空のANSWERセクションにはレコードが含まれていないため、署名するものがありません。DNSSECは、NSECレコードタイプを使用してこれを解決します。存在しない名前を署名する代わりに、要求された名前の前に来る既存の名前を識別し、正規のDNS順序で次の既存の名前を報告することで、要求された名前がそれらの間に存在しないことを証明します。NSECレコードは署名されるため、改ざんは検出できます。DNS応答コードはNXDOMAINのままです。たとえば、ゾーンには次のドメイン名が含まれている場合があります。
a.example.com
z.example.com
存在しないドメインf.example.comをクエリすると、応答は次のように表示されます。
a.example.com 300 IN NSEC z.example.com. A RRSIG NSEC
これは、a.example.comが存在し、正規のDNS順序でそれに続くドメインがz.example.comであり、レコードタイプがA、RRSIG、NSECであることを知らせることで、f.example.comが存在しないことを確認します。それ以外は間に存在しません。実際には、これよりも少し複雑です。なぜなら、f.example.comをカバーするワイルドカードレコードが存在しないことを証明するために、2番目のNSECレコードも必要になるからです。例外は、ドメイン名が存在するが、そのレコードタイプではないことを示したい場合です。この場合、前述のように1つのNSECレコードのみを使用し、存在するレコードタイプをリストできます。現在、多くのDNSサーバーはNSECのバリアントであるNSEC3を使用しており、ゾーン内のすべてのドメイン名を列挙する攻撃者がDNSゾーンを「ウォーク」するのをより困難にするために、元の名前の代わりにハッシュ化された名前を使用しています。これが機能するためには、3番目のNSEC3レコードが必要になり、「最も近い囲み」が存在することを証明します。最悪の場合、ドメインが存在しないことを証明するためだけに、合計8つのレコード(SOA + SOA RRSIG + 3x NSEC3 + 3x NSEC3 RRSIG)になります。場合によっては、これはDNS UDPパケットのサイズ制限に近づき、応答が切り捨てられたり、TCPに切り替わったりする可能性があります。
~ ❯ dig non-existent.rcodezero.at +dnssec +noall +comments +authority
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 28077
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; AUTHORITY SECTION:
rcodezero.at. 30 IN SOA ns1.rcodezero.at. rcodezero.ipcom.at. 2025113549 10800 3600 604800 30
rcodezero.at. 30 IN RRSIG SOA 13 2 3600 20260716000000 20260625000000 61192
rcodezero.at. m2lRXWLkudZ/DMpS0VPiaNwkN2Wak44JjLNM2VsfY4pwOuVeEOE+Yip5 g4QaVC4vOhuTDikl6RG2XbTJhJIIjQ==
5fck5kit9i35fg68phiu98n07jqtcbe5.rcodezero.at. 30 IN NSEC3 1 0 0 - 5O2N7HE1TQ836ADQ0G40SEJUHNT866RF A NS SOA TXT AAAA RRSIG DNSKEY NSEC3PARAM
5fck5kit9i35fg68phiu98n07jqtcbe5.rcodezero.at. 30 IN RRSIG NSEC3 13 3 30 20260716000000 20260625000000 61192
rcodezero.at. Ix74l+UIyGSWfhymQJgrHRceKtzla5yCyF56yZfawS4JLak+ECXniLoM MMEZKF+2Q4jQ+UeLV6+oT54wov1YJw==
dqj11be2u7pvv034803fs4s4v1i77o5c