ネガティブキャッシュ(Negative Caching)
概要
ネガティブキャッシュ(Negative Caching) は、DNS リゾルバーが「レコードが存在しない」という応答結果をキャッシュする仕組みです。RFC 2308(1998年)で詳細な仕様が定義されています。存在しないドメインやレコードタイプへの問い合わせに対して、権威サーバーが返す否定応答(NXDOMAIN や NODATA)を一定期間保持し、同じ問い合わせが繰り返された場合にキャッシュから応答します。
通常の DNS キャッシュ(ポジティブキャッシュ)はレコードの「存在する」結果をキャッシュしますが、ネガティブキャッシュは「存在しない」という事実をキャッシュします。この仕組みがなければ、存在しないドメインへの問い合わせが繰り返されるたびに権威サーバーへの問い合わせが発生し、サーバーの負荷が増大します。タイプミスのドメイン名、スパムボットによるランダムなサブドメインへの問い合わせなど、存在しないレコードへのクエリは全体の相当な割合を占めます。
ネガティブキャッシュの保持期間は、SOA レコードの MINIMUM フィールドの値と SOA レコード自体の TTL の小さい方で決まります。
仕組み
ネガティブキャッシュは NXDOMAIN と NODATA の 2 種類の否定応答を対象とし、保持期間は SOA レコードのフィールド値から決定されます。
否定応答の種類
DNS の否定応答には 2 種類あります。
NXDOMAIN(Non-Existent Domain) は、ドメイン自体が存在しないことを意味するレスポンスコード(RCODE = 3)です。nonexistent.example.com のような登録されていないドメインを問い合わせたとき返されます。
NODATA は、ドメインは存在するがリクエストされたレコードタイプが存在しないことを意味します。NODATA は独立したレスポンスコードではなく、RCODE = 0(NOERROR)かつ回答セクションが空の応答として表現されます。例えば example.com に AAAA レコードが設定されていないとき、AAAA クエリに対して NODATA が返ります。
SOA MINIMUM フィールドとの関係
ネガティブキャッシュの TTL は、否定応答に含まれる SOA レコードの情報から決定します。RFC 2308 は、SOA レコードの MINIMUM フィールドと SOA レコード自体の TTL を比較して、小さい方をネガティブキャッシュの TTL として使用すると定めています。
example.com. 3600 IN SOA ns1.example.com. admin.example.com. (
2024010101 ; SERIAL
3600 ; REFRESH
900 ; RETRY
604800 ; EXPIRE
300 ) ; MINIMUM
; ^^^
; ネガティブキャッシュ TTL の候補
この例では SOA の TTL が 3600、MINIMUM が 300 です。小さい方の 300 秒(5 分)がネガティブキャッシュの保持期間になります。
SOA の MINIMUM フィールドは、RFC 1035 では「ゾーン内のすべてのレコードの最小 TTL」として定義されていましたが、RFC 2308 で「ネガティブキャッシュの TTL」に再定義されました。現在の実装では RFC 2308 の解釈が標準です。
ネガティブキャッシュの動作フロー
- クライアントが再帰リゾルバーに
nonexistent.example.comを問い合わせる - 再帰リゾルバーのキャッシュにデータがないため、権威サーバーに問い合わせる
- 権威サーバーが NXDOMAIN を返し、応答の権威セクションに SOA レコードを含める
- 再帰リゾルバーは SOA の MINIMUM と SOA TTL の小さい方を TTL として、この否定応答をキャッシュする
- TTL の期間中に同じ問い合わせが来た場合、権威サーバーに問い合わせずにキャッシュから NXDOMAIN を返す
設定例
SOA レコードの MINIMUM フィールドでネガティブキャッシュの TTL を制御します。
; ネガティブ TTL を 300 秒(5 分)に設定
example.com. 3600 IN SOA ns1.example.com. admin.example.com. (
2024010101 3600 900 604800 300 )
; ネガティブ TTL を 60 秒に設定(短い値)
example.com. 3600 IN SOA ns1.example.com. admin.example.com. (
2024010101 3600 900 604800 60 )
; ネガティブ TTL を 3600 秒に設定(長い値)
example.com. 3600 IN SOA ns1.example.com. admin.example.com. (
2024010101 3600 900 604800 3600 )
一般的な推奨値は 300〜600 秒 です。短すぎると権威サーバーへの無駄なクエリが増え、長すぎると新しいサブドメインの追加後に「見つからない」状態が長引きます。
確認方法
dig で存在しないドメインを問い合わせると、NXDOMAIN 応答と SOA レコードを確認できます。
# 存在しないサブドメインを問い合わせる
dig A nonexistent.example.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 12345
;; AUTHORITY SECTION:
example.com. 300 IN SOA ns1.example.com. admin.example.com. (
2024010101 3600 900 604800 300 )
status: NXDOMAIN が否定応答を、AUTHORITY SECTION の SOA レコードがネガティブキャッシュの TTL 情報を示しています。SOA レコードの最後のフィールド(300)が MINIMUM です。
SOA レコードのフィールドを直接確認するには次のコマンドを使います。
dig SOA example.com
外部の視点からも確認したい場合は、Labee Dev Toolbox の DNS API を使うと、外部の視点から見た結果を取得できます。SOA レコードを問い合わせると MINIMUM フィールドの値を確認できます。
curl "https://labee.dev/api/dns?domain=example.com&type=SOA"
{
"success": true,
"data": {
"domain": "example.com",
"records": {
"SOA": [
{
"mname": "ns1.example.com",
"rname": "admin.example.com",
"serial": 2024010101,
"refresh": 3600,
"retry": 900,
"expire": 604800,
"minimum": 300
}
]
}
},
"error": null,
"meta": { "responseTime": 45 }
}
minimum フィールドの値がネガティブキャッシュの TTL 候補です。
よくある問題
ネガティブキャッシュは新規レコード追加後の「反映されない」問題やメール配送遅延の原因になります。
新しいサブドメインを作ったのに見つからない
新しいサブドメインを追加する前にそのドメインを問い合わせてしまうと、NXDOMAIN がネガティブキャッシュに記録されます。SOA の MINIMUM が 3600 秒の場合、最大 1 時間は「存在しない」とキャッシュされ続けます。
対処法は 3 つあります。OS の DNS キャッシュをフラッシュする方法、dig @8.8.8.8 のように別のリゾルバーを使う方法、ネガティブキャッシュの TTL が切れるまで待つ方法です。頻繁にサブドメインを追加する環境では、SOA の MINIMUM を 300 秒 程度に設定しておくと影響を最小化できます。
MINIMUM が長すぎてメール配送に影響する
新しい MX レコードを追加する前に、送信元のメールサーバーがそのドメインの MX レコードを問い合わせて NODATA を受け取ると、ネガティブキャッシュにより MX レコードが「存在しない」と判断され続けます。メールサーバーはネガティブキャッシュが切れるまでメール配送をリトライしないか、NDR(Non-Delivery Report)を返す場合があります。
NXDOMAIN のリダイレクト(NXDOMAIN Rewriting)
一部の ISP やパブリック DNS は、NXDOMAIN 応答を独自のページにリダイレクトすることがあります。RFC 1034 および RFC 2308 が定める DNS 仕様に反する挙動ですが、ISP が広告ページや検索ページを表示するために行うケースが存在します。この場合、ネガティブキャッシュが正しく機能せず、存在しないドメインに対して偽の A レコードが返されます。DNSSEC 検証を有効にしたリゾルバーを使用すると、このような改ざんを検知できます。