DNSキャッシュサーバを構築する(CentOS8 + BIND9)
検証のため仮想環境にてサーバを複数構築する必要となったのだが、その準備として各サーバが使用するDNSとDHCPサーバを構築する必要がある。最近ではDNSは Ansible で構築することが多かったが構成管理するほどではなく設定変更もそれほど発生しないことから今回は久しぶりに手動で構築することにした。
構築環境としてOSはCentOS 8 を使用。DNSの仕様だが今回はゾーン情報は持たないDNSクエリーのみを処理するDNSキャッシュサーバをBIND 構築することにする。なおBINDデーモンの権限を奪われてもセキュリティリスクを限定的にできるchroot環境でDNSを動作させたいと思う。
BIND インストール
yumからbindをインストールする。その他 chroot環境にできるbind-chrootもインストールする。インストール後、各設定ファイルをchroot環境のディレクトリ (/var/named/chroot/{etc,var}) に自動的に作成してもらうためBINDデーモンを起動する。なお systemctl による起動では、chrootの場合 named でなく named-chroot を指定する必要となるので注意。
yum install bind bind-chroot bind-utils
systemctl start named-chroot # /var/named/chroot/{etc,var}/named 配下にファイルが作られる
設定ファイル作成
DNSキャッシュサーバとして動作させるために必要な設定ファイルは named.conf ぐらいだ。ただログは細かくファイルを分けて出力させたいためログの設定箇所は外部ファイルとして作成して named.conf から include で読み込むようにする。
named.conf の作成
設定ファイルはchroot環境だと /var/named/chroot/etc/named.conf に設定ファイルがあるのでこれをvimで開いて下記の通り修正した。以下に簡単に変更点を記載する。
-
listen-on と listen-on-v6 でこのサーバに割り当てたIPアドレスを指定する。環境によってはIPv6がないと思うので listen-on-v6 は不要だ。
-
DNS問い合わせを受け付けるソースIPは特に制限を設けないので allow-query では any を指定している。ソースIPで制限を設けたい場合は 192.168.0.0/24; 等指定する。
-
クエリに対するレスポンスでバージョン情報を秘匿化するため version で適当な文字列を加えた。これでBINDのバージョンを知られることがなくなり多少はセキュリティ強化ができる。
-
logging の設定は長くなるので別ファイル logging.conf として include で読み込むようにした。
options {
listen-on port 53 { <<IPv6 Address>>; }; // 説明1
listen-on-v6 port 53 { <<IPv6 Address>>; }; // 説明1
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
allow-query { any; }; // 説明2
version "himitsu"; // 説明3
recursion yes;
dnssec-enable yes;
dnssec-validation yes;
managed-keys-directory "/var/named/dynamic";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
include "/etc/crypto-policies/back-ends/bind.config";
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
include "/etc/named/logging.conf"; // 説明4
logging.conf の作成
ロギング設定は named.conf に書かず、別ファイルに切り出して設定する。簡単に説明すると各channelセクションで出力させたいログを指定している。出力先の他にログローテーションの設定もここに指定することも可能だ。設定内容を見ればなんとなくわかると思うが詳細は他のサイトで調べてほしい。
ロギング設定ファイルは /var/named/chroot/etc/named/logging.conf に作成した。
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
channel "log_default" {
file "/var/log/named.log" versions 7 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel "log_security" {
file "/var/log/security.log" versions 7 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel "log_queries" {
file "/var/log/queries.log" versions 7 size 100m;
severity info;
print-time yes;
print-category yes;
};
channel "log_xfer" {
file "/var/log/xfer.log" versions 7 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel "log_resolver" {
file "/var/log/resolv.log" versions 7 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel "default_syslog" {
syslog local0;
severity info;
print-category yes;
};
category default {
"log_default";
"default_syslog";
};
category security {
"log_security";
"default_syslog";
};
category client {
"log_security";
"default_syslog";
};
category queries {
"log_queries";
};
category xfer-in {
"log_xfer";
"default_syslog";
};
category xfer-out {
"log_xfer";
"default_syslog";
};
category resolver {
"log_resolver";
"default_syslog";
};
};
BIND 再起動と自動起動の有効化
設定ファイルを修正したのでBINDデーモンを再起動する。
systemctl restart named-chroot
再起動後、正常に起動されたか下記コマンドで確認しよう。起動が失敗していれば設定ファイルに何かしら誤りがある。
systemctl status named-chroot
またOSが起動した際に自動的にデーモンも起動されるように自動起動を有効化しておく。
systemctl enable named-chroot
ファイアウォール設定
これでDNSの設定は完了したがこのままではクライアントからの名前解決のリクエストがファイアウォール(finrewalld)でブロックされてしまう。よってDNSのポートである 53/tcp と 53/udp のポートを受け付けるように firewalld を設定する。なおUDPの53番ポートは主にDNSクライアント(リゾルバ)がDNSサーバに問い合わせする際に使用するものだ。TCPの方はゾーン転送の際に使用するらしい。今回の要件ではゾーン転送は使用しないが合わせて設定した。
firewalld の設定は firewall-cmd コマンドを使用する。オプションとして –add-service で dns を指定することで 53/tcp と 53/udp のポート番号を指定したことになる。 –permanent を指定すれば永続的に設定されるのでサーバ再起動しても設定が消えることがない。
firewall-cmd --add-service=dns --zone=public --permanent
設定しただけでは反映されないので下記コマンドで設定をリロードさせる。
firewall-cmd --reload
設定が反映されたかは下記コマンドで確認できる。
firewall-cmd --list-services
firewall-cmd --list-all
これでサーバはDNSキャッシュサーバとして動作しているはずだ。dig コマンドでDNSクエリを投げて名前解決がされるか試してみよう。
<<DNS Server IP>>
はDNSサーバのIPアドレスを指定する。
dig @<<DNS Server IP>> www.google.com. a