RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

DNSサーバー 構築 入門編

はじめに

初めましてこんにちは!matsutairaです! 今回は、普段何気なく利用しているDNSサーバーというものにフォーカスし、実際にWebサーバー・DNSサーバーの構築を通してDNSサーバーとは何なのかをざっくり学べる内容となっております。「DNSサーバーってどんなもの?」「自分でDNSサーバーを構築してみたい!」という方々の力になれればと思います。 今回は初めて触る方向けの内容になっていますので、「DNSサーバーの構築方法だけ知りたい!」という方は目次からジャンプしていただければと思います。

手順の大まかな流れとしては、「ドメイン取得」 → 「各種サーバー構築」 → 「動作確認」です。
ドメインの取得は通常それなりのコストがかかりますが、お名前ドットコムであれば初回1年間は1円で利用することができる「.work」ドメインがあるため、最小限のコストに抑えることができます。また、ドメインの取得は個人・法人問わず、ホームページやメールアドレス、個人ブログで利用することができ、世界に一つだけのオリジナルであるという証明にもなります。
各種サーバーの構築は今回AWSを利用して作成していきます。AWSを利用するメリットとしては、初回1年間のみ無料で試すことができ、今回利用する範囲内であれば1年間無料で利用できます。(BDやRoute53を利用する場合は別途料金がかかります)また、AWS上でサーバーを一括管理できることやグローバルIPアドレスの取得が容易であること、GUIでの操作が可能であることもメリットになります。

通常お金のかかるドメインの取得とAWSの利用ですが、今回は合計1円のみでDNSサーバーについて学ぶことができるため、初めての方でも取り組みやすい内容になっているかと思います。

目次

DNSサーバーとは

DNSDomainNameSystem)とは、ドメイン名や完全修飾ドメイン名(FQDN)に対応するIPアドレスの情報を管理・運用するシステムです。 簡単に言えば、例えばドメイン名「google.com」を「172.217.175.14」というIPアドレスに変換してくれるシステムです。 もう少し詳しく言うと、インターネット上でコンピュータ同士が通信を行うためにはIPアドレスと呼ばれるインターネット上の住所のようなものを使って通信します。 しかし私たち人間がIPアドレス「172.217.175.14」を見ただけでは、それが「google.com」のサーバーだとはわかりません。 同様にコンピュータがドメイン名「google.com」を見ても、コンピュータはIPアドレスでしか読み取ることができないため、人間とコンピュータにわかるようにするための相互変換が必要になり、DNSというシステムが使用されています。 DNSサーバーはその機能を実装しているサーバーということになります。
例えば、検索バーに「google.com」と入力します。先ほども説明したようにコンピュータには「google.com」という文字列からサーバーの住所はわかりませんが、DNSサーバーに「google.comのIPアドレス(住所)を教えて下さい」と問い合わせを行うことでDNSサーバーは「google.comのIPアドレス(住所)は172.217.175.14ですよ」とコンピュータに教えてくれます。これによりコンピュータは受け取ったIPアドレスにアクセスすることでgoogle.comのページが表示されるということになります。 簡単にDNSサーバーの動きを説明しましたが、DNSサーバーは世界中にある無数のDNSサーバーが階層構造になって存在しています。そのため、一口に「google.comのIPアドレスは何?」と言っても、「ルートDNSサーバー」→「.comを管理しているDNSサーバー」→「google.comのIPを管理しているDNSサーバー」を経由してIPアドレスをコンピュータに教えてくれます。この動作は世界中にある無数のDNSサーバーが連携し一瞬で完了するため、私たちは普段意識することはありません。また、DNSサーバーにはキャッシュDNSサーバーと権威DNSサーバーというものが存在しています。キャッシュDNSサーバーは、自身でドメイン名とIPアドレスの情報を管理しているわけではなく、他のDNSサーバーに問い合わせを行ったり、自身で保持しているキャッシュからIPアドレスなどを返したりするDNSサーバーです。逆に権威DNSサーバーは、自身でドメイン名とIPアドレスの情報を管理しているDNSサーバーになります。今回は、自身でドメイン名とIPアドレスの情報を管理するので、権威DNSサーバーを構築します。

