Loading
BLOG 開発者ブログ

2020年12月9日

初歩から解説!BINDでシンプルDNSサーバー構築【構築編】

なかなか理解するのが難しいDNSサーバーについて、前後編に分けて BIND を設定しながら解説します。

この記事は アイソルート Advent Calendar 2020 9日目の記事です。

 

 

こんにちは。日々検証環境を構築しているプラットフォームソリューショングループのsuzuki.koです。

前回の【用語編】ではDNSの仕組みと登場する用語について簡単に解説しました。

今回は【構築編】として、 BIND を実際に構築していきましょう!

 

初歩から解説!BINDでシンプルDNSサーバー構築【用語編】

 

目次

 

DNSサーバー構築

BINDでDNSサーバーの構築を行っていきます。

前提としてVMの立ち上げ、IP設定、GW設定、DNSクライアント設定などは完了し、pingによる疎通は確立していることとします。

 

動作環境

検証環境の作成にはESXi、OSはCentOSを利用します。各種バージョンは以下の通りです。

  • ハイパーバイザ
    • VMware ESXi 6.7.0 Update 2 (build-13006603)
  • DNSサーバー
    • CentOS Linux release 8.2.2004 (Core)
    • bind-libs-lite-9.11.13-6.el8_2.1.x86_64
  • NTPサーバー
    • CentOS Linux release 8.2.2004 (Core)
    • chrony-3.5-1.el8.x86_64
  • Client (NTPを利用)
    • CentOS Linux release 8.2.2004 (Core)
    • chrony-3.5-1.el8.x86_64
  • 仮想ルーター
    • VyOS 1.3-rolling-202002180217

 

ネットワーク構成

今回のネットワーク構成はこちらです。

少し実践的な内容の構成にしています。

 

 

そして

  • Step1: NTPサーバー (192.168.20.200) からインターネット上の上位NTPサーバー(2.centos.pool.ntp.org) への 再帰問い合わせ 成功。
  • Step2: Client (192.168.10.10) から NTPサーバー (192.168.20.200) に対して 非再帰的な名前解決 の成功。

というところを目標に構築していこうと思います。

 

今回動作確認に利用する NTPサーバー 仮想ルーター に関しては別の記事にて解説を行っていますので、

気になる方はそちらも確認してみてください。

 

たった3行編集!ChronyでシンプルNTPサーバー構築

ESXi内のルーティングに必須!VyOSで仮想ルーター構築

 

インストール

ではさっそくBINDを構築していきましょう。

CentOSにBINDのインストールを行います。

yumからインストールできます。

$ yum install bind

 

Firewalld

Firewalldを編集しておきます。

FirewalldとはCentOSの標準ファイアウォール機能で、systemctl (システムコントロール) コマンドで操作することができます。

これが 初期状態で有効 であるため、そのままにしておくとフィルタリングが働いてしまいます。

設定を無効にするか、

$ systemctl stop firewalld

DNSの通信を許可しておいてください。

$ firewall-cmd --add-service=dns
$ firewall-cmd --add-service=dns --permanent

 

BINDのステータス確認

BINDを起動させ、ステータスを確認してみます。

BINDはsystemctlコマンドで named を指定して操作を行います。

$ systemctl start named
$ systemctl status named

● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2020-12-01 14:22:52 EST; 5s ago

  Process: 1200865 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 1200862 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS)
 Main PID: 1200867 (named)
    Tasks: 4 (limit: 11129)
   Memory: 58.0M
   CGroup: /system.slice/named.service
           mq1200867 /usr/sbin/named -u named -c /etc/named.conf
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './DNSKEY/IN': 2001:500:1::53#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './NS/IN': 2001:500:1::53#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './DNSKEY/IN': 2001:500:2::c#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './NS/IN': 2001:500:2::c#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './DNSKEY/IN': 2001:503:c27::2:30#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './NS/IN': 2001:503:c27::2:30#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './DNSKEY/IN': 2001:500:2d::d#53
Dec 01 14:22:52 dns named[1200867]: network unreachable resolving './DNSKEY/IN': 2001:500:1::53#53
Dec 01 14:22:52 dns named[1200867]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Dec 01 14:22:52 dns named[1200867]: resolver priming query complete

誤った設定を入れたりするとここにエラーが吐き出されます。

 

初期設定確認

初期状態の設定を確認してみましょう。

設定ファイルは /etc/named.conf にあります。

 

