概要
2026年1月8日、1.1.1.1のメモリ使用量削減を目的としたアップデートがDNS解決障害を引き起こした事例 CNAMEレコードの順序変更が一部DNSクライアントの不具合の原因 40年以上前のDNSプロトコル仕様の曖昧さが根本要因 障害の詳細なタイムラインと影響範囲の解説 CNAMEチェーンやRFCの曖昧な記述についても考察
2026年1月8日発生 DNS解決障害の概要
- 2026年1月8日、 1.1.1.1 の定期アップデートにより DNS解決障害 が発生
- 原因は DNS応答内のレコード順序 変更によるもの
- 多くのソフトウェアは順序を無視するが、一部実装では CNAMEレコードが先頭 であることを期待
- この順序変更により、特定のDNSクライアントで 名前解決が失敗
- 攻撃や大規模障害ではなく、 仕様解釈の違い によるもの
障害発生までのタイムライン
- 2025-12-02: レコード順序変更のコードが 1.1.1.1コードベース に導入
- 2025-12-10: テスト環境 でリリース
- 2026-01-07 23:48: グローバルリリース 開始
- 2026-01-08 17:40: 90%のサーバー に展開完了
- 2026-01-08 18:19: インシデント宣言
- 2026-01-08 18:27: リリース リバート 開始
- 2026-01-08 19:55: 復旧完了
CNAMEチェーンとDNS動作の基礎
- ドメイン問い合わせ時、 CNAME(Canonical Name) レコードで別名解決が行われる
- 例: www.example.com → cdn.example.com → server.cdn-provider.com → 198.51.100.1
- 1.1.1.1 はこのチェーンを辿り、 各レコードをキャッシュ
- 各レコードは 独自のTTL (有効期限)を持つ
- チェーンの一部が失効しても、 有効部分のみ再解決 し、全体を再構築
問題の発生した実装変更
- 以前は「 CNAMEチェーン→新しいレコード」の順で応答を構築
- メモリ最適化のため「 既存回答にCNAMEを追加(CNAMEが後ろ)」方式に変更
- これにより、 CNAMEレコードが末尾 に現れる場合が発生
影響を受けたDNSクライアント
- 一部クライアントは CNAMEが先頭 であることを前提
- glibcの getaddrinfo 関数などが該当
- レコードを順に処理し、 CNAME発見時に参照名を更新
- CNAMEが後ろにある場合、 期待通りに動作せず解決失敗
- Ciscoスイッチ の一部モデルでは、CNAME順序変更で 再起動ループ が発生
影響を受けない実装例
- systemd-resolved などは、全レコードを 順不同のセット として扱う
- CNAMEがどこにあっても 正しくチェーンを辿れる
RFC(仕様書)における解釈の曖昧さ
- RFC 1034 (1987年発行)がDNSプロトコルの基礎を定義
- 「 CNAMEレコードが先頭に来る可能性がある」と記載
- ただし MUST/SHOULD などの強制表現は未使用
- RRset(同名・同タイプのレコード集合) 内の順序は 重要でない と明記
- ただし、 異なるRRset間の順序 は明確に規定されていない
- 例示ではAレコード同士の順序のみ扱い、 CNAMEやAの混在順序は未記述
CNAMEチェーン順序のさらなる問題
- CNAMEチェーン自体の順序 もRFCで明確な規定なし
- チェーン順がバラバラだと、 逐次処理型クライアントで不具合
- 例: www.example.com→cdn.example.com→server.cdn-provider.com の順序が崩れると解決失敗
レゾルバ(DNSクライアント)が取るべき対応
- RFC 1034は「 CNAME発見時に新しい名前で再クエリ」を推奨
- ただし、 フルレゾルバ 向けの記述が中心
- スタブレゾルバ (glibcなど簡易クライアント)は仕様通り動かない場合も
DNSSEC仕様との比較
- RFC 4035 (DNSSEC)は「 RRSIGは他RRsetより優先して含めるべき」と明確に規定
- MUST などの強制表現を使用し、 曖昧さを排除
- DNSSECのような明示的な優先順位指定が 従来DNSには存在しない
まとめ
- DNS応答のレコード順序 は、古いRFCの曖昧な記述と実装依存によりトラブルの温床
- 今回の障害は 仕様解釈の違い と テスト不足 が要因
- 安定運用には 実装間の互換性 と 明確な仕様遵守 が重要