今回の名前解決の流れは以下のようになります。

  1. クライアントはブラウザで「http://web-test.dns-server-test.work」と入力すると、WebサーバーのIPアドレスを得るためにキャッシュDNSサーバーに問い合わせを行います。
  2. キャッシュDNSサーバーは、「http://web-test.dns-server-test.work」のIPアドレスを保持している場合はそのIPアドレスをクライアントに返し、保持していない場合はルートDNSサーバーに問い合わせを行います。
  3. ルートDNSサーバーには、「http://web-test.dns-server-test.work」のIPアドレスの情報はありませんが、「.work」を管理しているDNSサーバーのIPアドレスを保持しているため、そのIPアドレスを返します。
  4. 3で受け取ったDNSサーバーのIPアドレスを元に、「.work」を管理しているDNSサーバーに「http://web-test.dns-server-test.work」のIPアドレスを問い合わせます。
  5. 「.work」を管理しているDNSサーバーには、「http://web-test.dns-server-test.work」のIPアドレスの情報はありませんが、「dns-server-test.work」を管理しているDNSサーバーのIPアドレスを保持しているため、そのIPアドレスを返します。
  6. 5で受け取ったDNSサーバーのIPアドレスを元に、「dns-server-test.work」を管理しているDNSサーバーに「http://web-test.dns-server-test.work」のIPアドレスを問い合わせます。
  7. dns-server-test.work」を管理しているDNSサーバーには、「http://web-test.dns-server-test.work」のIPアドレス情報が記載されているため、そのIPアドレスを返します。
  8. 受け取った「http://web-test.dns-server-test.work」のIPアドレスをクライアントに返します。
  9. クライアントは「http://web-test.dns-server-test.work」のIPアドレスを元にWebサーバーにアクセスします。
  10. WebサーバーのHTMLからブラウザ上にWebページが表示されます。

DNSサーバーには、ドメイン名とIPアドレスを紐づける情報が無数に蓄積されています。しかし、DNSサーバーがダウンしてしまった場合、ドメイン名とIPアドレスの紐づけができなくなるため、Webサービスにアクセスできなくなったり、メールを送信することができなくなってしまいます。そのため、DNSサーバーは障害がいつ発生しても問題ないように2つ以上のサーバー群で構成されています。今回はプライマリDNSサーバーとセカンダリDNSサーバーの2つを構築し、片方のDNSサーバーで障害が発生しても問題ないことも確かめたいと思います。



環境準備

実際にDNSサーバーを構築するための準備を行っていきます。
※今回はAWS上で作成したWebサーバーとDNSサーバーにSSH接続するため、RLoginというSSHクライアントをインストールしておきます。
※すでにターミナルソフトがインストールされている方はそちらを利用してください。
http://nanno.dip.jp/softlib/man/rlogin/#INSTALLnanno.dip.jp

ドメイン取得

まず、ドメインの取得です。今回は初回1年のみ1円/年で取得できる「.work」ドメインを取得します。
※今回はdns-server-test.workドメインを取得しました(取得する場合は) www.onamae.com

※お名前ドットコムは1年後にドメインが自動更新される設定になっているため、自動更新を解除しておきましょう。
※お名前ドットコムからは頻繁にメールが届くため、メールの配信設定を変更することをお勧めします。

AWS登録

次にAWSAmazon Web Service)を利用するためアカウント登録を行います。
aws.amazon.com

インスタンス作成

AWSが利用可能になったら次はインスタンスを作成していきます。インスタンスとは、AWSクラウド上にあるOSを載せた仮想サーバーのことです。 インスタンスを作成することでサーバーの環境構築を行うことができます。
以下のリンクを参考にインスタンスを作成します。
aws.amazon.com

