2026年6月12日

2026年6月12日

BIND のACL設定方法|acl 文で問い合わせ・再帰・ゾーン転送を許可する相手を決める

BIND のアクセス制限は、acl 文で「信頼する相手」に名前を付け、その名前を allow-query・allow-recursion・allow-transfer などの項目に割り当てる形で設定します。どの項目で何を制限するのかを区別しておかないと、「外部から再帰問い合わせができてしまう(オープンリゾルバー)」「セカンダリにゾーンが届かない」といった問題が起きます。この記事では、ACL の書き方の規則、用途別の設定例、TSIG 鍵を使ったゾーン転送の制限、設定後の確認方法までを説明します。

内容は BIND 9.18 系・9.20 系を前提にしています(2026年10月現在)。既定値は版によって変わることがあり、たとえば allow-transfer は、以前は誰にでも転送を許す既定でしたが、9.20 系の新しい版では既定が none に変わっています。既定値に頼らず、必要な項目は明示的に書くのが安全です。設定ファイルの場所は、Debian・Ubuntu では /etc/bind/named.conf.options など、RHEL 系では /etc/named.conf が一般的です。変更前にファイルをバックアップしておきます。

ACL の書き方の規則

acl 文は、IP アドレスやネットワークの一覧(アドレスマッチリスト)に名前を付けるものです。

acl "internal" {
    127.0.0.1;
    ::1;
    192.168.0.0/16;
    10.0.0.0/8;
    2001:db8:10::/48;
};

acl "secondaries" {
    198.51.100.2;
    203.0.113.2;
};

書くときに押さえておく規則は次のとおりです。

  • 上から順に照合し、最初に一致した項目で決まる:! を付けると「一致したら拒否」になります。{ !192.168.1.66; 192.168.1.0/24; }; は 192.168.1.66 だけを除いて許可しますが、順序を逆にすると 192.168.1.66 も先に許可に一致してしまいます。
  • 組み込みの名前がある:any(すべて)、none(なし)、localhost(サーバー自身のアドレス)、localnets(サーバーのインターフェースが属するネットワーク)の4つです。
  • 使う前に定義する:ACL の名前は、それを参照する箇所より前に acl 文で定義しておきます。include で分けている場合は読み込む順序にも注意します。
  • ACL の中で別の ACL や鍵を参照できる:acl "admin" { internal; key "xfr-key"; }; のように組み合わせられます。

localnets は便利ですが、VPS のようにグローバルアドレスのネットワークに直接つながっているサーバーでは、同じネットワークにいる他の利用者まで含むことがあります。再帰を許可する範囲には、localnets ではなく自分で定義した ACL を使うほうが意図が明確になります。

ACL を割り当てる主な項目

項目 制限する内容
allow-query 問い合わせ全般を受け付ける相手
allow-recursion 再帰問い合わせ(外部の名前の解決)を許す相手
allow-query-cache キャッシュからの応答を返す相手
allow-transfer ゾーン転送(AXFR/IXFR)を許す相手
allow-update 動的更新を許す相手
allow-notify セカンダリ側で、プライマリ以外からの NOTIFY を受け付ける相手
blackhole 問い合わせを一切無視する相手

options に書くとサーバー全体の既定になり、zone の中に書くとそのゾーンだけ上書きされます。権威ゾーンは誰からの問い合わせにも答える必要がありますが、再帰とキャッシュは内部の利用者だけに限る、というように項目ごとに範囲を変えるのが基本の考え方です。

用途別の設定例

権威サーバー専用(外部に公開するゾーンだけを持つ)

options {
    directory "/var/cache/bind";
    recursion no;
    allow-query { any; };
    allow-transfer { none; };
};

zone "example.com" {
    type primary;
    file "/etc/bind/zones/example.com.zone";
    allow-transfer { secondaries; };
    also-notify { 198.51.100.2; 203.0.113.2; };
};

recursion no; にすると再帰は行われないため、オープンリゾルバーになる心配がありません。ゾーン転送は全体で none にしておき、必要なゾーンだけセカンダリに許可します。type primary は現在の版で推奨されている書き方で、古い type master も引き続き読み込めます。

社内向けのキャッシュサーバー

