2026年6月22日

2026年6月22日

BINDのインストールとDNSサーバー設定方法(権威サーバーの基本構成)

BIND(named)は、パッケージで導入して設定ファイルにゾーンを定義し、構文チェックをしてから読み込ませる、という流れで動かせます。この記事では、Ubuntu/Debian と RHEL系でのインストール、自分のドメインに答える権威DNSサーバーとしての基本設定、ゾーンファイルの書き方、セカンダリへの転送設定、動作確認とつまずきやすい点までを順に説明します。外部に公開する場合は、オープンリゾルバーにしない設定が重要なので、その点も合わせて解説します。

最初に決めること:権威サーバーかキャッシュサーバーか

DNSサーバーには役割が2種類あります。

  • 権威DNSサーバー:自分が管理するドメイン(例: example.com)について「正解」を返すサーバーです。レジストラにネームサーバーとして登録するのはこちらです。
  • キャッシュDNSサーバー(フルリゾルバー):利用者の問い合わせを受けて、インターネット上を再帰的にたどって答えを探すサーバーです。社内LANやサーバー群の名前解決に使います。

BINDはどちらにもなれますが、1台で両方を兼ねるとセキュリティと運用の両面で問題が起きやすいため、役割は分けるのが一般的です。この記事では権威サーバーを中心に扱い、キャッシュサーバーの設定は後半で簡単に触れます。

なお、WordPressサイトを運営するだけなら、レジストラやクラウドのDNSサービスを使うほうが手間も障害リスクも小さく済みます。自前で権威サーバーを運用するなら、ネットワーク的に離れた場所に最低2台を置き、OSとBINDの更新を継続できる体制が前提になります。

インストール

ディストリビューションによってパッケージ名と設定ファイルの場所が異なります。

# Ubuntu / Debian
sudo apt update
sudo apt install bind9 bind9-utils bind9-dnsutils

# RHEL / Rocky Linux / AlmaLinux
sudo dnf install bind bind-utils
sudo systemctl enable --now named

主な配置は次のとおりです。

項目 Ubuntu / Debian RHEL系
メイン設定 /etc/bind/named.conf(options と local に分割) /etc/named.conf
作業ディレクトリ /var/cache/bind /var/named
サービス名 named(bind9 という別名でも扱える) named

古いUbuntu/Debianでは補助ツールのパッケージ名が bind9utils だった時期があるなど、名称はリリースによって変わります。BIND自体もISCがサポート期間の異なる系列を並行して提供しているため、使う系列のサポート状況をISCの公式情報で確認してください(2026年10月現在)。

options の設定(オープンリゾルバーにしない)

権威サーバーとして公開する場合、最も重要なのは再帰問い合わせを受け付けないことです。誰の問い合わせにも再帰で答えるサーバー(オープンリゾルバー)は、DNSリフレクション攻撃の踏み台に悪用されます。

Ubuntu/Debianなら /etc/bind/named.conf.options を次のように設定します(RHEL系では /etc/named.conf の options 内で同じ項目を設定し、directory は /var/named のままにします)。

options {
    directory "/var/cache/bind";

    // 権威サーバーなので再帰は無効
    recursion no;

    // ゾーン転送は既定で誰にも許可しない(ゾーンごとに個別許可)
    allow-transfer { none; };

    // バージョン文字列を返さない
    version "not disclosed";

    listen-on { any; };
    listen-on-v6 { any; };

    dnssec-validation auto;
};

version を隠すのは情報を減らすための補助的な対策で、脆弱性対策の本体はBINDを最新の修正版に保つことです。

ゾーンを定義する

/etc/bind/named.conf.local(RHEL系は /etc/named.conf の末尾)に、管理するゾーンとファイルの場所を書きます。

zone "example.com" {
    type primary;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 198.51.100.53; };   // セカンダリのIP
    also-notify { 198.51.100.53; };
};

type primary は以前 type master と書かれていた設定で、新しいBINDでは primary / secondary の表記が使えます。古い系列では master / slave しか受け付けない場合があるので、手元のバージョンの資料に合わせてください。

ゾーンファイルを書く

ゾーンファイルには、そのドメインのレコードを列挙します。以下は説明用ドメイン example.com と説明用アドレスを使った例です。

$TTL 3600
@   IN  SOA ns1.example.com. hostmaster.example.com. (
            2026101801  ; serial(更新のたびに増やす)
            3600        ; refresh
            900         ; retry
            1209600     ; expire
            300 )       ; negative cache TTL

    IN  NS  ns1.example.com.
    IN  NS  ns2.example.com.