インスタンスの仕様は以下のように設定します。

  • AMI(Amazonマシンイメージ):CentOS8 minimal
  • インスタンスタイプ    :t2.micro
  • セキュリティグループ   :Webサーバー・・・SSH(マイIP)、HTTP(80番ポート)
                 :DNSサーバー・・・SSH(マイIP)、DNS(UDP)、DNS(TCP)
  • Nameタグ         :Webサーバー・・・web-test
                 :プライマリDNSサーバー・・・dns1-test
                 :セカンダリDNSサーバー・・・dns2-test


Webサーバー・プライマリDNSサーバー・セカンダリDNSサーバーの3つ分、インスタンスを作成します。


ネットワーク設定

次にネットワークの設定を行っていきます。 AWSではEIP(Elastic IP)というものが設定でき、今回作成したサーバーに固定のIPアドレスを付けることができます。
以下の リンクを参考にEIPを設定します。
docs.aws.amazon.com

今回使用するWebサーバー・プライマリDNSサーバー・セカンダリDNSサーバーの3つにそれぞれ割り当てます。
EIPが重複せずに設定されていれば完了です。


Webサーバー構築

DNSサーバーの構築に入る前に、Webサーバーを作成します。
初めにWebサーバーにSSH接続します。
今回はログインユーザ名を「centos」とする必要があるため注意してください。(rootユーザではログインできません)
また、インスタンス作成時に作成したキーペアを登録します。(登録しない場合SSHできません)

SSH接続後は、rootに切り替えてコマンドを実行していきます。 (デフォルトではrootユーザでログインできないため)
※以降サーバー内でコマンドを実行するときは必ずrootユーザに変更してから行う

# sudo su -

SSH接続後は、ミドルウェアアップデートをして脆弱性の排除を行います。

# dnf check-update
# dnf upgrade

ミドルウェアアップデートが完了したら再度確認を行い、最新の状態であることを確認します。
アップデート対象が表示されなければ完了です。

# dnf check-update

Apacheのインストール

次に、Apacheをインストールします。

# dnf install httpd

インストールが完了したら、Apacheのバージョンを確認しておきます。

# httpd -v
Server version: Apache/2.4.37 (centos)
Server built:   Nov  4 2020 03:20:37

Apache自動起動する設定に変更しておきます。 enabledになっていれば自動起動される設定になったということになります。

# systemctl enable httpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
# systemctl list-unit-files | grep httpd.service
httpd.service                              enabled        

Apacheを起動してステータスを確認します。 「Active: active (running)」となっていれば起動状態です。

# systemctl start httpd.service
# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running)
~省略~

無事Apacheが起動しましたので、次はHTMLの作成と配置です。

HTMLの作成と配置

