自作のDMARCチェッカーにnews.gmail.comを入れたら、結果は「p=none」でした。gmail.comのレコードにはsp=quarantineがはっきり書いてあるのに、です。原因は、DMARCのsp、つまりサブドメインポリシーの継承を読み違えていたことでした。
何が問題だったのか
DMARCチェッカーを使う人が知りたいのは「このドメインを名乗るなりすましメールを、受信側にどう扱ってほしいと宣言しているか」です。noneなら受信側に処置を求めない。quarantineなら疑わしいメールとして扱う(迷惑メールフォルダに入れるなど)よう求める。表示がnoneなら、読み手は「このドメインは保護されていない」と判断してしまいます。
サブドメインに専用のDMARCレコードがなければ、答えは継承で決まります。組織ドメインのspがpと違う場合、継承を間違えたツールはそのサブドメインすべてで違う答えを出します。gmail.comはまさにそのケースでした。
考えられる原因を順に消す
p=noneと出たとき、考えられる原因は3つあります。
- リゾルバのキャッシュが古い
-
_dmarc.news.gmail.comに別のレコードがあり、それを読んでいる - google.comなど、別の組織ドメインのレコードを読んでいる
②と③はDNSを直接引けば確かめられます。2026年11月3日にdns.googleのJSON APIで確認した値がこちらです。
| 名前 | TXT / 結果 |
|---|---|
_dmarc.gmail.com |
v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com |
_dmarc.google.com |
v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com |
_dmarc.news.gmail.com |
Status 3(NXDOMAIN) |
news.gmail.com(A) |
Status 3(名前が存在しない) |
mail.gmail.com(A) |
Status 3(名前が存在しない) |
少なくとも、サブドメイン側にレコードはありません。news.gmail.comという名前自体がDNS上に存在しないからです。google.comはp=rejectなので、③ならrejectと出るはずです。p=noneという値を持つのは_dmarc.gmail.comだけなので、読む場所は合っていて、読んだあとの処理が間違っていたことになります。
原因: pだけを見ていた
原因は、継承の際に組織ドメインのpをそのまま返していたことです。考え方としてはこうなっていました。
// 誤った継承(簡略化した例)
function inheritedPolicy(orgRecord) {
return orgRecord.p;
}
gmail.comはp=noneなので、結果はnone。組織ドメイン自身に対するポリシーとしては正しい値ですが、サブドメインに効くのはspのほうです。
サブドメインポリシーはspとnpで決まる
DMARCの仕様は2026年5月にRFC 9989として改訂され、RFC 7489とRFC 9091を置き換えました。4.7節のタグ定義を要約すると、こうなります。
-
sp: 組織ドメインのサブドメインに対するポリシー。spがなく、npもない(または該当しない)場合はpを使う -
np: 「存在しない」サブドメインに対するポリシー(定義は3.2.13節)。npがなければsp、それもなければp
どの組織ドメインのレコードを見るかは、4.10節のDNS Tree Walkで決まります。継承の順番は、名前が存在するかどうかで分岐します。正しい順番をコードにすると、次のようになります。これも説明用に簡略化した例で、ツールに入っているのはsp→pの部分までです。
// RFC 9989 4.7節に沿った継承(npの分岐はツールには未実装)
function inheritedPolicy(orgRecord, nameExists) {
if (!nameExists && orgRecord.np) {
return { policy: orgRecord.np, from: 'np' };
}
if (orgRecord.sp) {
return { policy: orgRecord.sp, from: 'sp' };
}
return { policy: orgRecord.p, from: 'p' };
}
fromを一緒に返しているのは、画面に「どのタグから来た値か」を出すためです。これがあれば、今回のようなずれに利用者自身が気づけます。
news.gmail.comは厳密にはnpのケース
news.gmail.comはDNS上に存在しないので、RFC 9989の言葉では「存在しないサブドメイン」、つまりnpの対象です。
gmail.comのレコードにはnpがありません。そのため、次のsp=quarantineが使われます。存在するサブドメインなら最初からspです。どちらの道を通っても答えはquarantineで、noneではありません。
直したことと確かめ方
修正後は、同じく存在しないサブドメインのmail.gmail.comで確認しました。説明文はこう表示されます。
No DMARC record at _dmarc.mail.gmail.com, so receivers use the organizational domain's record at _dmarc.gmail.com: its sp= (subdomain policy), or p= when there is no sp= (RFC 7489).
適用ポリシーの欄は「inherited from gmail.com, sp=quarantine」です。
ただし、修正はまだ途中です。説明文は置き換え前のRFC 7489を参照したままで、npの分岐も入っていません。gmail.comのようにnpを置いていないドメインでは結果は同じですが、npを設定しているドメインでは、存在しない名前に対して違う答えを出す可能性があります。このDMARCチェッカーはMyIPScanで公開しています(MyIPScanは私が作ったサイトです)。
手元で同じ確認をしたい場合は、digで十分です。
dig +short TXT _dmarc.news.gmail.com # 何も返らない
dig news.gmail.com A # status: NXDOMAIN
dig +short TXT _dmarc.gmail.com
# "v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com"
1行目でサブドメインにレコードがないこと、2行目で名前自体があるかないかを確かめ、3行目で組織ドメインのタグを読みます。この3つで、どのタグが効くかは手で決められます。
まとめ: 継承するときはpを最後に見る
サブドメインのDMARCポリシーを継承するときは、存在する名前ならsp→p、存在しない名前ならnp→sp→pの順に見る。そして、どのタグから取った値かを必ず表示する。
pは組織ドメイン自身のためのタグです。サブドメインに対しては、npもspもないときの最後の候補です。