ns1 IN  A   192.0.2.53
ns2 IN  A   198.51.100.53

@   IN  A   203.0.113.10
www IN  CNAME example.com.

@   IN  MX  10 mail.example.com.
mail IN A   203.0.113.25
@   IN  TXT "v=spf1 mx -all"

書くときにつまずきやすいのは次の点です。

  • 末尾のドット:ns1.example.com. のように完全修飾名の最後にはドットが要ります。ドットを忘れると ns1.example.com.example.com. と解釈されます。
  • シリアル番号:内容を変えたら増やします。増やさないとセカンダリが更新を取りに来ません。「日付+2桁の連番」の形式がよく使われます。
  • SOAのメールアドレス:hostmaster.example.com. は hostmaster@example.com を表します。@ の代わりに最初のドットを使う書き方です。
  • TTL:移転前は短くしておくと切り替えが早く反映されます。

ファイルを作ったら、所有者と権限を named が読める状態にします。Ubuntu/Debianでは AppArmor、RHEL系では SELinux が named の読み書きできる場所を制限しているため、独自の場所に置くと「権限があるのに読めない」状態になることがあります。標準の配置に従うのが無難です。

# Ubuntu/Debian の例(ディレクトリは事前に作成)
sudo mkdir -p /etc/bind/zones
sudo chown root:bind /etc/bind/zones/db.example.com
sudo chmod 644 /etc/bind/zones/db.example.com

構文チェックと反映

設定を読み込ませる前に、付属のチェックツールで確認します。エラーのまま再起動すると、既存のゾーンまで応答しなくなるおそれがあります。

# 設定ファイル全体の構文チェック(何も出力されなければ問題なし)
sudo named-checkconf

# ゾーンファイルのチェック
sudo named-checkzone example.com /etc/bind/zones/db.example.com

# 設定やゾーンを再読み込み
sudo rndc reload
sudo systemctl status named

動作確認

# 自分のサーバーに直接問い合わせる(+norec で再帰を要求しない)
dig @127.0.0.1 example.com SOA +norec
dig @127.0.0.1 www.example.com A +norec

# 外部から問い合わせ、権威応答(flags に aa)が返るか確認
dig @192.0.2.53 example.com A

# 外部からの再帰問い合わせが拒否されることを確認(REFUSED になればよい)
dig @192.0.2.53 www.google.com A

外部からの確認では、ファイアウォールで UDP 53番とTCP 53番の両方 を開けているかが重要です。TCPを閉じていると、応答が大きいときやゾーン転送で失敗します。うまくいかないときは sudo journalctl -u named でログを確認すると、ゾーンの読み込みエラーや権限の問題が記録されています。

最後に、レジストラの管理画面でネームサーバーを ns1・ns2 に変更します。ネームサーバー名が自分のドメイン内にある場合は、グルーレコード(ネームサーバーのIPアドレス)の登録も必要です。

セカンダリとの転送をTSIGで守る

上の例ではIPアドレスで転送相手を限定しましたが、共有鍵で認証するTSIGを使うとより安全です。tsig-keygen で鍵を生成し、プライマリとセカンダリの両方に同じ鍵を設定して、allow-transfer { key "鍵名"; }; のように指定します。鍵ファイルは設定と同じく権限を絞り、リポジトリなどに置かないよう管理してください。

社内向けキャッシュサーバーにする場合

キャッシュサーバーとして使う場合は recursion yes; にしたうえで、問い合わせを受け付ける範囲を限定します。

options {
    directory "/var/cache/bind";
    recursion yes;
    allow-recursion { 127.0.0.1; ::1; 10.0.0.0/8; 192.168.0.0/16; };
    allow-query-cache { 127.0.0.1; ::1; 10.0.0.0/8; 192.168.0.0/16; };
    dnssec-validation auto;
};

範囲を指定せずに外部へ公開すると、前述のオープンリゾルバーになります。

まとめ

  • BINDは権威サーバーとキャッシュサーバーで役割を分け、公開する権威サーバーは recursion no; にします。
  • ゾーンファイルは末尾のドットとシリアル番号の更新に注意し、named-checkconf と named-checkzone を通してから rndc reload で反映します。
  • UDP・TCPとも53番を開け、外部から dig で権威応答と再帰拒否を確認します。
  • 転送はIP制限やTSIGで相手を限定し、BINDは継続して更新します。
  • 運用の負担を考えると、WordPressサイトだけなら外部のDNSサービスを使う選択も有力です。

お気軽にご相談ください

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