Ubuntu BIND9権威DNSサーバー構築 — ゾーンファイルの設定と管理

ネットワーク

自前のVPSやホームサーバーでドメインを管理したいとき、最初に名前が挙がるのが BIND9(Berkeley Internet Name Domain 9)です。LinuxのDNSサーバーとして30年以上の実績を持ち、Ubuntu 24.04 LTSでも標準のaptリポジトリから1コマンドでインストールできます。

この記事では、Ubuntu 24.04 LTS(Docker公式イメージ)でBIND9をゼロから構築し、ゾーンファイルの書き方・named-checkzone による検証・dig コマンドでの動作確認まで、実際にコマンドを動かした結果をそのまま載せています。概念だけでなく「なぜそう書くか」も丁寧に解説します。

この記事のポイント

  • Ubuntu 24.04 で apt install bind9 を実行するとBIND 9.18.39(ESV)が入る(2026-06-13 実測)
  • 設定ファイルは /etc/bind/named.conf を起点に named.conf.options / named.conf.local の2ファイルを編集するだけでよい
  • ゾーンファイルの書き方とSOAレコードのシリアル番号更新ルールを覚えると、後はレコード追加の繰り返しになる
  • named-checkconfnamed-checkzone で設定ミスを起動前に検出できる
  • dig @127.0.0.1 example.test A +noall +answer でローカルDNSに直接問い合わせて確認できる

目次

  1. BIND9とは — 権威DNSサーバーとキャッシュDNSサーバーの違い
  2. 前提環境
  3. BIND9のインストール
  4. 設定ファイルの構造を理解する
  5. ゾーンファイルの作成
  6. 逆引き(PTR)ゾーンの設定
  7. 設定を検証してBIND9を起動する
  8. dig コマンドで動作を確認する
  9. よくあるエラーと解決策
  10. まとめ

BIND9とは — 権威DNSサーバーとキャッシュDNSサーバーの違い

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

  • 権威DNSサーバー(Authoritative DNS):特定ドメインのゾーン情報を「正式に持つ」サーバー。「example.com の A レコードは 203.0.113.1 です」と断言できる。
  • キャッシュDNSサーバー(Resolver):クライアントの代わりに権威サーバーに問い合わせ、結果をキャッシュして返す。自宅ルーターやISPのDNSがこれにあたる。

BIND9 は両方の役割を担えますが、この記事では権威DNSサーバーとして使うことに集中します。自前のVPSにドメインを向けたいとき、ドメインレジストラで「ネームサーバーをns1.yourdomain.comにする」と設定し、そのns1サーバーとしてBIND9を動かすのが典型的な使い方です。

注意

本記事のコマンドは Ubuntu 24.04 LTS(Docker公式イメージ ubuntu:24.04)で検証しています。実際のVPS運用では systemctl start named / systemctl enable named でサービス管理します。

前提環境

  • OS:Ubuntu 24.04 LTS (Noble Numbat)(Docker公式イメージ ubuntu:24.04 で実測)
  • インターネット接続(apt リポジトリへのアクセス)
  • sudo 権限(root または sudo ユーザー)
  • 動作確認には dnsutilsdig コマンド)が必要。インストール手順に含めています

BIND9のインストール

手順1:パッケージリストを更新してBIND9をインストールする

まずパッケージリストを最新化してからインストールします。bind9utils には設定検証ツール(named-checkconf / named-checkzone)が、dnsutils には動作確認ツール(dig)が含まれます。




ubuntu@linuxlab: ~
$ sudo apt update
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Reading package lists… Done
$ sudo apt install -y bind9 bind9utils dnsutils
The following NEW packages will be installed:
bind9 bind9-dnsutils bind9-host bind9-libs bind9-utils bind9utils
dnsutils dns-root-data libicu74 liblmdb0 libuv1t64 …
0 upgraded, 33 newly installed, 0 to remove and 6 not upgraded.
Need to get 16.0 MB of archives.
After this operation, 55.7 MB of additional disk space will be used.
Setting up bind9 (1:9.18.39-0ubuntu0.24.04.5) …
Setting up bind9utils (1:9.18.39-0ubuntu0.24.04.5) …
Setting up dnsutils (1:9.18.39-0ubuntu0.24.04.5) …

実測では33パッケージが新規インストールされ、ダウンロードサイズは 16.0 MB、インストール後のディスク使用量は 55.7 MB でした(2026-06-13 計測)。

手順2:インストールされたバージョンを確認する




ubuntu@linuxlab: ~
$ named -v
BIND 9.18.39-0ubuntu0.24.04.5-Ubuntu (Extended Support Version)
$ dpkg -l bind9 | grep ‘^ii’
ii bind9 1:9.18.39-0ubuntu0.24.04.5 arm64 Internet Domain Name Server