options {
    directory "/var/cache/bind";
    recursion yes;
    allow-query { internal; };
    allow-recursion { internal; };
    allow-query-cache { internal; };
    allow-transfer { none; };
    listen-on { 127.0.0.1; 192.168.1.53; };
};

allow-recursion だけを設定して allow-query を any のままにすると、外部からキャッシュ済みの内容を引けてしまう場合があります。再帰・キャッシュ・問い合わせの3つをそろえて内部に限定し、さらに listen-on で待ち受けるアドレスも内部向けに絞っておくと、設定の漏れがあっても影響を小さくできます。

権威とキャッシュを1台で兼ねることもできますが、ACL の設定が複雑になり、どちらかの設定変更がもう一方に影響します。可能であれば、サーバー(または少なくとも待ち受けるアドレス)を分けることをおすすめします。

TSIG 鍵でゾーン転送を制限する

IP アドレスだけの制限は、アドレスの付け替えや経路の誤りに弱いため、ゾーン転送には TSIG 鍵を組み合わせるのが一般的です。

sudo tsig-keygen -a hmac-sha256 xfr-key | sudo tee /etc/bind/xfr-key.key
sudo chown root:bind /etc/bind/xfr-key.key
sudo chmod 640 /etc/bind/xfr-key.key
include "/etc/bind/xfr-key.key";

acl "secondaries-signed" {
    key "xfr-key";
};

zone "example.com" {
    type primary;
    file "/etc/bind/zones/example.com.zone";
    allow-transfer { secondaries-signed; };
};

セカンダリ側にも同じ鍵を置き、server 192.0.2.1 { keys { xfr-key; }; }; のようにプライマリとの通信で鍵を使うよう設定します。鍵のファイルには秘密の値が入っているので、権限を絞り、Git などで管理する場合は除外します。グループ名(bind か named か)はディストリビューションによって異なります。

設定を反映して確認する

書式の検査をしてから反映します。

sudo named-checkconf
sudo rndc reconfig

named-checkconf は問題がなければ何も表示しません。未定義の ACL 名を参照している場合などはここでエラーになります。rndc reconfig は設定ファイルを読み直す操作で、サービスを止めずに反映できます。

反映したら、許可した側と許可していない側の両方から試します。

# 内部の端末から:再帰が使えること
dig @192.168.1.53 www.example.org A

# 外部の端末から:再帰が拒否されること(status: REFUSED になる)
dig @203.0.113.53 www.example.org A

# 許可していない端末から:ゾーン転送が失敗すること
dig @203.0.113.53 example.com AXFR

# セカンダリ相当の環境から:鍵を使った転送が成功すること
dig @203.0.113.53 example.com AXFR -k /etc/bind/xfr-key.key

拒否された問い合わせは、BIND のログに「query (cache) ... denied」や「zone transfer ... denied」のような行で記録されます。どの ACL に引っかかったかを追いやすくするため、security カテゴリーを別のファイルに出しておくと便利です。

logging {
    channel security_log {
        file "/var/log/named/security.log" versions 5 size 10m;
        severity info;
        print-time yes;
    };
    category security { security_log; };
};

ログのディレクトリは named を動かすユーザーが書き込める必要があります。AppArmor や SELinux が有効な環境では、許可されたディレクトリ以外に書けないことがあるので、ログが出ない場合はその設定も確認します。

ACL だけに頼らない

ACL は「誰に答えるか」を決める仕組みで、大量の問い合わせを防ぐものではありません。権威サーバーでは応答レート制限(rate-limit)、全体ではファイアウォールで53番ポートへの到達範囲を絞るなど、別の層の対策と組み合わせます。設定を変えたあとは、外部の環境から再帰が拒否されることを定期的に確かめておくと、意図しない変更に気づけます。

まとめ

  • acl 文で名前を付け、allow-query・allow-recursion・allow-query-cache・allow-transfer などに割り当てます。上から順に照合し、最初の一致で決まります。
  • 権威サーバーは recursion no;、キャッシュサーバーは再帰・キャッシュ・問い合わせの3つを内部に限定します。localnets の範囲には注意します。
  • allow-transfer は版によって既定値が違うため明示し、TSIG 鍵と組み合わせます。
  • named-checkconf と rndc reconfig で反映し、許可する側と拒否する側の両方から dig で確かめます。

お気軽にご相談ください

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