初期config (※ダブルクリックすると全文が確認できます。)

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
        listen-on port 53 { 127.0.0.1; };
        listen-on-v6 port 53 { ::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     { localhost; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        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";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

 

再帰問い合わせ

  • Step1: NTPサーバー (192.168.20.200) からインターネット上の上位NTPサーバー(2.centos.pool.ntp.org) への 再帰問い合わせ 成功。

となるように構築を行います。

 

 

設定ファイルの /etc/named.conf を編集していきましょう。

編集するのは次の4箇所です。

 

config (※ダブルクリックすると全文が確認できます。)

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
        listen-on port 53 { 127.0.0.1; 192.168.20.100;};
        listen-on-v6 port 53 { ::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     { localhost; 192.168.0.0/16;};
        forwarders      { 8.8.8.8; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        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";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

 

  • listen-on port 53
    • LISTENするIPアドレスを指定します。
      自身のIPアドレスを追記しています。
  • allow-query
    • 問い合わせを受け付けるネットワークを制限します。
      今回はClientのネットワークも含めた192.168.0.0/16で許可します。
  • forwarders
    • 再帰問い合わせ先を指定します。
      GoogleのパブリックDNSサーバーを指定します。
  • recursion
    • 再帰問い合わせ機能を利用するかを記述します。
      利用する場合は yes , 利用しない場合は no と記述します。

 

DNSサーバーを再起動して設定を反映させます。

$ systemctl restart named

 

動作確認

NTPサーバー(Chrony) を使って動作確認を行います。

 

まずは getentコマンド で名前解決が成功するか確認してみます。

※ちなみに nslookupコマンド はCentOS8では非推奨らしいです。知らなかった。

$ getent hosts 2.centos.pool.ntp.org

2a01:4f8:211:2816:71c:7ac:71c:7ac 2.centos.pool.ntp.org
2402:1f00:8000:800::da1 2.centos.pool.ntp.org
2001:41d0:701:1100::285d 2.centos.pool.ntp.org
2a01:4f9:2b:1ac5::58 2.centos.pool.ntp.org

2.centos.pool.ntp.org というFQDNがIPアドレス(v6ですが)に変換されているのが確認できますね!

 

では次に FQDNで時刻同期 させてみましょう。

NTPサーバーの /etc/chrony.conf を編集します。(※ダブルクリックすると全文が確認できます。)

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool 2.centos.pool.ntp.org iburst

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift

# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3

# Enable kernel synchronization of the real-time clock (RTC).
rtcsync

# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *

# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2

# Allow NTP client access from local network.
#allow 192.168.0.0/16

# Serve time even if not synchronized to a time source.
#local stratum 10

# Specify file containing keys for NTP authentication.
keyfile /etc/chrony.keys

# Get TAI-UTC offset and leap seconds from the system tz database.
leapsectz right/UTC

# Specify directory for log files.
logdir /var/log/chrony

# Select which information is logged.
#log measurements statistics tracking

Chronyを再起動させます。

$ systemctl restart chronyd

 

時刻同期のステータスを確認します。

$ chronyc sources

210 Number of sources = 4
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* a7ccbf33-b39e-4c87-af35->     2   6    77    22  +5663us[+4869us] +/-  165ms
^+ unifi.it-risch.de             2   6    77    22  +8136us[+7342us] +/-  137ms
^+ 193.104.228.123               3   6    77    21    -16ms[  -16ms] +/-  182ms
^+ customer-212-237-100-250>     2   6    77    20   +338us[ +338us] +/-  154ms

IPアドレスの横に「*」があるので無事に FQDNを名前解決 した上で同期が完了していますね!

 

非再帰問い合わせ

  • Step2: Client (192.168.10.10) から NTPサーバー (192.168.20.200) に対して 非再帰的な名前解決 の成功。

となるように構築を行います。

今回は ntp.local 192.168.20.200 と解決されるように設定します。

 

 

まずconfigファイルでzoneを定義します。

 

config (※ダブルクリックすると全文が確認できます。)

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

zone "local" IN {
       file "local.zone";
       type master;
};

options {
        listen-on port 53 { 127.0.0.1; 192.168.20.100;};
        listen-on-v6 port 53 { ::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     { localhost; 192.168.0.0/16;};
        forwarders      { 8.8.8.8; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        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";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

 

  • zone “ゾーン名” IN
    • この記述でゾーンについて定義しています。
      今回はlocalゾーンを定義します。
  • file
    • 名前を引くための情報がどのファイルに記載してるかを示しています。
      今回は local.zone というファイルを作成してそこに記述します。
  • type
    • DNSのタイプを指定します。
      masterでプライマリーサーバ、slaveでセカンダリーサーバ、hintでキャッシュサーバとなります。
      今回はプライマリサーバーに指定します。
  • directory
    • ゾーンを定義するファイルの配置場所を記述します。
      /var/namedを指定しているので、/var/named/local.zone となるようにファイルを配置すればいいということになります。

 

次に /var/named/local.zone を作成し、その中で解決したいFQDNに関するレコードを書いていきます。

 

/var/named/local.zone

$ORIGIN local.
$TTL      86400
@         IN       SOA     dns.local. suzuki.ko.mail.add.jp. (
                                        2020120900 ; Serial
                                        28800      ; Refresh
                                        14400      ; Retry
                                        3600000    ; Expire
                                        86400 )    ; Minimum
          IN       NS      dns.local.
dns       IN       A       192.168.20.100
ntp       IN       A       192.168.20.200

 

  • $ORIGIN
    • このファイルで利用されるドメインを記述します。
      ここでは local. を指定しているため、11行目で記述されている ntp は ntp.local. と認識して処理されます。
      また3行目にあるように @ と記述すると local. として処理されます。
  • $TTL
    • 再帰問い合わせを行った際にキャッシングする時間を秒で記述します。
      今回は利用しないのですが、お決まりの記述ですので残しておきます。
  • SOAレコード
    • この部分にDNSサーバー名と管理者のメールアドレス、DNSサーバーの各種設定を記述します。
      DNSサーバー名は9行目のNSで定義したもの、メールアドレスには適当なものを記述しています。
      注意点として、完全なFQDNで記述する必要があり、また @ は使えないため代わりにピリオド(.)で記述しなければなりません。
  • SOA 内パラメータ
    • SOA 内で記載されている各種パラメータは以下の通りです。
      • Serial:適当なシリアルナンバーを10桁で記述します。
      • Refresh:リフレッシュ値といい、セカンダリサーバーへのゾーン情報の転送間隔を記述します。
      • Retry:リフレッシュが失敗したときの再送間隔を記述します。
      • Expire:リフレッシュが失敗している時のセカンダリサーバの有効時間を記述します。
      • Minimum:存在しないドメイン名に対して「存在しない」という情報(=ネガティブキャッシュ)を保持する時間を記述します。
  • NSレコード
    • 9行目のNSレコードではこのゾーンを管理するDNSサーバーを定義します。
      セカンダリサーバーを定義するときNSレコードを追加で記述します。
  • Aレコード
    • 10-11行目のAレコードでホストとIPとの対応関係の定義を行ないます。
      ntp.local からNTPサーバのIPである 192.168.20.200 が引けるように記述しています。
      またDNSサーバー自身のIPについても記述する必要があります。

 

DNSサーバーを再起動して設定を反映させましょう。

$ systemctl restart named

 

動作確認

では同じ手順で NTPサーバー(Chrony) を使って動作確認を行います。

 

まずは getentコマンド で名前解決が成功するか確認してみます。

$ getent hosts ntp.local
192.168.20.200    ntp.local

ntp.local というFQDNが 192.168.20.200 に変換されているのが確認できます!

 

では次に FQDNで時刻同期 させてみましょう。

NTPサーバーの /etc/chrony.conf を編集します。(※ダブルクリックすると全文が確認できます。)

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#pool 2.centos.pool.ntp.org iburst
server ntp.local iburst

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift

# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3

# Enable kernel synchronization of the real-time clock (RTC).
rtcsync

# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *

# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2

# Allow NTP client access from local network.
#allow 192.168.0.0/16

# Serve time even if not synchronized to a time source.
#local stratum 10

# Specify file containing keys for NTP authentication.
keyfile /etc/chrony.keys

# Get TAI-UTC offset and leap seconds from the system tz database.
leapsectz right/UTC

# Specify directory for log files.
logdir /var/log/chrony

# Select which information is logged.
#log measurements statistics tracking

Chronyを再起動させます。

$ systemctl restart chronyd

 

時刻同期のステータスを確認します。

$ chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* 192.168.20.200               10  10   377   733    -11us[  -12us] +/-  104us

こちらも無事に FQDNを名前解決 した上で同期できていますね!成功です!

 
 

さいごに

今回は【用語編】【構築編】の2回にわたってDNSサーバーの構築について解説しました。

BINDの構築は難しいですが、やはりきちんと動いてくれると嬉しいですね。

この基本的な設定を土台にさらに応用的なDNSサーバーを構築していけるようにしていきたいと思います。

DNSの基礎について解説した【用語編】についてはこちらになりますので、ぜひ確認してみてください。

 

初歩から解説!BINDでシンプルDNSサーバー構築【用語編】

 

明日の記事は maruoka.n さんによる 理想のテレワーク環境をWVDで実現です、お楽しみに!

 
 
 

suzuki.koのブログ