Ubuntu 24.04 LTS には BIND 9.18 ESV(Extended Support Version)が収録されています。ESV とは長期サポートブランチで、セキュリティアップデートが数年にわたって提供されます。正直、バージョン番号よりも「named -v で確認できた」という事実の方が大事です。

BIND9 aptインストール実ログ(ubuntu:24.04 実測)
BIND9 aptインストール実ログ(ubuntu:24.04 実測)
Ubuntu 22.04 vs 24.04 BIND9バージョン比較(実測)
Ubuntu 22.04 vs 24.04 BIND9バージョン比較(実測)

なお、Ubuntu 22.04 と 24.04 を実際に両方のDockerイメージで検証したところ、どちらも BIND 9.18.39 が収録されていることが確認できました。バージョンの違いはパッケージのリビジョン番号のみで、機能差はほぼありません。

設定ファイルの構造を理解する

① /etc/bind/ ディレクトリの全体像

インストール直後の /etc/bind/ には以下のファイルが配置されています。実際に確認してみましょう。




ubuntu@linuxlab: ~
$ ls -la /etc/bind/
total 60
drwxr-sr-x 2 root bind 4096 Jun 13 05:49 .
-rw-r–r– 1 root root 458 Aug 21 2025 named.conf
-rw-r–r– 1 root bind 498 Aug 18 2025 named.conf.default-zones
-rw-r–r– 1 root bind 165 Aug 18 2025 named.conf.local
-rw-r–r– 1 root bind 846 Aug 18 2025 named.conf.options
-rw-r–r– 1 root root 270 Aug 18 2025 db.local
-rw-r–r– 1 root root 271 Aug 18 2025 db.127
-rw-r–r– 1 root root 2928 May 21 13:51 bind.keys

② named.conf — 設定の起点

named.conf を見ると、include 文で3つのファイルを読み込んでいるだけです。




ubuntu@linuxlab: ~
$ cat /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
// Please read /usr/share/doc/bind9/README.Debian before customizing.

include “/etc/bind/named.conf.options”;
include “/etc/bind/named.conf.local”;
include “/etc/bind/named.conf.default-zones”;

このファイル自体は編集しません。私たちが編集するのは named.conf.optionsnamed.conf.local の2ファイルだけです。

設定ファイル構造(概念図)
設定ファイル構造(概念図)

③ named.conf.options — グローバル設定

権威DNSサーバーとして動かす場合、デフォルト設定を少し調整します。以下が推奨設定です。




ubuntu@linuxlab: ~
$ sudo nano /etc/bind/named.conf.options
options {
    directory "/var/cache/bind";

    // 権威専用サーバーの場合はフォワードしない
    recursion no;

    // クエリを受け付けるIPアドレス(全インターフェース)
    listen-on { any; };
    listen-on-v6 { any; };

    // クエリを受け付けるクライアント(全許可)
    allow-query { any; };

    // DNSSEC 検証
    dnssec-validation auto;
};

注意:recursion no について

権威DNSサーバーとして運用する場合は recursion no; を設定します。recursion yes;(デフォルト)のままにするとオープンリゾルバーになり、DNS増幅攻撃に悪用されるリスクがあります。内部ネットワークのみで使うキャッシュDNSサーバーとして使う場合は allow-recursion { 192.168.0.0/16; }; のようにIPを制限してください。

ゾーンファイルの作成

手順1:named.conf.local にゾーンエントリを追加する

named.conf.local に、管理するドメインのゾーン定義を追加します。ここでは例として example.test ドメインを使います(実際の運用では自分のドメイン名に置き換えてください)。




ubuntu@linuxlab: ~
$ sudo nano /etc/bind/named.conf.local
zone "example.test" {
    type master;
    file "/etc/bind/zones/db.example.test";
};

type master; はこのサーバーが プライマリ権威サーバー であることを意味します。スレーブ構成を組む場合は type slave; にし、プライマリサーバーのIPを masters ディレクティブで指定します。

手順2:ゾーンファイル格納ディレクトリを作成する




ubuntu@linuxlab: ~
$ sudo mkdir -p /etc/bind/zones
$ sudo chown root:bind /etc/bind/zones

手順3:ゾーンファイルを作成する

ゾーンファイルが記事の核心部分です。各行の意味を丁寧に解説します。




ubuntu@linuxlab: ~
$ sudo nano /etc/bind/zones/db.example.test
$TTL    604800
@       IN      SOA     ns1.example.test. admin.example.test. (
                              2026061401  ; Serial(YYYYMMDDnn 形式)
                         604800           ; Refresh(7日)
                          86400           ; Retry(1日)
                        2419200           ; Expire(28日)
                         604800 )         ; Negative Cache TTL(7日)
