Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

bindによるDNSサーバ

初めまして、nechinechiです。
今回はbindでDNSサーバの構築手順を紹介したいと思います。
ここでは、内向けDNSの正引きの場合の手順を示しています。
なお、私はVagrantとVirtualboxを利用したVM上で構築していますが、VMの立て方は省略します。 また、OSはUbuntuを使っています。

はじめに

ここでは以下の流れで話を進めていきます。

  • ソフトウェアのインストール
  • 設定ファイルの編集
  • ドメイン解決がされているかの確認

また、今回割り当てるドメインとIPアドレスの対応は以下のようにします。

IPアドレス ドメイン エイリアス(別名)
IPアドレス1 ns.fw.test (なし)
IPアドレス2 pig.fw.test buta.fw.test
IPアドレス3 neko.fw.test (なし)

※ IPアドレス1、IPアドレス2、IPアドレス3には、ドメインを割り当てたいIPアドレスがそれぞれ入る

利用するツール

  • bind9

インストール

まずはbind9のインストールです。以下のコマンドを実行してインストールします。

sudo apt-get install bind9

設定ファイルの編集

Ubuntu環境であれば、設定ファイルは/etc/bindの下にあるかと思います。
その中で読み込まれるファイルはnamed.confファイルです。
他のファイルは、named.confからincludeされていたり、includeされたファイルから参照されています。
記述内容をきれいに分けたいときにincludeを使ってファイルを分けます。

それでは各ファイルの中身を見ていきます。
ただし、ソースコードはコメントアウトされている部分は省いて示しています。

/etc/bind/named.conf

named.confの内容は以下のようになっています。
ここでは、/etc/bindにあるnamed.conf.optionsnamed.conf.localnamed.conf.default-zonesをインクルードしています。
このファイルは何も編集はしません。

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

/etc/bind/named.conf.options

named.conf.optionsは以下のようになっています。
named.conf.optionsでは、ドメインの問い合わせに対して、そのリクエストを受け付け、IPアドレスを返すサーバの制限をしています。
ここでは、自分自身と、IPアドレスのネットワークアドレス部が、記述したネットワークアドレスと合致した場合のみ、対応するドメインを返すようにしています。

options {
        directory "/var/cache/bind";

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

        // ---- 以下を追記 ---------------------------
        allow-query {
            127.0.0.1;             // 自分自身(localhost)
            ネットワークアドレス;    // 192.168.10.0/24 のように記述
        };
        // --------------------------------------------
};

/etc/bind/named.conf.local

このファイルはnamed.confから、includeはされていますが、インストールした初めの状態ではすべてがコメントアウトされていると思います。
また、このファイルは編集をしないので、このファイルはそのままでいいです。

/etc/bind/named.conf.default-zones

named.conf.default-zonesは以下のようになっています。 type masterは、そのサーバがプライマリDNSサーバであることを表します。
セカンダリDNSサーバであれば、type slaveと記述します。
fileはそこで指定したファイルから、ドメインなどの情報を得るようにしています。 ここで、ファイルのパスは必ず絶対パスで記述します。
追記した部分では、db.fw.testを参照しています。

// prime the server with knowledge of the root servers
zone "." {
        type hint;
        file "/etc/bind/db.root";
};

// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

// ---- 以下を追記 -------------------------------------

// fw.test の正引きの設定
zone "fw.test" {
  // Master DNS Serverであることを明示
  type master;
  // 設定ファイル名
  file "/etc/bind/db.fw.test";
};
// -----------------------------------------------------

/etc/bind/db.fw.test

db.fw.testの内容は以下になります。
$ORIGINはその右側に指定された名前で@を置き換えてくれます。なので、行頭で@で表している部分は、fw.test.に置き換えられて解釈されます。
$TTLは外部DNSサーバがこのサーバのドメイン情報をキャッシュして、その情報を保持する期間を指定しています。
SOANSACNAMEはレコードと呼ばれるものです。
IPアドレス1には、このDNSサーバのIPアドレスを記述します。 IPアドレス2、IPアドレス3には名前の割り当てたいIPアドレスを記述します。
ここでは、nsにIPアドレス1、pigにIPアドレス2、nekoにIPアドレス3をそれぞれ割り当てています。また、pigにはエイリアスとして、butaといった名前も与えています。
※ ドメインの最後に.を忘れないようにしましょう

