2026年6月12日

2026年6月12日

Unbound で複数ゾーンを管理する設定|local-zone・stub-zone・forward-zone・auth-zone の使い分け

Unbound で複数のゾーンを扱うときは、ゾーンごとに「答えをどこから持ってくるか」を決め、local-zone(Unbound 自身が答える)、stub-zone(社内の権威DNSに聞く)、forward-zone(別のキャッシュDNSに任せる)、auth-zone(ゾーンの写しを手元に持つ)の4つを使い分けます。この記事では、それぞれの違いと設定例、ファイルの分け方、DNSSEC の検証や DNS リバインディング対策とぶつかる典型的なつまずき、反映と確認の手順を説明します。

Unbound はキャッシュDNS(フルリゾルバー)です。NSD や BIND の権威サーバーのように、ゾーンを外部へ配信する用途を主眼にしたソフトではありません。ここでいう「複数ゾーンの管理」は、社内の名前、社内の権威DNSが持つゾーン、取引先や Active Directory のドメインなどを、1台の Unbound でまとめて引けるようにすることを指します。設定項目は版によって追加・変更されるため、unbound -V で手元の版を確認し、同梱の man unbound.conf と照らし合わせてください。記載は執筆時点(2026年10月現在)の情報です。変更前には unbound.conf と関連ファイルのバックアップを取ります。

4つの仕組みの違い

仕組み 答えの出どころ 向いている用途
local-zone / local-data unbound.conf に書いたレコード 数件〜数十件の社内名、特定ドメインの遮断
stub-zone 指定した権威DNS(非再帰で問い合わせ) 社内の NSD・BIND が持つゾーン
forward-zone 指定したキャッシュDNS(再帰を依頼) AD のドメインコントローラー、取引先のリゾルバー
auth-zone 手元に持つゾーンの写し ゾーンファイルで管理したい社内ゾーン、ルートゾーンの写し

迷いやすいのは stub と forward の違いです。stub は「このゾーンの権威はこのサーバーだ」と教える設定で、相手は権威DNSである必要があります。相手がキャッシュDNSだと、非再帰の問い合わせにまともに答えないことがあり、名前解決に失敗します。逆に、相手がキャッシュDNSなら forward を使います。

ファイルを用途ごとに分ける

ゾーンが増えると unbound.conf が長くなるため、用途ごとにファイルを分けて読み込みます。

# /etc/unbound/unbound.conf(抜粋)
server:
    interface: 10.0.0.10
    access-control: 10.0.0.0/8 allow
    access-control: 0.0.0.0/0 refuse

include: "/etc/unbound/unbound.conf.d/*.conf"

include はファイルの中身をその場に差し込む指定で、ワイルドカードも使えます。ここで気を付けたいのは、差し込まれたファイルが直前の節(server: など)の続きとして読まれる点です。各ファイルの先頭に server: や stub-zone: などの節名を書いておくと、どこに差し込まれても意図どおりに解釈されます。Debian 系のパッケージでは、unbound.conf.d を読み込む設定が最初から入っていることが多いので、二重に読み込まないよう既存の設定を確認します。

ファイル名は 10-local.conf、20-stub.conf、30-forward.conf のように役割と順番が分かる形にすると、あとから見たときに迷いません。

local-zone と local-data:Unbound 自身が答える

# /etc/unbound/unbound.conf.d/10-local.conf
server:
    local-zone: "lab.internal." static
    local-data: "nas.lab.internal. 3600 IN A 192.168.10.20"
    local-data: "printer.lab.internal. 3600 IN A 192.168.10.30"
    local-data-ptr: "192.168.10.20 nas.lab.internal."

    # 特定のドメインを社内から引けないようにする
    local-zone: "ads.example." always_nxdomain

local-zone の種類で、local-data に無い名前の扱いが変わります。

  • static:local-data に無い名前には NXDOMAIN を返します。外に問い合わせないので、社内専用のドメインに向きます。
  • transparent:local-data に無い名前は、通常どおり外へ解決しにいきます。公開ドメインの一部の名前だけ社内向けに差し替えたいときに使います。
  • typetransparent:名前はあるが型が無い場合(A はあるが AAAA は無い、など)も外へ解決しにいきます。

local-data はワイルドカードや委任のような込み入った内容には向きません。マニュアルも、そうした場合は stub-zone などを使うよう案内しています。件数が増えてきたら、社内に権威DNS(NSD など)を立てて stub-zone で参照するか、後述の auth-zone に移す目安です。

stub-zone:社内の権威DNSに聞く

# /etc/unbound/unbound.conf.d/20-stub.conf
stub-zone:
    name: "corp.example.com."
    stub-addr: 10.0.1.53
    stub-addr: 10.0.1.54

stub-zone:
    name: "10.in-addr.arpa."
    stub-addr: 10.0.1.53

stub-addr を複数書くと、応答の速いほうを選びながら問い合わせます。ゾーンごとに stub-zone: の節を1つずつ書きます。

プライベートアドレスの逆引きを社内の権威DNSに任せる場合は、もう1つ設定が要ります。Unbound は 10.in-addr.arpa. や 168.192.in-addr.arpa. などの逆引きゾーンを、外へ問い合わせないよう既定で static の local-zone として持っています。このままでは stub-zone を書いても使われないため、次のどちらかで既定の扱いを外します。