クライアントからのアクセスでファイル名を指定しなかった場合(http://example.com/index.html ← この最後のファイルを指定しない場合)、/etc/httpd/conf/httpd.confファイル内のDirectoryIndexディレクティブからindex.htmlがデフォルトで表示されるようになっています。

~省略~

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

~省略~

このようにデフォルトではindex.htmlが指定されており、http://www.dns-server-test/にアクセスされると、index.htmlが存在すればそのHTMLが、存在しなければApacheのテストページが表示されます。 そのため、今回は編集する箇所を少なくしたいという意味も込めて、index.htmlファイルを作成していきます。
まず、HTMLファイルの配置場所ですが、以下のコマンドを使用することで確認することができます。

# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf
DocumentRoot "/var/www/html"

これによりHTMLファイルは「/var/www/html」の下に配置すればよいということがわかります。
次に、HTMLの作成です。以下のコマンドでHTMLを作成します。

# vi /var/www/html/index.html

簡易的ですが、記述するHTMLを記載します。

<!DOCTYPE html>
<html lang="ja"> 
  <head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <meta name="description" content=""> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <title>DNS TEST</title> 
  </head> 
  <body> 
    <h1>Successful Access!</h1> 
  </body> 
</html>

HTMLの作成と配置が完了しました。


セキュリティグループの変更(Webサーバー)

これにてWebサーバーの構築は完了しましたので、構築できているか確認するためにアクセスします。
Webサーバーにアクセスするためには、セキュリティグループを変更して80番ポートを解放する必要があります。
以下のように設定を追加します。

  • タイプ:HTTP
  • ソース:カスタム、0.0.0.0/0




一度動作確認のため、IPアドレスでアクセスしてみます。

成功しました。



DNSサーバー構築

前置きが長くなりましたが、いよいよ本題のプライマリDNSサーバーとセカンダリDNSサーバーの構築に入ります。

プライマリDNSサーバーの構築

それでは実際に構築していきます。 まず、AWS上で作成したサーバーをDNSサーバーとして動作させるための設定ファイル等が入ったミドルウェアをインストールする必要があります。 今回インストールするものは、「bind」「bind-chroot」「bind-utils」の3種類です。

  • bind ・・・・・・BIND9本体で各種設定ファイル等が入っているもの
  • bind-chroot・・・chroot化させるためのもの
  • bind-utils・・・・nslookupやdigコマンドを使用するためのもの(named-checkzoneコマンドも使用できるようにするため)

Step1~9でDNSサーバーの構築を行います。

Step1
Webサーバー構築時と同様にプライマリDNSサーバー(dns1)にSSH接続します。
※接続方法はWebサーバーで解説していますのでそちらを参照
※「# sudo su -」でrootユーザに変更してから実施


Step2
Webサーバー構築時と同様にミドルウェアアップデートを行います。

# dnf check-update
# dnf upgrade


Step3
以下のコマンドを入力し、BIND関連のミドルウェアをインストールします。

# dnf install bind bind-chroot bind-utils


Step4
BINDのバージョンがBIND9系であることを確認します。

# named -v
BIND 9.11.20-RedHat-9.11.20-5.el8 (Extended Support Version) <id:f3d1d66>


Step5
namedではなくnamed-chrootというサービスを起動して利用するため、namedのステータスと設定を確認します。 ※chrootについては後述します。

# systemctl list-unit-files | grep ^named.service
named.service                              disabled
# systemctl status named
● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

namedが自動起動しない設定であることと停止していれば問題ありません。
自動起動する設定や起動している場合には、以下のコマンドで停止させましょう。

# systemctl disable named.service
# systemctl stop named.service


Step6
named-chroot自動起動する設定にして起動させます。先ほど説明を後回しにしたchrootですが、ルートディレクトリを変更するというもので、namedをchroot化させると/var/named/chroot以下に関連するファイルがマウントされ、chrootより上位のディレクトリにはアクセスをできなくなります。これによりアクセス可能な範囲が制限されセキュリティ対策となります。

# systemctl enable named-chroot.service
Created symlink /etc/systemd/system/multi-user.target.wants/named-chroot.service → /usr/lib/systemd/system/named-chroot.service.
# systemctl start named-chroot.service
# systemctl status named-chroot.service
● named-chroot.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named-chroot.service; enabled; vendor preset: disabled)
   Active: active (running)
~省略~


Step7
named.confファイルを編集してDNSサーバーの基本設定を行います。 ※chroot化しているため、/etc/named.confではなく/var/named/chroot/etc/named.confを編集することに注意

# vi /var/named/chroot/etc/named.conf

デフォルトのnamed.confファイルは以下になります。

//
// named.conf
//
//
// 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";

今回編集するのは、optionsステートメントとzoneステートメントです。以下のように変更します。

options {
        // 1. BINDのバージョンを隠蔽
        version "unknown";
        
        // 2. ホスト名
        hostname "dns1.dns-server-test.work.";

        // 3. 53番ポートでの受付をすべて許可
        listen-on port 53 { any; };

        // 4. ipv6を使用しない
        listen-on-v6 { 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";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";

        // 5. すべてのクエリーを受け付ける
        allow-query     { any; };


        // 6. リゾルバとして動作しないように設定
        recursion no;
        allow-recursion { none; };
        allow-query-cache { none; };

        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;
        };
};