$ORIGIN fw.test.
$TTL           604800
@       IN SOA fw.test. root.fw.test. (
            20160515  ;  Serial
            604800    ;  Refresh
            86400     ;  Retry
            2419200   ;  Expire
            604800    ;  Negative Cache TTL
        )
@       IN    NS     ns.fw.test.
ns      IN    A      IPアドレス1
pig     IN    A      IPアドレス2
buta    IN    CNAME  pig
neko    IN    A      IPアドレス3

SOAレコード内の説明

説明
Serial ゾーン情報のバージョンを表す。ファイルの作成日時などにしておくとよい
Refresh ゾーン情報をリフレッシュするまでの時間(秒数)
Retry ゾーン情報の更新ができなかった場合の、再度リフレッシュをするまでの間隔(秒数)
Expire ゾーン情報のリフレッシュができない場合、セカンダリDNSサーバの持つデータの有効期限(秒数)
Negatie Cache TTL ネガティブキャッシュの有効期限(秒数)

※ ゾーンとは、管理されているDNS情報の単位のこと。
※ ネガティブキャッシュとは、ドメインの問い合わせで失敗したキャッシュ情報のこと。

レコードの説明

レコード名 説明
SOA ゾーン情報のバージョンなどを記述
NS 下位ドメインのネームサーバを表す
A ホスト名からIPアドレスへ対応付ける
CNAME ホスト名にエイリアス(別名)をつける

変更の反映

以下のコマンドを実行する。

service bind9 restart

確認

設定がうまくいっているかを確認するには、digコマンドを使います。使い方は以下のようにします。

dig @構築したDNSサーバのIPアドレス ホスト名を含むドメイン名

実際に実行した結果が以下の2つの図です。
黄色の部分にはDNSサーバのIPアドレスが表示されています。

1枚目の図はneko.fw.testをDNSサーバに問い合わせています。
赤色の部分にneko.fw.testのIPアドレスが表示されていれば、うまくいっています。
また、出力された結果の5行目に、status: NOERRORとありますが、ここからもうまくいっていることがわかります。

f:id:nechinechi:20160517232441p:plain

2枚目の図では、buta.fw.testを問い合わせています。
butapigのエイリアスにしているので、水色の部分にpig.fw.testのIPアドレスが表示されていれば成功です。
また、水色の部分の上に、buta.fw.testからpig.fw.testが導き出されていることがわかります。

f:id:nechinechi:20160517232454p:plain

以上から設定がうまくいっていることがわかります。

終わりに

複数のサーバ上のリソースに対し、アクセスを行うようなことがあると思います。 この際、自身の所有するマシンなどでドメイン名が割り当てられてないと、ブラウザやプログラムにIPアドレスをそのまま記述する必要があります。
しかし、IPアドレスでは今どのサーバを参照しているのか、すぐには理解しづらいと思います。 このような場合には、ドメインを割り振り、ドメイン名でサーバを参照するようにします。
ただ、/etc/hostsに以下のように記述すれば、IPアドレス2にpig.fw.testを割り当てることができます。

IPアドレス2 pig.fw.test

しかし、これは記述したマシンにおいてのみです。つまり、複数のマシンにも同じようにIPアドレス2にpig.fw.testを割り当てるには、全てのマシンで同じように/etc/hostsに記述しなければなりません。
ドメインを割り当てるIPアドレスが10個、20個もあり、それを10個、20個のマシンで名前解決させたい場合もあります。それはかなりの手間がかかってしまう事です。
しかし、DNSサーバを構築しておけば、最初の構築の手間と、新たにドメインを割り振りたいIPアドレスの記述を1度行うだけで名前解決が可能になるのです。
DNSサーバで名前解決をするメリットはここにあります。
私自身がこのような状況であり、DNSサーバの構築は今回が初めてで未知のものだったのですが、初めはさっぱりでしたが徐々にわかってきて、思っていたほどに複雑ではないんだなと感じました。
また、ホスト名にエイリアスをつけれることは今まで知らなかったです。