server:
    local-zone: "10.in-addr.arpa." nodefault
    # または、プライベートアドレスの逆引きの既定ゾーンをまとめて外す
    # unblock-lan-zones: yes

forward-zone:別のキャッシュDNSに任せる

# /etc/unbound/unbound.conf.d/30-forward.conf
forward-zone:
    name: "ad.example.com."
    forward-addr: 10.0.2.10
    forward-addr: 10.0.2.11

# それ以外を上流のリゾルバーに任せる場合(任意)
forward-zone:
    name: "."
    forward-addr: 192.0.2.53

Active Directory のドメインは、ドメインコントローラーが権威とキャッシュを兼ねていることが多いため、forward で渡すのが一般的です。forward-first: yes を付けると、転送先が応答しないときに Unbound 自身で解決を試みます。社内専用のドメインでは外に問い合わせても答えが無いため、付けないほうが原因を切り分けやすくなります。

名前が複数のゾーンに当てはまる場合は、もっとも長く一致するゾーンの設定が使われます。. を forward しつつ ad.example.com. を別の転送先にする、という書き方ができるのはこのためです。

auth-zone:ゾーンの写しを手元に持つ

# /etc/unbound/unbound.conf.d/40-auth.conf
auth-zone:
    name: "lab2.internal."
    zonefile: "/etc/unbound/zones/lab2.internal.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no

auth-zone は、ゾーンファイルを読み込むか、primary: に書いた権威DNSからゾーン転送で取得して、Unbound の中にゾーンの写しを持つ仕組みです。for-downstream はクライアントへ権威として直接答えるか、for-upstream は Unbound が名前解決するときにこの写しを使うか、fallback-enabled は写しが使えないときに通常の解決へ戻るかを決めます。

local-data よりも普通のゾーンファイルの書式で管理でき、ワイルドカードも扱えるため、社内ゾーンを Git で管理したい場合に向きます。ルートゾーンの写しを持って問い合わせを減らす使い方(RFC 8806)もマニュアルに例がありますが、取得元の指定などを誤ると名前解決全体に影響するため、検証環境で十分に試してから導入します。

DNSSEC とリバインディング対策でつまずく点

複数ゾーンを足したあとに「社内の名前だけ SERVFAIL になる」「答えが空になる」という相談はよくあります。原因はたいてい次の2つです。

DNSSEC の検証に失敗している:corp.example.com のように、公開ドメインの下に社内専用のゾーンを作ると、親の example.com が署名済みの場合、Unbound は「公開 DNS 上には corp が存在しない」という署名付きの証明を受け取り、社内DNSからの答えを不正と判断します。社内専用のゾーンは検証の対象から外します。

server:
    domain-insecure: "corp.example.com."

プライベートアドレスが応答から取り除かれている:DNS リバインディング対策として private-address: 10.0.0.0/8 などを設定していると、外から受け取った応答に含まれるプライベートアドレスは捨てられます。stub や forward の先が返す社内のアドレスも対象になるため、社内のドメインは例外として登録します。

server:
    private-domain: "corp.example.com."
    private-domain: "ad.example.com."

もう1つ、local-zone は stub-zone や forward-zone より先に評価されます。同じ名前に local-zone: ... static と stub-zone の両方を書くと、stub は使われません。どちらで答えるかはゾーンごとに1つに決めます。

反映と確認

# 文法を確認(問題なければ "no errors" と表示される)
unbound-checkconf

# 設定を読み直す(キャッシュも消える)
unbound-control reload

# どのゾーンがどの扱いになっているかを確認
unbound-control list_local_zones | grep internal
unbound-control list_stubs
unbound-control list_forwards
unbound-control list_auth_zones

unbound-control を使うには、remote-control: 節で有効にし、unbound-control-setup で鍵を作っておく必要があります。unbound-control forward_add や stub_add、local_data で実行中に設定を足すこともできますが、再起動すると消えます。恒久的な変更は設定ファイルに書きます。

ゾーンを1つだけ変えた場合は、キャッシュ全体ではなくそのゾーンだけ消すと、ほかの利用者への影響を抑えられます。

unbound-control flush_zone corp.example.com.
dig @10.0.0.10 www.corp.example.com A
dig @10.0.0.10 -x 10.0.1.20

応答の status: が NOERROR か、SERVFAIL ならログ(verbosity を一時的に上げる)に DNSSEC の検証失敗が出ていないかを見ます。社内のアドレスが答えに含まれない場合は、private-domain の登録漏れを疑います。

まとめ

  • 社内名を数件持つなら local-zone、社内の権威DNSに聞くなら stub-zone、別のキャッシュDNSに任せるなら forward-zone、ゾーンファイルで管理したいなら auth-zone を使います。
  • 設定は用途ごとにファイルを分け、各ファイルの先頭に節名を書いてから include で読み込みます。
  • プライベートアドレスの逆引きを stub するときは nodefault などで既定のゾーンを外し、社内専用ドメインには domain-insecure と private-domain を設定します。
  • unbound-checkconf で確認してから反映し、list_stubs などで意図どおりの扱いになっているかを確かめます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