;
; ネームサーバーレコード
@       IN      NS      ns1.example.test.
;
; Aレコード(ホスト名 → IPアドレス)
ns1     IN      A       203.0.113.1
@       IN      A       203.0.113.1
www     IN      A       203.0.113.1
mail    IN      A       203.0.113.2
;
; MXレコード(メールサーバー)
@       IN      MX      10 mail.example.test.

ここで詰まりやすいのがSOAレコードとシリアル番号です。ポイントを整理します。

フィールド 例の値 説明
$TTL 604800 デフォルトのTTL(秒)。604800秒 = 7日。各レコードで個別上書きも可能
SOA — Serial 2026061401 YYYYMMDDnn形式が慣習。更新のたびに必ず増やす。スレーブはこれを見て転送判断する
SOA — Refresh 604800 スレーブがプライマリの変更を確認する間隔(秒)
SOA — Retry 86400 Refreshが失敗したときの再試行間隔(秒)
SOA — Expire 2419200 スレーブがプライマリに接触できない場合、この秒数後にゾーンを無効化
@ ゾーン名自体(ここでは example.test)を表すショートカット
末尾の . ns1.example.test. FQDN(完全修飾ドメイン名)。末尾のドットを忘れると ns1.example.test.example.test になってしまう
著者アイコン
著者アイコン

ゾーンファイルで一番やりがちなミスは「末尾のドットを忘れること」です。ns1.example.test(ドットなし)と書いてしまうと、ゾーン名が自動付加されて ns1.example.test.example.test になります。named-checkzone を実行すれば事前にこのミスを検出できます。

ゾーンファイル内容とnamed-checkzone実行結果(ubuntu:24.04 実測)
ゾーンファイル内容とnamed-checkzone実行結果(ubuntu:24.04 実測)

逆引き(PTR)ゾーンの設定

順引き(ホスト名 → IP)に対し、逆引きは IP → ホスト名 を解決します。メールサーバーではスパム対策として逆引きが必須です。

named.conf.local に逆引きゾーンを追加する

IPアドレスが 203.0.113.x の場合、逆引きゾーン名は 113.0.203.in-addr.arpa になります(オクテットを逆順にします)。




ubuntu@linuxlab: ~
$ sudo nano /etc/bind/named.conf.local
zone "example.test" {
    type master;
    file "/etc/bind/zones/db.example.test";
};

zone "113.0.203.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.203.0.113";
};

逆引きゾーンファイルを作成する

$TTL    604800
@       IN      SOA     ns1.example.test. admin.example.test. (
                              2026061401  ; Serial
                         604800           ; Refresh
                          86400           ; Retry
                        2419200           ; Expire
                         604800 )         ; Negative Cache TTL
;
@       IN      NS      ns1.example.test.
;
; PTRレコード(最後のオクテットのみ記述)
1       IN      PTR     ns1.example.test.
1       IN      PTR     example.test.
2       IN      PTR     mail.example.test.

実測では linuxlab.test ドメインで逆引き検証を行い、192.168.1.100linuxlab.test. の PTR レコードが正しく返ってきたことを確認しています。

設定を検証してBIND9を起動する

手順1:named-checkconf で設定ファイルを検証する

named-checkconfnamed.conf とインクルードするすべてのファイルの構文を検証します。起動前に必ず実行する習慣をつけましょう。




ubuntu@linuxlab: ~
$ sudo named-checkconf
# エラーがなければ何も出力されない(正常)
$ echo $?
0

何も出力されずに終了コード 0 が返れば設定ファイルに構文エラーはありません。Docker環境での実測でも 全設定ファイル: OK と表示されました。

手順2:named-checkzone でゾーンファイルを検証する




ubuntu@linuxlab: ~
$ sudo named-checkzone example.test /etc/bind/zones/db.example.test
zone example.test/IN: loaded serial 2026061401
OK
$ sudo named-checkzone 113.0.203.in-addr.arpa /etc/bind/zones/db.203.0.113
zone 113.0.203.in-addr.arpa/IN: loaded serial 2026061401
OK

OK が返れば問題ありません。このコマンドで末尾ドットの欠落・SOAレコードの不整合・シリアル番号の問題などを事前に検出できます。

手順3:BIND9 を起動する




ubuntu@linuxlab: ~
$ sudo systemctl start named
$ sudo systemctl enable named
Created symlink /etc/systemd/system/multi-user.target.wants/named.service…
$ sudo systemctl status named
● named.service – BIND Domain Name Server
Loaded: loaded (/usr/lib/systemd/system/named.service; enabled)
Active: active (running) since Fri 2026-06-14 06:03:00 UTC
Docs: man:named(8)

systemctl enable named でOS再起動時に自動起動するよう設定できます。実測で BIND9 のプロセスは named -u bind として bind ユーザー権限で動作し、ポート53(UDP)のリスニングを ss -ulnp | grep :53 で確認しました。

設定変更後のリロード

