最近DNSサーバを触る機会が出てきたので、勉強がてらBINDでキャッシュDNSサーバの構築をしてみた。
DNSの概要と構成
DNSサーバは大きく2種類に分類できる。
・キャッシュサーバ:クライアントから再帰問い合わせを受け付け、名前解決を代行する。自分自身はドメインを管理しない。
・コンテンツサーバ:自分の管理しているドメインについて、問い合わせの回答を行う。
以下の図は、LANに配置したDNSキャッシュサーバを使用してwww.google.comの名前解決を行った際の図。クライアントは再帰問い合わせのリクエストをDNSキャッシュサーバに投げ、同サーバが代行して反復問い合わせを行う。
ただし、上記の例だとDNSキャッシュサーバが直接ルートDNSサーバに問い合わせを行うこととなる。全世界中のDNSキャッシュサーバが同様のことを行うとルートDNSサーバへの負荷が高まってしまうので、通常は行わないのがマナーである。
そのため、以下のようにISP契約時に提供されるDNSサーバにDNSキャッシュサーバからの問い合わせを転送(フォワード)する。
今回構築するのは、図中でDNSキャッシュサーバ(LAN)。
要件
以下の要件でDNSキャッシュサーバを構築する。
OS:CentOS7.1
DNSソフトウェア:BIND
DNSキャッシュサーバ(LAN、今回構築対象)のIPアドレス:192.168.56.10
DNSキャッシュサーバ(IPS)のIPアドレス:192.168.56.1(自宅のブロードバンドルータをIPS DNSサーバ役に代用)
DNSキャッシュサーバ(LAN)への問い合わせを許可するクライアントセグメント:192.168.56.0/24
インストールと設定
まだBINDがインストールされていない場合は、以下コマンドでBINDをインストールする。
yum -y install bind bind-utils
インストール後、以下のように設定ファイルを編集する。コメントを入れていない箇所は、デフォルトで入っている設定。
/etc/named.conf
# アクセス制御。trustというグループに属するIPアドレスを定義する。 acl "trust" { 192.168.56.0/24; 127.0.0.1; }; options { # UDP53でDNSクエリを受け付ける自分自身のIPアドレス listen-on port 53 { 127.0.0.1; 192.168.56.203; }; # IPv6は使わないのでnone listen-on-v6 port 53 { none; }; 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"; # DNSクエリはaclで設定した送信元のみ許可 allow-query { trust; }; allow-query-cache { trust; }; # 再帰問い合わせもaclで問い合わせした送信元のみ許可 recursion yes; allow-recursion { trust; }; # DNS問い合わせの転送先 # 本来はISPのDNSサーバ指定すべきだが、今回は自宅ブロードバンドルータで代用する forwarders { 192.168.56.1; }; # 問い合わせの転送に失敗した場合は自分自身で名前解決を行う # 問い合わせ転送に失敗した際名前解決をあきらめる場合はonlyを設定する forward first; dnssec-enable yes; dnssec-validation yes; bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { # デフォルトの設定。使わないので消してもよいかも channel default_debug { file "data/named.run"; severity dynamic; }; # DNSクエリログ用の出力設定 channel query-log { # 以下すべてのチャネルで3世代10Mごとにログローテーションを行う file "/var/log/named/query.log" versions 3 size 10M; severity info; print-category yes; print-severity yes; print-time yes; }; # ゾーン転送ログ用の出力設定 channel xfer-log { file "/var/log/named/xfer.log" versions 3 size 10M; severity info; print-category yes; print-severity yes; print-time yes; }; # 上記以外の種類のエラーログ用の出力設定 channel error-log { file "/var/log/named/error.log" versions 3 size 10M; severity error; print-category yes; print-severity yes; print-time yes; }; # ログ種別ごとの出力先設定指定 category queries { query-log; }; category xfer-in { xfer-log; }; category xfer-out { xfer-log; }; category default { error-log; }; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key";
次に、BINDのログ出力先ディレクトリを作成する。
mkdir /var/log/named chown named:named /var/log/named
named-checkconfで設定に問題無いことを確認したら、namedを起動する。
named-checkconf systemctl start named systemctl status named
動作確認
構築したDNSサーバで名前解決の動作確認を行う。
名前解決の問い合わせ先を自分自身にしたいので、以下設定を行う。
vim /etc/resolv.conf # ↓nameserverを自分自身のアドレスに変更 nameserver 192.168.56.10
digでYahooのURLを名前解決してみる。
「QUESTION SECTION」では、「www.yahoo.co.jp.」に対するAレコードの値を問い合わせていることがわかる。
「ANSWER SECTION」では、「www.yahoo.co.jp. 」の別名が「www.g.yahoo.co.jp.」で、そのIPアドレスが4つにDNSラウンドロビンされていることがわかる。流石商用サービスだけあって念入りに冗長化されている。
ちなみに、「ANSWER SECTION」でFQDNの横に表示されている数字はDNSキャッシュサーバがキャッシュしている情報の有効期限である。何回かdigコマンドを実行すると値が減っていき、0になると再度名前解決が行われる。
dig www.yahoo.co.jp ; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> www.yahoo.co.jp ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46801 ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 8, ADDITIONAL: 16 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.yahoo.co.jp. IN A ;; ANSWER SECTION: www.yahoo.co.jp. 426 IN CNAME www.g.yahoo.co.jp. www.g.yahoo.co.jp. 50 IN A 183.79.198.240 www.g.yahoo.co.jp. 50 IN A 183.79.197.242 www.g.yahoo.co.jp. 50 IN A 183.79.71.173 www.g.yahoo.co.jp. 50 IN A 183.79.23.158 ~略~