ICTSC2025 本戦 問題解説: [9830] 備えあれば憂いあり
問題文
概要
あなたはISPのネットワークエンジニアとして勤務している。
自社で提供しているDNSフルサービスリゾルバは元々1台で運用していたが、可用性向上のためリゾルバをもう1台追加しロードバランサで冗長構成にした。
構成変更後、リゾルバを参照しているフォワーダー運用者から「名前解決ができない」と連絡を受けた。
調査の結果、BINDをフォワーダーとして使用している一部のユーザのみ影響を受けていることがわかった。
影響を受けているユーザの環境を再現し、原因の調査を行うことになった。これはその環境を簡略化して再現したものである。
原因を調査し、名前解決が正常に行えるようにしてほしい。
前提条件
- 各ノードへはSSHでログイン可能である
resolver1,resolver2にはフルサービスリゾルバとしてBINDがインストールされているloadBalancerはdnsdistを使用し、resolver1,resolver2にラウンドロビンで振り分けているforwarderはBINDをフォワーダーとして使用し、loadBalancerを上流として参照しているfirewallはclient/forwarderセグメントとLB/resolverセグメントの間のファイアウォールである
制約
resolver1とresolver2はActive/Active構成であり、ラウンドロビンによる振り分けから変更しないことforwarderの設定を変更してはならない
初期状態
clientからdig @192.168.128.253で名前解決を行うと、安定した名前解決ができない
終了状態
- 採点時に、すべてのサーバのキャッシュを削除した後、
clientから以下のコマンドを連続で実行し、すべてANSWERセクションにレコードが含まれる応答が返ることdig example.com @192.168.128.253dig example.org @192.168.128.253dig 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の共有を求めています。
resolver1とresolver2の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をフォワーダーとして使用している一部のユーザのみ影響を受けた」理由です。
調査手順
想定している調査手順は以下の通りです。
clientからdig @192.168.128.253でSERVFAILを確認forwarderのnamedログで上流へのタイムアウトを確認forwarderやloadBalancer上でtcpdumpを実行し、BADCOOKIEの連鎖とTCP SYNの応答なしを観測resolver1/resolver2のcookie-secret未設定を確認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/resolver2のoptionsブロックに以下を追加します。
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側の原因分析:
resolver1とresolver2の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を無効化するのも一つの選択肢です。