タグ: docker

  • 自宅ラボのBIND 9をCVE対応でアップデート|Docker移行で発生した権限問題とDNS監視

    はじめに

    自宅ラボでは、AdGuard HomeとBIND 9を組み合わせて内部DNSを運用しています。

    先日、Xで「BIND 9を使っている」という内容をポストしたところ、それを見てくださった方からBIND 9の脆弱性についての記事を教えていただきました。

    紹介いただいた情報では、BIND 9に以下の2件の脆弱性が報告されていました。

    • CVE-2026-19666
    • CVE-2026-19667

    調べたところどちらもリゾルバのDoSに関する脆弱性で、CVE-2026-19666はDNS64有効時、CVE-2026-19667はデフォルトで影響するとされています。CVSSはどちらも7.5(High)です。

    自宅ラボのBINDも対象となる可能性があるため、実際の構成を確認したうえでアップデートすることにしました。

    今回は、その対応内容をまとめます。

    1. 更新前のDNS構成

    今回の環境では、DNSの役割をAdGuard HomeとBINDで分けています。

    イメージとしては以下の構成です。

    クライアント
         |
         v
    AdGuard Home
         |
         | 内部ドメイン
         v
       BIND 9
         |
         +-- 内部正引き
         +-- 内部逆引き
         +-- Tailscale用DNS
         |
         v
      PBS Secondary

    AdGuard Homeをクライアントから見えるDNSサーバとして使用し、内部ドメインの問い合わせだけBINDへ渡しています。

    外部ドメインについてはAdGuard Home側で処理する構成です。

    なお、記事では実環境のIPアドレスやドメイン名などは掲載せず、構成が分かる範囲でサンプル値に置き換えています。


    2. BINDの役割を確認

    今回の脆弱性情報をきっかけに、まず現在のBINDの役割を確認しました。

    この環境のBINDは、インターネット向けの再帰DNSとして使用しているのではなく、内部ゾーンを提供するauthoritative DNSとして利用しています。

    そのため、

    recursion no;

    として、BIND自身では再帰問い合わせを行わない構成にしています。

    また、問い合わせ元についても、以前の設定に存在していた

    any;

    を削除しました。

    内部ネットワークからの問い合わせだけを許可する構成に変更しています。


    3. DNS64の利用状況を確認

    今回の脆弱性のうち、CVE-2026-19666はDNS64有効時に影響するとされています。

    そこで、AdGuard Home側の設定を確認しました。

    この環境ではDNS64を使用しておらず、

    use_dns64: false

    となっていることを確認しました。

    一方、CVE-2026-19667についてはデフォルトで影響するとされているため、DNS64を使用していないことだけで対応を終えるのではなく、BIND自体を更新することにしました。


    4. BINDイメージを変更

    更新前はUbuntuベースのBINDイメージを使用していました。

    BINDのバージョンを確認したところ、今回の脆弱性対応として必要な修正版へ確実に更新するため、ISC公式のBINDイメージを利用することにしました。

    変更前:

    ubuntu/bind9:latest

    変更後:

    internetsystemsconsortium/bind9:9.20

    最終的に、

    BIND 9.20.29

    で起動していることを確認しました。


    5. Dockerイメージ変更で発生した権限問題

    今回、一番苦労したのがDockerイメージ変更後の権限問題です。

    ISC公式イメージへ変更したところ、最初はBINDコンテナが起動と停止を繰り返す状態になりました。

    ログを見ると、

    directory '/var/cache/bind' is not writable

    というエラーが出ていました。

    ISC公式イメージのbindユーザーを確認すると、

    uid=53(bind) gid=53(bind)

    でした。

    一方、ホスト側のcacheディレクトリは別のUID/GIDで所有されていました。

    つまり、同じ「bind」という名前のユーザーを使用していても、Dockerイメージが変わればUID/GIDが同じとは限りません。

    そこで、ホスト側のcacheディレクトリをISC公式イメージのbindユーザーに合わせました。

    chown 53:53 /srv/ubn-name-sv/cache

    その後、BIND 9.20.29が正常に起動しました。


    6. 設定とゾーンを確認

    コンテナ起動後、

    named-checkconf -z /etc/bind/named.conf

    を実行しました。

    結果として、以下の3ゾーンが正常にロードされました。

    • 内部正引きゾーン
    • 内部逆引きゾーン
    • Tailscale用DNSゾーン

    設定ファイルの構文だけではなく、実際にゾーンがロードされているところまで確認しました。


    7. DNSの名前解決を順番に確認

    BINDが起動しただけでは、DNS環境が正常に復旧したとは言えません。

    そこで、DNSの経路ごとに確認しました。

    BINDへ直接問い合わせ

    まずBIND自身に問い合わせます。

    dig @127.0.0.1 -p 5353 dns01.home.example A +noall +answer

    期待するIPアドレスが返ることを確認しました。

    AdGuard HomeからBINDへ問い合わせ

    次に、AdGuard HomeからBINDへの名前解決を確認しました。

    docker exec adguardhome nslookup dns01.home.example 172.18.0.2

    こちらも正常に名前解決できました。

    ホストからAdGuard Home経由で問い合わせ

    最後に、普段クライアントが利用する経路を確認しました。

    dig @127.0.0.1 dns01.home.example A +noall +answer

    この結果も正常でした。

    DNSサーバを更新するときは、単純に「サービスが起動した」だけではなく、

    クライアント
      ↓
    AdGuard Home
      ↓
    BIND

    という実際の通信経路を確認することが重要です。


    8. PBSのセカンダリDNSも確認

    BINDでは、別サーバにセカンダリDNSを用意しています。

    今回の対応では、PBS側のセカンダリDNSについても確認しました。

    SOAレコードを取得して、

    dig @192.168.10.20 -p 5353 home.example SOA +noall +answer

    マスターとセカンダリのserialが一致することを確認しました。

    さらにBINDのログから、マスターからセカンダリへNOTIFYが送信されていることも確認しました。

    DNSの冗長化を構成している場合は、マスターだけ正常でも不十分です。

    セカンダリ側まで確認する必要があります。


    9. DNS確認用スクリプトを作成

    今回の確認を毎回手作業で行うのは面倒なので、最後にdns-pipeline.shを作成しました。

    スクリプトでは、

    1. BINDコンテナが起動しているか
    2. BINDのバージョン
    3. BIND設定とゾーン
    4. BINDへの直接問い合わせ
    5. BINDへの逆引き問い合わせ
    6. AdGuard Home経由の名前解決
    7. PBSセカンダリのSOA
    8. マスターとセカンダリのserial一致

    を確認します。

    すべて成功した場合、

    DNS PIPELINE: OK

    として終了コード0を返します。

    どれか1つでも失敗すると、

    DNS PIPELINE: NG

    として終了コード1を返します。

    実際に今回の環境で実行し、すべてのチェックがPASSして正常終了することを確認しました。


    10. 今回の対応で得られたこと

    今回の対応では、単純にBINDをアップデートしただけではありませんでした。

    脆弱性情報をきっかけに、

    脆弱性情報を確認
        ↓
    現在のDNS構成を確認
        ↓
    BINDの役割を確認
        ↓
    DNS64の利用状況を確認
        ↓
    BINDイメージを変更
        ↓
    UID/GID問題を切り分け
        ↓
    BINDをアップデート
        ↓
    ゾーン確認
        ↓
    DNS疎通確認
        ↓
    セカンダリDNS確認
        ↓
    ヘルスチェックを自動化

    という一連の対応を行いました。

    特に、Dockerイメージを変更するときには、アプリケーションの設定だけでなく、コンテナ内ユーザーのUID/GIDやホスト側のボリューム権限まで確認する必要があることを改めて実感しました。

    また、DNSについては「サービスが起動している」だけではなく、実際の問い合わせ経路を確認することが重要だと感じました。


    まとめ

    今回、XでBIND 9を使用していることをポストしたことをきっかけに、BIND 9の脆弱性情報を教えていただきました。

    そこから自宅ラボのDNS構成を確認し、BINDをISC公式イメージへ移行して9.20.29へ更新しました。

    その過程でDockerのUID/GIDによる権限問題も発生しましたが、原因を切り分けて解決し、最終的には、

    • BIND 9.20.29への更新
    • authoritative-onlyとしての運用確認
    • DNS64を使用していないことの確認
    • 内部ネットワークからの問い合わせに限定
    • 3ゾーンの正常ロード
    • AdGuard HomeからBINDへの名前解決
    • PBSセカンダリとの同期
    • DNSパイプラインによる自動チェック

    まで確認できました。

    自宅ラボであっても、脆弱性情報をきっかけに実際の構成を確認し、アップデート、障害対応、疎通確認、監視まで一通り実施してみると、普段の運用では気づきにくい問題を発見できます。

    今回教えていただいたことをきっかけに、DNSまわりの構成を見直す良い機会になりました。