// 7. ルートDNSサーバーのゾーン情報は今回必要ないのでコメントアウト
/* 
zone "." IN {
        type hint;
        file "named.ca";
};
*/

// 8. ゾーンファイルdns-server-test.workの設定
zone "dns-server-test.work" IN {
        // プライマリDNSサーバーであることを指定
        type master;
        // ゾーンファイルのファイル名を指定
        file "dns-server-test.work";
        // ゾーンファイルの変更を通知する
        notify yes;
        // ゾーンファイルの変更を通知する先を指定(セカンダリDNSサーバーのプライベートIPアドレスを指定)
        also-notify { xxx.xxx.xxx.xxx; };
        // ゾーン転送先を指定(セカンダリDNSサーバーのプライベートIPアドレスを指定)
        allow-transfer { xxx.xxx.xxx.xxx; };
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
  1. BINDのバージョンを隠蔽
    • nslookupコマンド等でBINDのバージョンを表示されないようにします。バージョンが知られてしまうと、そのバージョンでの脆弱性を突いて攻撃される可能性があるためです。今回は入力をunknownしているため、unknownと表示されることになります。
  2. ホスト名
    • DNSサーバーのホスト名を記述します。プライマリDNSサーバーのnamed.confファイルを編集しているので、「dns1-test.dns-server-test.work」となります。
  3. 53番ポートでの受付をすべて許可
    • DNSサーバーは53番ポートを使用するため許可する設定にします。
  4. IPv6を使用しない
    • 今回はIPv4のみ使用するため使用しないことを明示的に記述しています。(記述しない場合も使用しない設定になります)
  5. すべてのクエリーを受け付ける
    • どこからでも名前解決の問い合わせを受け付ける設定にします。
  6. ゾルバとして動作しないように設定
    • recursionは再帰問い合わせを行う設定です。今回は権威DNSサーバーを構築するため、設定をnoにします。
  7. ルートDNSサーバーのゾーン情報は今回必要ないのでコメントアウト
  8. ゾーンファイルdns-server-test.workの設定
    • DNSサーバーがプライマリなのかセカンダリなのかの指定や、ゾーンファイルの名前を指定、ゾーン転送先を指定等をします。

編集が完了したら記述が正しくできているかチェックを行います。
※正しく記述できている場合には何も表示されません

# named-checkconf /var/named/chroot/etc/named.conf


Step8
named.confファイルの編集が終わったら次はゾーンファイルの作成です。簡単に言うとゾーンファイルはドメイン名とIPアドレスの対応表を記載していくファイルになります。
/var/named/chroot/var/named以下に作成します。

# vi /var/named/chroot/var/named/dns-server-test.work

ゾーンファイルの記述は以下のようになります。

$TTL 300
@ IN SOA  dns1-test.dns-server-test.work. xxxxxxxxxx.gmail.com. (
        2020122000      ; Serial(シリアル
        3600            ; Refresh(転送間隔
        900             ; Retry(再試行猶予時間
        21600           ; Expire(有効時間
        60              ; Minimum TTL(ネガティブキャッシュTTL
)

; DNSサーバ
        IN NS   dns1-test.dns-server-test.work.
        IN NS   dns2-test.dns-server-test.work.

dns1-test                 IN A    xxx.xxx.xxx.xxx
dns2-test                 IN A    xxx.xxx.xxx.xxx


; Webサーバ
web-test                 IN A    xxx.xxx.xxx.xxx

ゾーンファイル内では「 ; 」はコメントとして扱われます。以下に各記述の内容を記載します。

  • TTL
    • DNSサーバーがレコード情報をキャッシュする時間で、この場合最大5分間ローカルにキャッシュを保持します。
  • @ IN SOA
    • SOAレコートといい、@ IN SOA {MNAME} {RNAME}で記述します。
    • MNAMEは、DNSサーバーの名前を記述します。
    • RNAMEは、このドメインの管理者のメールアドレスを記述します。@マークは「 . 」に置き換えて記述する必要があります。
  • Serial
    • ゾーンファイルのバージョンを表し、YYYYMMDDnn形式で記述します。この場合であれば「2020年12月20日1回目の変更」ということになります。※変更回数は0回からカウントします。
    • 例えば同じ日に2回目の変更をした場合はシリアルを変更して「2020122001」となります。
  • Refresh
    • ゾーンの情報をリフレッシュするまでの時間です。
    • セカンダリDNSサーバーはゾーン転送をした後、この時間が経過すると、ゾーンの更新がされたかを問い合わせ、必要に応じて再度データを入手しようとします。
  • Retry
    • Refreshでゾーンの情報が更新できなかった場合に、指定された時間後に再度リフレッシュを試みます。
  • Expire
    • ゾーン情報のリフレッシュができない状態が続いた場合に、セカンダリDNSサーバーが所持しているデータをどのくらいの時間利用するか記述します。
  • Minimum TTL
    • ネガティブキャッシュと言われ、名前解決ができなかったという情報を保持する時間を記述します。
  • IN NS ~
    • NSレコードといい、DNSサーバーを記述します。今回の場合はプライマリDNSサーバーとセカンダリDNSサーバーを指定します。
    • 最後に「 . 」を付けます。
  • ~ IN A ~
    • Aレコードといい、ホスト名に対応するIPアドレスを記述します。


ゾーンファイルの編集が終わったらパーミッションと所有権を変更します。

# chmod 750 /var/named/chroot/var/named/dns-server-test.work
# chown root:named /var/named/chroot/var/named/dns-server-test.work
# ll /var/named/chroot/var/named/dns-server-test.work
-rwxr-x---. 1 root named 570 Dec 20 14:01 /var/named/chroot/var/named/dns-server-test.work

ゾーンファイルもnamed.confと同様、記述が正しいかチェックします。「OK」と表示されれば問題ありません。
※構文が正しいかのみのチェックであるため、IPアドレスが正しいかどうか等は判定されません

# named-checkzone dns-server-test.work /var/named/chroot/var/named/dns-server-test.work
zone dns-server-test.work/IN: loaded serial 2020122000
OK


Step9
最後に設定を反映させます。rndcコマンドを使用することで、DNSサーバーを再起動させることなくゾーンファイルを反映させることができます。

# rndc reload
server reload successful

プライマリDNSサーバーの構築は完了です。


セカンダリDNSサーバーの構築

プライマリDNSサーバーの構築が終わったら次はセカンダリDNSサーバーの構築です。構築はプライマリDNSサーバーとほぼ同様です。
セカンダリDNSサーバーにSSH接続し、プライマリDNSサーバーで行ったStep2~6までを行います。
Step7はプライマリDNSサーバーとセカンダリDNSサーバーでは変更箇所があるため、変更箇所を以下に記述します。named.confファイルを編集します。

# vi /var/named/chroot/etc/named.conf
options {
        // BINDのバージョンを隠蔽
        version "unknown";
        
        // ホスト名
        hostname "dns2.dns-server-test.work.";

        // 53番ポートでの受付をすべて許可
        listen-on port 53 { any; };

        // ipv6を使用しない
        listen-on-v6 { 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";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";

        // すべてのクエリーを受け付ける
        allow-query     { any; };


        // リゾルバとして動作しないように設定
        recursion no;
        allow-recursion { none; };
        allow-query-cache { none; };

        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";

        // 1. セカンダリDNSサーバーからは通知を送信しない
        notify no;

        // 2. セカンダリDNSサーバーからはゾーン転送しない
        allow-transfer { none; };
};

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


// ルートDNSサーバーのゾーン情報は今回必要ないのでコメントアウト
/* 
zone "." IN {
        type hint;
        file "named.ca";
};
*/

// 3. ゾーンファイルdns-server-test.workの設定
zone "dns-server-test.work" IN {
        // セカンダリDNSサーバーであることを指定
        type slave;
        // ゾーン転送されたファイルをバイナリ形式からテキスト形式に変換する設定
        masterfile-format text;
        // ゾーンファイルのファイル名を指定
        file "slaves/dns-server-test.work";
        // マスターDNSサーバーを指定(マスターDNSサーバーのプライベートIPアドレスを指定)
        masters { xxx.xxx.xxx.xxx; };
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
  1. セカンダリDNSサーバーからは通知を送信しない
    • プライマリDNSサーバーからは通知を送信しますが、セカンダリDNSサーバーはバックアップのような存在であるため、通知の必要がありません。
  2. セカンダリDNSサーバーからはゾーン転送しない
    • プライマリDNSサーバーからはゾーン転送を行いますが、セカンダリDNSサーバーはゾーン転送を受ける側なので必要がありません。
  3. ゾーンファイルdns-server-test.workの設定
    • DNSサーバーがプライマリなのかセカンダリなのかの指定や、ゾーンファイルの名前を指定、ゾーン転送先を指定等をします。


セカンダリDNSサーバーはゾーン転送によりゾーンファイルがプライマリDNSサーバーから転送されてくるため、Step8は行いません。
Step9を行います。

# rndc reload
server reload successful


最後にStep10として、ゾーン転送されているか確認します。
※最初のゾーン転送が行われるまでは若干時間がかかる可能性があるため、次の「セキュリティグループの変更」や「DNSサーバー登録」を行ってから再度確認してください。

# ll /var/named/chroot/var/named/slaves/
total 4
-rw-r--r--. 1 named named 473 Dec 20 15:20 dns-server-test.work


セキュリティグループの変更(DNSサーバー)

Webサーバーのセキュリティグループ変更と同様にDNSサーバーのセキュリティグループを以下のように変更します。
DNSサーバーは53番ポートで通信を行うため、DNS(UDP)とDNS(TCP)を解放する必要があります。
DNSサーバーのセキュリティグループ変更は完了です。



DNSサーバー登録

先ほど構築したDNSサーバーですが、構築しただけではDNSサーバーとしての役割、つまり名前解決を行うことはできません。
DNSサーバーとはの部分でも触れましたが、DNSサーバーは階層構造になっているため、今回構築したDNSサーバーの一つ上のDNSサーバーに、構築したDNSサーバーのIPアドレスを登録する必要があります。
つまり今回の場合であれば「.workドメインを管理しているDNSサーバー(お名前ドットコム)に、今回構築したDNSサーバーのIPアドレスを登録する」ということになります。
まずはお名前ドットコムにアクセスします。 画面右上の「お名前ドットコム navi ログイン」をクリックしてログイン画面に移ります。



ドメイン取得時にお名前IDが発行されているのでそちらとパスワードを入力しログインします。



ログインが完了したら、画面上部のDNSタブにカーソルを合わせ、「ドメインDNS設定」をクリックします。



取得したドメインにチェックを入れ「次へ」をクリックします。



画面下部にある「ネームサーバー名としてホスト登録を行う」の「設定する」をクリックします。



作成にチェックを入れ「入力画面に進む」をクリックします。



ホスト名「dns1」とdns1のIPアドレスを入力し、「確認画面へ進む」をクリックします。
※dns2も同様にホスト名とIPアドレスを登録します。(DNSサーバーを2つ登録しないと後の画面でエラーになります。)



ホスト名の登録が完了したら次は、DNSサーバーの変更を行います。
画面左のメニューバーから「ネームサーバーの変更」をクリックします。



ドメインの選択でドメイン名にチェックを入れます。ネームサーバーの選択でその他を選択し、構築したDNSサーバーのFQDNを入力します。
今回であれば「dns1.dns-server-test.work」「dns2.dns-server-test.work」を入力します。(ここで2つ登録できないとエラーになります。)
エラー時参考:【ドメイン】ネームサーバーの変更ができません。|ヘルプサポート | ドメイン取るならお名前.com

「確認」をクリックすればDNSサーバーの変更は完了です。
※場合によっては、反映に時間がかかる可能性があります。



動作確認

最後にDNSサーバーが正常に動作しているか確認します。
URL入力欄にFQDNを入力します。

成功です。

次は、コマンドプロンプトから確認してみます。

> nslookup web-test.dns-server-test.work
サーバー:  ~~~~~~~~
Address:  xxx.xxx.xxx.xxx ←自分のIPアドレス

権限のない回答:
名前:    web-test.dns-server-test.work
Address:    xxx.xxx.xxx.xxx ←WebサーバーのIPアドレス

WebサーバーのIPアドレスが返ってきていれば成功です。


次はDNSサーバーを直接指定して名前解決ができるか確認します。
まずは、プライマリDNSサーバーからです。(yyy.~はプライマリDNSサーバーのIPアドレスを指定)

> nslookup web-test.dns-server-test.work yyy.yyy.yyy.yyy
サーバー:  UnKnown
Address:  xxx.xxx.xxx.xxx ←自分のIPアドレス

権限のない回答:
名前:    web-test.dns-server-test.work
Address:    xxx.xxx.xxx.xxx ←WebサーバーのIPアドレス

次に、セカンダリDNSサーバーです。(zzz.~はセカンダリDNSサーバーのIPアドレスを指定)

> nslookup web-test.dns-server-test.work zzz.zzz.zzz.zzz
サーバー:  UnKnown
Address:  xxx.xxx.xxx.xxx ←自分のIPアドレス

権限のない回答:
名前:    web-test.dns-server-test.work
Address:    xxx.xxx.xxx.xxx ←WebサーバーのIPアドレス

どちらもWebサーバーのIPアドレスが返ってきていれば成功です。


最後にプライマリDNSサーバーが停止している状態で確認します。
AWSマネジメントコンソール画面からプライマリDNSサーバーを停止させておきます。

正常に停止したことを確認したら、次はコマンドプロンプトでコマンドを実行します。
PC内にゾーン情報が残っている可能性があるため、キャッシュを削除します。

> ipconfig /flushdns

Windows IP 構成

DNS リゾルバー キャッシュは正常にフラッシュされました。

nslookupコマンドでも確認しておきます。

サーバー:  ~~~~~~~~
Address:  xxx.xxx.xxx.xxx ←自分のIPアドレス

DNS request timed out.
    timeout was 2 seconds.
権限のない回答:
名前:    web-test.dns-server-test.work
Address:  xxx.xxx.xxx.xxx ←WebサーバーのIPアドレス

WebサーバーのIPアドレスが返ってきていれば準備完了です。
キャッシュを削除する以外にも、Google Public DNS(8.8.8.8)を指定してコマンドを打つことでも確認することができます。

URL入力欄にFQDNを入力します。

成功です。
これにより、プライマリDNSサーバーが何等かの不具合により停止したとしても、セカンダリDNSサーバーが稼働しているためWebページにアクセスすることが可能になっていることがわかります。



おわりに

長くなってしまいましたが、難しい手順などもなく簡単にDNSサーバーを構築できたのではないでしょうか。普段意識することの無いDNSサーバーについて少しでも知ることができていれば幸いです。
今回学んだことを応用すると、例えば「DNSサーバーがダウンし目的のWebページにアクセスできないとなった場合(DNSサーバーが応答していません等)、WindowsMacの参照先DNSサーバー(Google Public DNS:8.8.8.8 や OpenDNS:208.67.222.222 等)を変更し、そのDNSサーバーを経由させ名前解決を正常に行えるようにすればWebページにアクセスできるようになる」ということが理解できるかと思います。このように、DNSサーバーについて理解を深めることで、Webサーバーがダウンしてアクセスできないのか、DNSサーバーがダウンしてアクセスできないのか等の原因の切り分けにも利用できるかと思います。

冒頭で一瞬出ましたが、AWSにはRoute53というDNSサーバーを簡単に構築することができるサービスがあるので、気になる方は是非調べてみてください。
今回は触れませんでしたが、DNSサーバーの逆引き設定についても機会があれば紹介したいと思います。


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.