手当たり次第に書くんだ

飽きっぽいのは本能

DNSSEC で名前解決できない原因が NTP だった話

自宅サーバーの再起動後、インターネット側の名前解決ができなくなったことがありました。最初は DNS やネットワークの問題に見えましたが、原因は DNSSEC と NTP が絡んだ時刻ずれでした。

この記事は、そのときの短いメモを、現在の運用でも使えるように再整理したものです。DNSSEC を有効にしたリゾルバでは、システム時刻がずれると署名検証に失敗します。さらに NTP サーバーをホスト名で指定していると、名前解決できないため時刻同期もできない、という循環に入ることがあります。

発生した症状

再起動後、BIND のログに次のようなメッセージが大量に出ていました。

Feb  4 13:05:36 centos named[xxxxx]: validating @xxxxxxxx: example.com NSEC3: verify failed due to bad signature (keyid=xxxxx): RRSIG validity period has not begun

RRSIG validity period has not begun は、DNSSEC の署名がまだ有効開始時刻に達していない、と判断されたことを示します。実際には署名側がおかしいとは限らず、検証しているサーバーのシステム時刻が過去にずれている場合にも発生します。

このときは、起動しているはずの ntpd が停止しており、サーバーの時刻が約 2 時間遅れていました。時刻を同期したあと、名前解決は正常に戻りました。

なぜ DNSSEC は時刻ずれに弱いのか

DNSSEC では、DNS レコードに対して RRSIG という署名情報が付与されます。この RRSIG には有効開始時刻と有効期限があります。検証するリゾルバの現在時刻がその期間外にある場合、署名は正しいものとして扱えません。

つまり、DNSSEC は暗号署名だけでなく、時刻にも依存しています。これは TLS 証明書の有効期間と似ています。サーバーの時刻が大きくずれると、実際には正しい署名であっても「まだ有効ではない」「すでに期限切れ」と判断される可能性があります。

確認項目見るところ
RRSIG validity period has not begun検証側の時刻が過去にずれている可能性がある。
RRSIG has expired検証側の時刻が未来にずれている、または署名が本当に期限切れの可能性がある。
SERVFAILDNSSEC 検証失敗時にクライアントから見える結果として出ることがある。

NTP と名前解決の循環

この問題で厄介なのは、DNSSEC と NTP が依存関係として循環することです。

順序状態
1サーバー再起動後、システム時刻がずれている。
2DNSSEC 検証で RRSIG の有効期間外と判断される。
3名前解決が SERVFAIL になる。
4NTP サーバーをホスト名で指定しているため、NTP サーバー名を解決できない。
5時刻同期できず、DNSSEC 検証失敗が続く。

つまり、時刻を直すために NTP が必要なのに、NTP サーバーへ到達するための名前解決が DNSSEC によって失敗する、という状態になります。

まず確認すること

DNSSEC を有効にした BIND や Unbound で名前解決できない場合は、DNS 設定だけでなく、時刻同期の状態を先に確認します。

date -u
timedatectl status

systemctl status chrony --no-pager
systemctl status ntp --no-pager
systemctl status systemd-timesyncd --no-pager

時刻同期サービスは環境によって異なります。現在の Ubuntu では chrony が使われる構成が増えていますが、古い環境やアプライアンスでは ntpd、軽量な環境では systemd-timesyncd の場合もあります。

NTP 側の確認については、次の記事でも整理しています。

NTP トラブル時に確認すること – chrony、ntpd、timesyncd の整理

一時復旧の考え方

名前解決が DNSSEC で失敗していて NTP サーバー名を解決できない場合は、まず時刻をある程度正しい範囲に戻す必要があります。

確認項目見るところ
手動で時刻を合わせる一時的に datetimedatectl set-time で大きなずれを戻す。
NTP サーバーを IP アドレスで指定するDNS に依存せず、NTP へ到達できるようにする。
内部 NTP を用意するLAN 内の固定 IP の時刻源を参照し、外部 DNS 依存を減らす。
DNSSEC 検証を一時的に切る原因切り分けとしては有効。ただし恒久対策にはしない。

恒久対策としては、NTP サーバーをホスト名だけで指定する構成に依存しすぎないことが重要です。特に DNSSEC 検証リゾルバ自身は、起動直後に名前解決へ依存せず時刻を戻せる構成にしておくと安全です。

予防策

この手の問題を避けるには、DNSSEC と NTP を別々の設定として見るのではなく、起動時の依存関係として考える必要があります。

確認項目見るところ
RTC を確認するハードウェアクロックが大きくずれていると、再起動直後に DNSSEC 検証が失敗しやすい。
内部 NTP を固定 IP で参照するDNSSEC 検証リゾルバ自身は、名前解決なしで時刻同期できる経路を持たせる。
起動順序を確認するDNS サービスが起動する前に時刻同期がある程度完了しているか確認する。
ログを確認するRRSIG validity period has not begunRRSIG has expired は時刻ずれを疑う。
仮想環境ではホスト側も見るゲスト OS の時刻だけでなく、仮想化ホストや時刻同期エージェントの影響も確認する。

参考

RFC 4034 – Resource Records for the DNS Security Extensions

BIND 9 DNSSEC Guide

まとめ

DNSSEC で名前解決できない場合、DNS の設定ミスだけを疑うと遠回りになることがあります。RRSIG には有効期間があるため、検証リゾルバの時刻がずれていると、正しい署名でも検証に失敗します。

特に NTP サーバーを名前で指定している環境では、時刻ずれによって DNSSEC 検証に失敗し、名前解決できないため NTP にも到達できない、という循環が起きます。DNSSEC を使うリゾルバでは、時刻同期を DNS より前提に近い基盤として扱う必要があります。

DNSSEC で名前解決できない原因が NTP だった話

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る