DNS サーバの設定
BIND 9 DNS サーバ構築手順。view 機能で内部向けと外部向けの名前解決を分離する設定。ゾーンファイルと named.conf の記述方法。rndc と systemd による管理操作。dig などによる動作確認。UFW と AppArmor によるアクセス制御。
BIND DNS サーバを動かし、順引き、逆引きができるようにする。
【関連する外部ページ】: Ubuntu Server ドキュメント「Domain Name Service (DNS)」: https://ubuntu.com/server/docs/how-to/networking/install-dns/
【関連する外部ページ】: BIND 9 Administrator Reference Manual: https://bind9.readthedocs.io/en/latest/
設定内容
設定内容は次の通りである。
-
rndc(Remote Name Daemon Controller): 使用する - ルートサーバに関する情報ファイル:
/usr/share/dns/root.hints(dns-root-dataパッケージが提供し、/etc/bind/named.conf.default-zonesから参照される) - ローカルホストのゾーンファイル:
/etc/bind/db.local,/etc/bind/db.127(パッケージが提供する) - ゾーンの配布における外部向きと内部向きの区別: 行う(
view機能を使用)- 内部向きのゾーンファイル名:
/etc/bind/zones/db.zone,/etc/bind/zones/db.rev - 外部向きのゾーンファイル名:
/etc/bind/zones/public.zone,/etc/bind/zones/public.rev - 外部向きのゾーンファイルに記述するホスト: 「上流の DNS サーバ」, DNS サーバ兼 MX, Web サーバの 3 つのみ
- 内部向きのゾーンファイル名:
- 統計情報など:
/var/cache/bind/cache_dump.db,/var/cache/bind/named_stats.txt - ログ出力ファイル:
/var/log/named/named.log,/var/log/named/security.log
Ubuntu 24.04 LTS の bind9 パッケージでのディレクトリ構成は次の通りである。
/etc/bind 設定ファイルの置き場 +-- named.conf 主設定ファイル(各ファイルを include する) +-- named.conf.options 全体のオプション +-- named.conf.local 自分で定義するゾーンや view +-- named.conf.default-zones localhost、その逆引き、ルートヒント +-- rndc.key rndc 用の鍵 +-- zones 本手順で作成するゾーンファイルの置き場 /var/cache/bind named が書き込む作業用ディレクトリ /var/log/named 本手順で作成するログの置き場
事前に調べておく事項
DNS サーバ構築に際して、以下の事項を確認しておく。
- DNS サーバ兼 MX のホスト名
(以下、ホスト名は「
dnsmail」のように記述する) - DNS サーバ兼 MX の IP アドレス (以下、「
XXX.YYY.ZZZ.160」のように記述する)。 - Web サーバのホスト名
(以下、ホスト名は「
www」のように記述する) - Web サーバの IP アドレス (以下、「
XXX.YYY.ZZZ.167」のように記述する)。 - DNS サーバ兼 MX がある「内部」のネットワークアドレス
(以下、ネットワークアドレスは「
XXX.YYY.ZZZ」のように記述する) - DNS ドメイン名 (NIS ドメイン名とは別物であるため混同しないこと)
(以下、DNS ドメイン名は「
mydomain.hoge.com」と記述する) - 上流の DNS サーバの IP アドレス
(以下、上流の DNS サーバの IP アドレスは「
AAA.BBB.CCC.10」と記述する)
DNS サーバソフトのインストール
- 時刻あわせ
時刻が大きくずれていると DNSSEC の検証などが失敗する。Ubuntu 24.04 LTS では
systemd-timesyncdが時刻を同期する。同期状況を確認する。timedatectl status
「System clock synchronized: yes」と表示されることを確認する。
- インストール
bind9がサーバ本体、bind9-utilsがnamed-checkconf,named-checkzone,rndc、bind9-dnsutilsがdig,host,nslookupを提供する。sudo apt update sudo apt install bind9 bind9-utils bind9-dnsutils
- サービス名の確認
Ubuntu 24.04 LTS では、サービス名は
named.serviceである(bind9.serviceはその別名として使える)。実行ユーザはbindである。systemctl status named.service
-
systemd-resolvedとの共存の確認Ubuntu 24.04 LTS では
systemd-resolvedが127.0.0.53:53で待ち受ける。namedが全アドレスの 53 番ポートで待ち受けるとポートが衝突することがある。衝突する場合は、systemd-resolvedのスタブリスナを止める。sudo vi /etc/systemd/resolved.conf # [Resolve] セクションに次の行を設定する ---------------------------------------------------------------------------- DNSStubListener=no ---------------------------------------------------------------------------- sudo systemctl restart systemd-resolved
仮のゾーンファイルの作成とチェック
public.zone, public.rev, db.zone, db.rev を作成する。次に named.conf.local を設定して、内部向けの view と外部向けの view を定義する。その後、DNS サーバを起動して動作をチェックする。
まず、ゾーンファイルを置くディレクトリを作成する。
sudo mkdir -p /etc/bind/zones
正引き
/etc/bind/zones/public.zone, /etc/bind/zones/db.zone は仮に次のように設定する。ドメイン名の末尾の「.」は必要である。Serial は「YYYYMMDDNN」(更新した年月日+その日の更新回数)の形式で設定する。
cd /etc/bind/zones sudo vi public.zone # 以下のように設定 ---------------------------------------------------------------------------- $TTL 86400 @ IN SOA dnsmail.mydomain.hoge.com. root.mydomain.hoge.com. ( 2024073001 ; Serial 28800 ; Refresh 14400 ; Retry 3600000 ; Expire 86400 ) ; Minimum IN NS dnsmail.mydomain.hoge.com. IN MX 10 dnsmail.mydomain.hoge.com. @ IN A XXX.YYY.ZZZ.160 dnsmail IN A XXX.YYY.ZZZ.160 www IN A XXX.YYY.ZZZ.167 hohoge IN A AAA.BBB.CCC.10 ---------------------------------------------------------------------------- sudo cp public.zone db.zone
逆引き
/etc/bind/zones/public.rev, /etc/bind/zones/db.rev は仮に次のように設定する。
cd /etc/bind/zones
sudo vi public.rev
# 以下のように設定
----------------------------------------------------------------------------
$TTL 86400
@ IN SOA dnsmail.mydomain.hoge.com. root.mydomain.hoge.com. (
2024073001 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS dnsmail.mydomain.hoge.com.
160 IN PTR dnsmail.mydomain.hoge.com.
167 IN PTR www.mydomain.hoge.com.
----------------------------------------------------------------------------
sudo cp public.rev db.rev
オーナとパーミッションの設定
ゾーンファイルは named の実行ユーザ bind が読めればよい。書き込み権限は与えない。
sudo chown -R root:bind /etc/bind/zones sudo chmod 750 /etc/bind/zones sudo chmod 640 /etc/bind/zones/*
named.conf の設定
view を使う場合、すべてのゾーンをいずれかの view の中に書く必要がある。そのため、/etc/bind/named.conf にある named.conf.default-zones の include をコメントアウトし、各 view の中で include する。
sudo vi /etc/bind/named.conf # 次の行をコメントアウトする ---------------------------------------------------------------------------- //include "/etc/bind/named.conf.default-zones"; ----------------------------------------------------------------------------
次に、全体のオプションを設定する。forwarders に上流の DNS サーバを設定し、統計情報などの出力先を設定する。
sudo vi /etc/bind/named.conf.options
# options ブロックに次を設定
----------------------------------------------------------------------------
options {
directory "/var/cache/bind";
forwarders { AAA.BBB.CCC.10; };
dump-file "/var/cache/bind/cache_dump.db";
statistics-file "/var/cache/bind/named_stats.txt";
dnssec-validation auto;
listen-on-v6 { any; };
};
----------------------------------------------------------------------------
次に、内部向けと外部向けの view、およびログ出力を設定する。match-clients により、問い合わせ元の IP アドレスで参照するゾーンが切り替わる。view は上から順に評価されるため、内部向けを先に書く。
sudo vi /etc/bind/named.conf.local
# 次のように設定
----------------------------------------------------------------------------
acl internal-net {
127.0.0.1;
XXX.YYY.ZZZ.0/24;
};
view "internal" {
match-clients { internal-net; };
recursion yes;
zone "mydomain.hoge.com" {
type master;
file "/etc/bind/zones/db.zone";
};
zone "ZZZ.YYY.XXX.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.rev";
};
include "/etc/bind/named.conf.default-zones";
};
view "external" {
match-clients { any; };
recursion no;
zone "mydomain.hoge.com" {
type master;
file "/etc/bind/zones/public.zone";
};
zone "ZZZ.YYY.XXX.in-addr.arpa" {
type master;
file "/etc/bind/zones/public.rev";
};
};
logging {
channel named_log {
file "/var/log/named/named.log" versions 3 size 10m;
severity info;
print-time yes;
};
channel security_log {
file "/var/log/named/security.log" versions 3 size 10m;
severity info;
print-time yes;
};
category default { named_log; };
category security { security_log; };
};
----------------------------------------------------------------------------
ログの出力先ディレクトリを作成し、named が書き込めるようにする。
sudo mkdir -p /var/log/named sudo chown bind:bind /var/log/named
チェック
設定ファイルの書き間違いを下記の手順でチェックする。
- チェックツールを使って、
named.confの内容をチェックする-zを付けると、設定されているゾーンファイルの読み込みまで行う。エラーが出たら、named.conf.options,named.conf.localを書き直す。named-checkconf -z /etc/bind/named.conf
- チェックツールで、ゾーンファイルを個別にチェックする
named-checkzone <ゾーン名> <ゾーンファイルパス>の形式で使用する。エラーが出たら、ゾーンファイルを書き直す。# 正引きゾーンのチェックにはゾーン名 (ドメイン名) を指定する named-checkzone mydomain.hoge.com /etc/bind/zones/public.zone named-checkzone mydomain.hoge.com /etc/bind/zones/db.zone # 逆引きゾーンのチェックには逆引きゾーン名 (.in-addr.arpa) を指定する named-checkzone ZZZ.YYY.XXX.in-addr.arpa /etc/bind/zones/public.rev named-checkzone ZZZ.YYY.XXX.in-addr.arpa /etc/bind/zones/db.rev
- 起動チェック (デバッグモード)
起動チェックのため、最初はフォアグラウンドのデバッグモードで起動してみる。起動の前に
namedの停止を行う。エラーメッセージが端末に表示される。確認できたら「Ctrl+C」で終了する。sudo systemctl stop named.service sudo named -u bind -g -d 1
参考:
-
-u:namedの実行ユーザ (Ubuntu 24.04 LTS ではbind) -
-g: フォアグラウンドで実行し、ログを標準エラー出力に出す -
-d 1: デバッグレベルの指定
-
- DNS サーバの起動
下記の手順で、DNS サーバを起動する。起動時にエラーが出たら、関係する設定ファイル (ここでは
named.conf.options,named.conf.local,public.zone,public.rev,db.zone,db.rev) を見直し、もう 1 度再起動する。sudo systemctl restart named.service sudo systemctl enable named.service systemctl status named.service
- ログの確認
systemdのログと、設定したログファイルの両方を確認する。/var/log/namedにnamed.log,security.logの 2 つのログファイルが作成されるため確認し、エラーが無いことを確認する。journalctl -u named.service -n 50 sudo ls -la /var/log/named sudo tail /var/log/named/named.log
-
rndcとの通信ができていることのチェックsudo rndc status # エラーが無く、「server is up and running」という行が出てくることを確認する
- ファイアウォールの設定
53/UDP は通常の名前解決に使われ、53/TCP は 512 バイトを超える応答やゾーン転送に使われる。
bind9パッケージは UFW 用のアプリケーションプロファイルを提供する。53/UDP は全体に開き、53/TCP はXXX.YYY.ZZZ.*のネットワークのみに許可する例を示す。sudo ufw allow 53/udp sudo ufw allow from XXX.YYY.ZZZ.0/24 to any port 53 proto tcp sudo ufw status
rndc についての補足説明
rndc は named をローカルまたはリモートから制御するツールである。制御には共有鍵による認証を用いる。Ubuntu 24.04 LTS では、bind9 のインストール時に /etc/bind/rndc.key が生成され、/etc/bind/named.conf から読み込まれるため、そのまま使用できる。鍵を作り直す場合は rndc-confgen を使う。
アクセス制御と AppArmor に関する補足説明
Ubuntu 24.04 LTS の bind9 パッケージは chroot を構成せず、named プロセスの権限を AppArmor のプロファイル /etc/apparmor.d/usr.sbin.named で制限する。このプロファイルにより、named が読み書きできるファイルが /etc/bind, /var/cache/bind, /var/lib/bind, /var/log/named などに限定される。named が乗っ取られた場合の被害を、これらの範囲に抑制することが目的である。
プロファイルが有効であることは次のコマンドで確認する。
sudo aa-status | grep named
上記以外の場所にゾーンファイルやログを置くと、AppArmor により拒否されて named が起動しない。その場合は、/etc/apparmor.d/local/usr.sbin.named に読み書きを許可する行を追加し、sudo systemctl reload apparmor を実行する。
クライアント側の設定
DNS クライアントとしての設定についても確認しておく。
- 名前解決に使うサーバの確認
Ubuntu 24.04 LTS では
/etc/resolv.confはsystemd-resolvedが管理するため、実際に問い合わせ先となっているサーバはresolvectlで確認する。DNS がうまく動かないと思った時は、まずこれを確認する。resolvectl status cat /etc/resolv.conf
問い合わせ先を変更するときは、
netplanの設定ファイル (/etc/netplan/*.yaml) のnameserversに DNS サーバの IP アドレスを記述し、sudo netplan applyを実行する。 -
/etc/nsswitch.conf次のように、
hostsの行にdnsを含むこと。これにより、名前解決の際にhostsファイル、次にDNSを参照する順序が定義される。hosts: files dns
上記の設定後、MX, Web サーバの順引き、逆引きができることを確認する(下記の「演習項目」を参照すること)。
演習項目
設定した DNS サーバの動作確認方法について説明する。
dig, host, nslookup の使い方の練習
dig
dig は DNS の問い合わせに広く使われる標準的なツールである。
- 下記の手順で、正引きをテストする。
dig @<DNSサーバのIPアドレス> <調べたいホスト名>
- 下記の手順で、逆引きをテストする。
dig @<DNSサーバのIPアドレス> -x <調べたいIPアドレス>
-
チェック項目について述べる。
;; ->>HEADER<<- の部分で ・status: が NOERROR である。 status: はサーバからの応答の状態を表す。 NOERROR :DNSサーバが正常に応答したことを示す。 NXDOMAIN:問い合わせたドメインが存在しないことを示す。 SERVFAIL:DNSサーバが正しく応答しなかったことを示す。 ・flags: に qr, aa があるか確認する。内部マシンから dig をした場合は ra もあるはずである。 flags: には次の5つがある。 qr:クエリに対する回答であることを示す。 aa:回答が権限のある回答であることを示す。 tc:回答が長くて切り捨てられたことを示す。 ra:サーバが再帰可能であることを示す。 rd:再帰希望のフラグが設定されていることを示す。 ・ANSWER: が1以上であるか確認する。 ANSWER: は問い合わせに対する回答の数を示す。 ;; ANSWER SECTION: がゾーンファイルに設定した通りであるかどうかを確認する。
host
host は簡単な名前解決の確認に使う。
# 正引き host <調べたいホスト名> <DNSサーバのIPアドレス> # 逆引き host <調べたいIPアドレス> <DNSサーバのIPアドレス>
nslookup
nslookup は対話的に問い合わせ先を切り替えられる。dig と同じく bind9-dnsutils パッケージが提供する。
- 下記の手順で、ゾーンファイルに記述したホスト名と IP との対応をテストする。
nslookup <-- nslookup を起動 > server <DNSサーバのIPアドレス> <-- 問い合わせるDNSサーバを指定 // 正引きのテスト方法 > <ホスト名> <-- ゾーンファイルに記述したホスト名 Server: <DNSサーバのIPアドレス> Address: <DNSサーバのIPアドレス>#<ポート番号> Name: <ゾーンファイルに記述したホスト名> Address: <対応するIPアドレス> <-- ゾーンファイルに記述したIPが返れば良い
- 下記の手順で、逆引きをテストする。
> <IPアドレス> <-- 逆引きゾーンファイルに記述したIP Server: <DNSサーバのIPアドレス> Address: <DNSサーバのIPアドレス>#<ポート番号> <IPアドレスの逆順>.in-addr.arpa name = <対応するホスト名> <-- 逆引きゾーンファイルに記述したホスト名が FQDN形式で返れば良い
nslookup は exit で終了する。
ゾーンファイル db.zone, db.rev のメンテナンス
ゾーンファイル db.zone, db.rev のメンテナンス手順は以下の通りである (マシンの追加・削除を行う場合)。
- ゾーンファイルに変更を加える前に、バックアップを取得しておく。
cd /etc/bind/zones sudo cp db.zone db.zone.back20240730 <-- その日の日付 sudo cp db.rev db.rev.back20240730 <-- その日の日付
-
db.zoneの A レコードを追加・削除する。// Aレコードの記述例 hostname IN A XXX.YYY.ZZZ.200
-
db.revの PTR レコードを追加・削除する。// PTRレコードの記述例 200 IN PTR hostname.mydomain.hoge.com.
- SOA レコードのシリアル番号を更新する。
シリアル番号は
YYYYMMDDNN (例: 2024073001) "更新した年月日+その日の更新回数"
のように設定する。シリアル番号を増やすことで、セカンダリサーバがゾーンの更新を検知できるようになる。 - ゾーンファイルをチェックし、変更を反映させる。
named-checkzone mydomain.hoge.com /etc/bind/zones/db.zone named-checkzone ZZZ.YYY.XXX.in-addr.arpa /etc/bind/zones/db.rev sudo rndc reload
rndc 関係
- 設定ファイルとゾーンファイルを再読み込みする。キャッシュデータは保持される。
sudo rndc reload # ログファイルを見てエラーが無いことを確認する sudo tail /var/log/named/named.log
- キャッシュをファイルにダンプする。出力先は
named.conf.optionsのoptions中のdump-fileで定義する。出力先を定義していない場合は作業ディレクトリのnamed_dump.dbに出力される。sudo rndc dumpdb # 出力結果を確認 sudo cat /var/cache/bind/cache_dump.db
- キャッシュをすべてフラッシュする。
sudo rndc flush # キャッシュをファイルに出力してクリアされたことを確認する sudo rndc dumpdb sudo cat /var/cache/bind/cache_dump.db
- サーバの統計情報をファイルにダンプする。出力先は
named.conf.optionsのoptions中のstatistics-fileで定義する。出力先を定義していない場合は作業ディレクトリのnamed.statsに出力される。sudo rndc stats # 出力結果を確認 sudo cat /var/cache/bind/named_stats.txt
出力結果の意味について述べる。
success 問い合わせに成功したクエリー数である。 referral 問い合わせに対し参照となったクエリー数である。 nxrrset 問い合わせに対するレコード型が存在しなかったクエリー数である。 nxdomain 問い合わせに対するドメイン名やホスト名が存在しなかったクエリー数である。 recursion 再帰問い合わせを行ったクエリー数である。 failure エラーとなったクエリー数である。
- 問い合わせのログを一時的に取得する。
sudo rndc querylog on sudo tail -f /var/log/named/named.log sudo rndc querylog off
内部向けのゾーンと外部向けのゾーンが正しく動いていることの確認
内部ネットワークのクライアントと、外部ネットワークのクライアントから、それぞれ同じ名前を問い合わせ、返る内容が異なることを確認する。
- 内部ネットワーク (
XXX.YYY.ZZZ.0/24) のクライアントから問い合わせる。internalのviewが使われ、db.zoneに記述したホストが返る。dig @XXX.YYY.ZZZ.160 hostname.mydomain.hoge.com
- 外部ネットワークのクライアントから問い合わせる。
externalのviewが使われ、public.zoneに記述した 3 つのホスト以外は返らない。dig @XXX.YYY.ZZZ.160 hostname.mydomain.hoge.com dig @XXX.YYY.ZZZ.160 www.mydomain.hoge.com
- どちらの
viewが使われたかは、rndc querylog onを実行してからログを確認すると判別できる。sudo rndc querylog on sudo tail -f /var/log/named/named.log
以上の演習が済んだら、仮に設定されたゾーンファイルを本格的なものに書き換える。その後、DNS 管理コマンドについての練習及び DNS サーバの動作確認を再度行う。