ICTSC2025 本戦 問題解説: [9830] 備えあれば憂いあり

問題文

概要

あなたはISPのネットワークエンジニアとして勤務している。

自社で提供しているDNSフルサービスリゾルバは元々1台で運用していたが、可用性向上のためリゾルバをもう1台追加しロードバランサで冗長構成にした。

構成変更後、リゾルバを参照しているフォワーダー運用者から「名前解決ができない」と連絡を受けた。
調査の結果、BINDをフォワーダーとして使用している一部のユーザのみ影響を受けていることがわかった。

影響を受けているユーザの環境を再現し、原因の調査を行うことになった。これはその環境を簡略化して再現したものである。

ネットワーク構成図

原因を調査し、名前解決が正常に行えるようにしてほしい。

前提条件

  • 各ノードへはSSHでログイン可能である
  • resolver1,resolver2にはフルサービスリゾルバとしてBINDがインストールされている
  • loadBalancerはdnsdistを使用し、resolver1,resolver2にラウンドロビンで振り分けている
  • forwarderはBINDをフォワーダーとして使用し、loadBalancerを上流として参照している
  • firewallはclient/forwarderセグメントとLB/resolverセグメントの間のファイアウォールである

制約

  • resolver1resolver2はActive/Active構成であり、ラウンドロビンによる振り分けから変更しないこと
  • forwarderの設定を変更してはならない

初期状態

  • clientからdig @192.168.128.253で名前解決を行うと、安定した名前解決ができない

終了状態

  • 採点時に、すべてのサーバのキャッシュを削除した後、clientから以下のコマンドを連続で実行し、すべてANSWERセクションにレコードが含まれる応答が返ること
    • dig example.com @192.168.128.253
    • dig example.org @192.168.128.253
    • dig example.net @192.168.128.253
  • ISP側・ユーザ側それぞれにおいて名前解決が失敗していた原因と、その対処についての説明を回答に含め、実際に対処を行うこと

接続情報

ホスト名 IPアドレス ユーザ パスワード
resolver1 192.168.30.1 user ictsc2025
resolver2 192.168.30.2 user ictsc2025
loadBalancer 192.168.30.3 user ictsc2025
firewall 192.168.30.4 user ictsc2025
client 192.168.30.5 user ictsc2025
forwarder 192.168.30.6 user ictsc2025

解説

原因

BINDはcookie-secretが未設定の場合、起動時にランダムなServer Secretを自動生成します。
各リゾルバが別々のServer Secretを持っていることが根本原因です。

BIND 9.20の安定版リリースでは、期限切れまたは不正だが形式上は正しいServer Cookieに対して、デフォルトでBADCOOKIEを返すようになりました
GL #4194)。
RFC 9018でも、anycast構成のサーバ群が一貫したServer Cookieを生成できるようServer Secretの共有を求めています。

resolver1resolver2のServer Secretが異なるため、forwarderからのクエリがラウンドロビンで別のリゾルバに振り分けられるとBADCOOKIEが返されます。forwarderはServer Cookieを更新して再試行しますが、再び別のリゾルバに当たると2度目のBADCOOKIEが返され、TCPへフォールバックします。
さらに、firewallではUDP 53しか許可しておらず、TCPフォールバックが失敗し、最終的に名前解決がタイムアウトしてSERVFAILが返されていました。

なお、DNS Cookieをクライアントとして送信するのは事実上BINDのみであるため、BINDをフォワーダーとして使用しているユーザのみが影響を受けます
(dnsmasq, PowerDNS Recursor, Unbound等はデフォルト設定では上流にDNS Cookieを送信しません)。
これが「BINDをフォワーダーとして使用している一部のユーザのみ影響を受けた」理由です。

調査手順

想定している調査手順は以下の通りです。

  1. clientからdig @192.168.128.253でSERVFAILを確認
  2. forwarderのnamedログで上流へのタイムアウトを確認
  3. forwarderloadBalancer上でtcpdumpを実行し、BADCOOKIEの連鎖とTCP SYNの応答なしを観測
  4. resolver1/resolver2cookie-secret未設定を確認
  5. firewallのルールでTCP 53が未許可であることを確認

BIND 9.20のデフォルトのログ設定ではBADCOOKIEは記録されません。
そのため、原因の特定にはtcpdump等のパケットキャプチャが最も確実でした。

解決方法

以下のいずれかの方法でBADCOOKIEを解消することで正解となります。

方法A: Server Secretの統一

共通の鍵を生成し、resolver1/resolver2/etc/bind/named.conf.optionsに設定します。

openssl rand -hex 16
# 出力例: cd92d478f1700d634f024813c28189f4
options {
    ...
    cookie-secret "cd92d478f1700d634f024813c28189f4";
};

設定後: sudo rndc reconfig

方法B: 応答でDNS Cookieを返さない

resolver1/resolver2optionsブロックに以下を追加します。

options {
    ...
    answer-cookie no;
};

設定後: sudo rndc reconfig

補足: FWでTCP 53を許可

firewallでTCP 53を許可するルールを追加します。
RFC 9210はDNS over TCPを遮断せず、UDPと同等にサポートすることを求めるBCPであり、
TCP 53を閉じていたことはこのBCPに反する運用でもありました。

configure
set firewall ipv4 forward filter rule 25 action accept
set firewall ipv4 forward filter rule 25 destination port 53
set firewall ipv4 forward filter rule 25 protocol tcp
commit
save
exit

採点基準

  • ISP側の原因分析: resolver1resolver2のServer Secretが異なるため、BADCOOKIEが返されることを説明している(40点)
  • ユーザ側の原因分析: FWでTCP 53が許可されていないため、TCPフォールバックが失敗することを説明している(20点)
  • ISP側の対処: cookie-secretの統一、またはanswer-cookie noによりBADCOOKIEを解消している(40点)

ユーザ側の対処(FWでTCP 53を許可)は採点対象外ですが、対処した場合は名前解決が正常に機能します。

講評

この問題は15チーム中9チームが満点を獲得し、全体的によく解かれていました。
解法としてはcookie-secretの統一を選んだチームが多数派で、answer-cookie noを選んだチームも数チームありました。いずれも正しい対処です。

一方、ISP側の原因であるBADCOOKIEの問題に気づけず、ユーザ側のファイアウォールのTCP 53の許可のみで対処したチームもありました。
TCP 53を許可することで実用上は名前解決が回復しますが、毎回BADCOOKIE→TCPフォールバックという非効率な経路を辿ることになります。
問題文の終了条件にも「ISP側・ユーザ側それぞれにおいて名前解決が失敗していた原因と、その対処についての説明を回答に含め」とある通り、根本原因であるCookieの不一致を特定し解消することが求められていました。

BIND 9.20のデフォルトのログ設定ではBADCOOKIEが記録されないため、tcpdump等のパケットキャプチャが原因特定の鍵でした。
パケットを観察できたチームとそうでないチームで差がついた問題だったと思います。

最後に、サーバ側DNS Cookieの運用について触れておきます。
現状では、主要なパブリックDNSリゾルバの多くは、クライアントからの問い合わせに対してServer Cookieを返していません。
サーバ側Cookieは同一VIPの全ノードでcookie-secretを共有・ローテーションする必要があり運用負荷が大きい一方、BINDをフォワーダーとして運用している一部の加入者を除きほとんどの加入者はDNS Cookieを送信しません。
ISCはanswer-cookie noを暫定的な措置と位置づけていますが、運用方針によってはサーバ側Cookieを無効化するのも一つの選択肢です。