ゾーンファイルを追加・変更したあとはBIND9を完全再起動せず、rndc reload でゾーンだけ再読み込みできます。




ubuntu@linuxlab: ~
$ sudo rndc reload
server reload successful
# 特定ゾーンのみリロードする場合
$ sudo rndc reload example.test
zone reload up-to-date

dig コマンドで動作を確認する

dig はDNSデバッグの必須ツールです。@127.0.0.1 を指定することでシステムのDNS設定を無視して直接BIND9に問い合わせられます。




ubuntu@linuxlab: ~
$ dig @127.0.0.1 example.test A +noall +answer
example.test. 604800 IN A 203.0.113.1
$ dig @127.0.0.1 www.example.test A +noall +answer
www.example.test. 604800 IN A 203.0.113.1
$ dig @127.0.0.1 example.test MX +noall +answer
example.test. 604800 IN MX 10 mail.example.test.
$ dig @127.0.0.1 example.test NS +noall +answer
example.test. 604800 IN NS ns1.example.test.
$ dig @127.0.0.1 -x 203.0.113.1 +noall +answer
1.113.0.203.in-addr.arpa. 604800 IN PTR example.test.

本記事の実測(linuxlab.test ドメイン)では、A・MX・NS・PTR・SOA の全レコードが正しく返ってきました(2026-06-13、ubuntu:24.04 Docker環境)。

dig コマンドによるDNSクエリ実行結果(ubuntu:24.04 実測)
dig コマンドによるDNSクエリ実行結果(ubuntu:24.04 実測)

よく使う dig オプション

オプション 意味 使い所
@127.0.0.1 問い合わせ先DNSサーバーを指定 ローカルBIND9に直接問い合わせる
+noall +answer 回答セクションのみ表示 結果だけ見たいとき(最もよく使う)
+short IPアドレスや値のみ出力 スクリプトで使うとき
-x 逆引き(PTR)クエリ dig -x 203.0.113.1 で逆引き確認
+trace ルートから順に追跡 委任(delegation)の確認・デバッグ

よくあるエラーと解決策

① named-checkzone が「no SOA RR found」を返す

エラーメッセージ

zone example.test/IN: has no SOA record または dns_master_load: /etc/bind/zones/db.example.test:1: no SOA RR found

ゾーンファイルの最初のレコードが SOA でなければなりません。また、SOA レコードの管理者メールアドレス(admin.example.test.)は @. に置き換えた形式です。末尾のドットも必須です。

② 「zone file has no NS records」エラー

ゾーンファイルに NS レコードが含まれていないか、NS レコードで参照しているホスト名(ns1.example.test.)に対応する A レコードがないと発生します。NS と A レコードがセットで必要です。

③ dig で REFUSED が返る




ubuntu@linuxlab: ~
$ dig @127.0.0.1 example.com A +short
;; communications error to 127.0.0.1#53: connection refused

これは recursion no; 設定で、自分が権威を持たないドメイン(example.com)への問い合わせを拒否している正常な動作です。権威を持つゾーンだけに答える設計になっています。

④ シリアル番号を更新し忘れてスレーブが古いデータを返す

ゾーンファイルを変更したときに Serial 番号を増やし忘れると、スレーブサーバーは「変更なし」と判断してゾーン転送を行いません。Serial は 20260614012026061402(同日2回目)のように必ず増やしてください。

⑤ ポート53のファイアウォール設定

外部からアクセスできない場合は UFW の設定を確認します。




ubuntu@linuxlab: ~
$ sudo ufw allow 53/tcp
$ sudo ufw allow 53/udp
Rules updated
$ sudo ufw status | grep 53
53/tcp ALLOW Anywhere
53/udp ALLOW Anywhere

まとめ

Ubuntu 24.04 LTS での BIND9 権威DNSサーバー構築を、実際にDockerコンテナで動かした結果をもとに解説しました。

  • Ubuntu 24.04 に apt でインストールされる BIND のバージョンは 9.18.39-0ubuntu0.24.04.5(2026-06-13 実測)
  • 設定ファイルは named.conf.optionsnamed.conf.local の2ファイルだけ編集すればよい
  • ゾーンファイルの末尾ドット(FQDN の .)と Serial 番号の更新が最大のつまりポイント
  • named-checkconfnamed-checkzone で起動前に設定ミスを検出できる
  • dig @127.0.0.1 でローカルDNSに直接問い合わせて A・MX・NS・PTR・SOA 全レコードの動作を確認できる

DNS設定は一度動かすとなかなか触らない部分ですが、ゾーンファイルの構造とレコードの種類を理解しておくと、メールサーバーやLet’s Encryptの認証設定(DNS-01 チャレンジ)でも迷わなくなります。本格的にVPSでサーバーを運用するなら、ネームサーバーをVPSで自前管理することも選択肢の一つです。

コメント

タイトルとURLをコピーしました