22.11. DNS

寄稿: Lee Chern [FAMILY Given].

22.11.1. 概観

FreeBSD はデフォルトでは DNS プロトコルの最も一般的な実装である BIND (Berkeley Internet Name Domain) を使用します。DNS はホスト名を IP アドレスに、そして IP アドレスをホスト名に関連づけるプロトコルです。 たとえば www.FreeBSD.org に対する問い合わせは The FreeBSD Project の ウェブサーバの IP アドレスを受け取るでしょう。 その一方で ftp.FreeBSD.org に対する問い合わせは、 対応する FTP マシンの IP アドレスを返すでしょう。 同様に、その逆のことも可能です。 IP アドレスに対する問い合わせを行うことで、 そのホスト名を解決することができます。 DNS 検索を実行するために、 システム上でネームサーバを動作させる必要はありません。

DNS は、 個々のドメイン情報を格納およびキャッシュした、 権威のあるルートサーバおよび他の小規模なネームサーバによる多少複雑なシステムによって、 インターネット全体にわたって協調して動作します。

この文書は FreeBSD で安定版として利用されている BIND 8.x について説明します。 FreeBSD では BIND 9.x を net/bind9 port からインストールできます。

RFC1034 および RFC1035 は DNS プロトコルを定義しています。

現在のところ BIND は Internet Software Consortium (www.isc.org) によって保守されています。

22.11.2. 用語

この文書を理解するには DNS 関連の用語をいくつか理解しなければいけません。

用語定義
正引き DNSホスト名から IP アドレスへの対応です。
オリジン (origine)特定のゾーンファイルによってカバーされるドメインへの参照です。
named, BIND, ネームサーバFreeBSD 内の BIND ネームサーバパッケージの一般名称です。
リゾルバ (resolver)マシンがゾーン情報についてネームサーバに問い合わせるシステムプロセスです。
逆引き DNS正引き DNS の逆です。つまり IP アドレスからホスト名への対応です。
ルートゾーンインターネットゾーン階層の起点です。 すべてのゾーンはルートゾーンの下に属します。 これはファイルシステムのすべてのファイルがルートディレクトリの下に属することと似ています。
ゾーン同じ権威によって管理される個々の DNS ドメイン、 DNS サブドメイン、あるいは DNS の一部分です。

ゾーンの例:

  • . はルートゾーンです。

  • org. はルートゾーンの下のゾーンです。

  • example.orgorg. ゾーンの下のゾーンです。

  • foo.example.org. はサブドメインで、 example.org. の下のゾーンです。

  • 1.2.3.in-addr.arpa は 3.2.1.* の IP 空間に含まれるすべての IP アドレスを参照するゾーンです。

見て分かるように、ホスト名のより詳細な部分はその左側に現れます。 たとえば example.org.org. より限定的です。同様に org. はルートゾーンより限定的です。 ホスト名の各部分のレイアウトはファイルシステムに非常に似ています。 たとえば /dev はルートの下であることなどです。

22.11.3. ネームサーバを実行する理由

ネームサーバは通常二つの形式があります: 権威のあるネームサーバとキャッシュネームサーバです。

権威のあるネームサーバは以下の場合に必要です。

  • 問い合わせに対して信頼できる返答をすることで、 ある人が DNS 情報を世界に向けて発信したいとき。

  • example.org といったドメインが登録されており、 その下にあるホスト名に IP アドレスを割り当てる必要があるとき。

  • IP アドレスブロックが (IP からホスト名への) 逆引き DNS エントリを必要とするとき。

  • プライマリサーバがダウンしているかまたはアクセスできない場合に、 代わりに問い合わせに対してスレーブと呼ばれるバックアップネームサーバが返答しなければならないとき。

キャッシュネームサーバは以下の場合に必要です。

  • ローカルのネームサーバが、 外部のネームサーバに問い合わせするよりも、 キャッシュしてより速く返答できるとき。

  • ネットワークトラフィックの総量を減らしたいとき (DNS のトラフィックはインターネットトラフィック全体の 5% 以上を占めることが測定されています)

www.FreeBSD.org に対する問い合わせを発したとき、 リゾルバは大体の場合上流の ISP のネームサーバに問い合わせをして返答を得ます。 ローカルのキャッシュ DNS サーバがあれば、 問い合わせはキャッシュ DNS サーバによって外部に対して一度だけ発せられます。 情報がローカルに蓄えられるので、 追加の問い合わせはいずれもローカルネットワークの外側にまで確認しなくてもよくなります。

22.11.4. 動作のしくみ

FreeBSD では BIND デーモンは自明な理由から named と呼ばれます。

ファイル説明
namedBIND デーモン
ndcネームデーモンコントロールプログラム
/etc/namedbBIND のゾーン情報が置かれるディレクトリ
/etc/namedb/named.confデーモンの設定ファイル

ゾーンファイルは通常 /etc/namedb ディレクトリ内に含まれており、ネームサーバによって処理される DNS ゾーン情報を含んでいます。

22.11.5. BIND の起動

BIND はデフォルトでインストールされているので、 すべてを設定することは比較的単純です。

named デーモンが起動時に開始されることを保証するには、 /etc/rc.conf に以下の変更をいれてください。

named_enable="YES"

デーモンを手動で起動するためには (設定をした後で)

# ndc start

22.11.6. 設定ファイル

22.11.6.1. make-localhost の利用

次のコマンドが

# cd /etc/namedb
# sh make-localhost

ローカル逆引き DNS ゾーンファイルを /etc/namedb/localhost.rev に適切に作成することを確認してください。

22.11.6.2. /etc/namedb/named.conf

// $FreeBSD$
//
// 詳細については named(8) マニュアルページを参照してください。プライマリサーバ
// を設定するつもりなら、DNS がどのように動作するかの詳細を確実に理解してくださ
// い。単純な間違いであっても、影響をうける相手に対する接続を壊したり、無駄な
// インターネットトラフィックを大量に引き起こし得ます。

options {
        directory "/etc/namedb";

// "forwarders" 節に加えて次の行を有効にすることで、ネームサーバに決して自発的
// に問い合わせを発せず、常にそのフォワーダにたいして尋ねるように強制すること
// ができます:
//
//      forward only;

// あなたが上流のプロバイダ周辺の DNS サーバを利用できる場合、その IP アドレス
// をここに入力し、下記の行を有効にしてください。こうすれば、そのキャッシュの
// 恩恵にあやかることができ、インターネット全体の DNS トラフィックが減るでしょう。
/*
        forwarders {
                127.0.0.1;
        };
*/

コメントが言っている通り、上流のキャッシュの恩恵を受けるために forwarders をここで有効にすることができます。 通常の状況では、ネームサーバはインターネットの特定のネームサーバを調べて、 探している返答を見つけるまで再帰的に問い合わせを行います。 これが有効になっていれば、まず上流のネームサーバ (または 与えられたネームサーバ) に問い合わせて、 そのキャッシュを利用するでしょう。 問い合わせをする上流のネームサーバが極度に通信量が多く、 高速であった場合、これを有効にする価値があるかもしれません。

警告:

ここに 127.0.0.1 を指定しても動作 しません。 上流のネームサーバの IP アドレスに変更してください。

        /*
         * あなたと利用したいネームサーバとの間にファイアウォールがある場合、
         * 下記の quiery-source 指令を有効にする必要があるでしょう。
         * 過去の BIND のバージョンは常に 53 番ポートに問い合わせをしますが、
         * BIND 8.1 はデフォルトで非特権ポートを使用します。
         */
        // query-source address * port 53;

        /*
         * 砂場内で動作させている場合、ダンプファイルのために異なる場所を指定
         * しなければならないかもしれません。
         */
        // dump-file "s/named_dump.db";
};

// 注意: 下記は将来のリリースで対応されるでしょう。
/*
host { any; } {
        topology {
                127.0.0.0/8;
        };
};
*/

// セカンダリを設定することはより簡単な方法で、そのおおまかな姿が下記で説明さ
// れています。
//
// ローカルネームサーバを有効にする場合、このサーバが最初に尋ねられるように
// /etc/resolv.conf に 127.0.0.1 を入力することを忘れないでください。さらに、
// /etc/rc.conf 内で有効にすることも確認してください。

zone "." {
        type hint;
        file "named.root";
};

zone "0.0.127.IN-ADDR.ARPA" {
        type master;
        file "localhost.rev";
};

zone
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.INT" {
        type master;
        file "localhost.rev";
};

// 注意: 下記の IP アドレスを使用しないでください。これはダミーでありデモや文書
// だけを目的としたものです。
//
// セカンダリ設定の例です。少なくともあなたのドメインが属するゾーンに対するセカ
// ンダリになることは便利かもしれません。プライマリの責を負っている IP アドレス
// をネットワーク管理者に尋ねてください。
//
// 逆引き参照ゾーン (IN-ADDR.ARPA) を含めることを決して忘れないでください!
// (これは ".IN-ADDR.ARPA" を付け加えられたそれぞれの IP アドレスの最初のバイト
// の逆順です。)
//
// プライマリゾーンの設定をはじめる前に DNS および BIND がどのように動作するか
// 完全に理解してください。時々自明でない落し穴があります。それに比べるとセカン
// ダリを設定するのは単純です。
//
// 注意: 下記の例を鵜呑みにして有効にしないでください。:-) 実際の名前とアドレス
// を代わりに使用してください。
//
// 注意!!! FreeBSD は bind を砂場のなかで動かします (rc.conf 内の named_flags
// を参照してください)。セカンダリゾーンを含んだディレクトリは、bind によって
// 書き込み可能でなければなりません。次の手順が推奨されます:
//
//      mkdir /etc/namedb/s
//      chown bind:bind /etc/namedb/s
//      chmod 750 /etc/namedb/s

BIND を砂場 (sandbox) で (訳注: chroot をもちいて) 動作させるための詳細は 砂場で named を実行する を参照してください。

/*
zone "example.com" {
        type slave;
        file "s/example.com.bak";
        masters {
                192.168.1.1;
        };
};

zone "0.168.192.in-addr.arpa" {
        type slave;
        file "s/0.168.192.in-addr.arpa.bak";
        masters {
                192.168.1.1;
        };
};
*/

named.conf の中で、 上記は転送と逆引きゾーンのためのスレーブエントリの例です。

新しくサービスするそれぞれのゾーンについて、新規のエントリを named.conf に加えなければいけません。

たとえば example.org に対する最もシンプルなゾーンエントリは以下のようになります。

zone "example.org" {
	type master;
	file "example.org";
};

このゾーンは type 命令で示されているようにマスタで、ゾーン情報を file 命令で指示された /etc/namedb/example.org ファイルに保持しています。

zone "example.org" {
	type slave;
	file "example.org";
};

スレーブの場合、 ゾーン情報は特定のゾーンのマスタネームサーバから転送され、 指定されたファイルに保存されます。 マスタサーバが停止するか到達できない場合には、 スレーブサーバが転送されたゾーン情報を保持していて、 サービスできるでしょう。

22.11.6.3. ゾーンファイル

example.org に対するマスタゾーンファイル (/etc/namedb/example.org に保持されます) の例は以下のようになります。

$TTL 3600

example.org. IN SOA ns1.example.org. admin.example.org. (
                        5               ; Serial
                        10800           ; Refresh
                        3600            ; Retry
                        604800          ; Expire
                        86400 )         ; Minimum TTL

; DNS Servers
@       IN NS           ns1.example.org.
@       IN NS           ns2.example.org.

; Machine Names
localhost       IN A    127.0.0.1
ns1             IN A    3.2.1.2
ns2             IN A    3.2.1.3
mail            IN A    3.2.1.10
@               IN A    3.2.1.30

; Aliases
www             IN CNAME        @

; MX Record
@               IN MX   10      mail.example.org.

. が最後についているすべてのホスト名は正確なホスト名であり、 一方で . で終了しないすべての行はオリジンが参照されることに注意してください。 たとえば wwwwww + オリジン に展開されます。この架空のゾーンファイルでは、 オリジンは example.org. なので wwwwww.example.org. に展開されます。

ゾーンファイルの書式は次のとおりです。

recordname      IN recordtype   value

DNS レコードに使われる最も一般的なものは以下のとおりです。

SOA

ゾーン権威の起点

NS

権威のあるネームサーバ

A

ホストのアドレス

CNAME

別名としての正規の名称

MX

メールエクスチェンジャ

PTR

ドメインネームポインタ (逆引き DNS で使用されます)

example.org. IN SOA ns1.example.org. admin.example.org. (
                        5               ; Serial
                        10800           ; Refresh after 3 hours
                        3600            ; Retry after 1 hour
                        604800          ; Expire after 1 week
                        86400 )         ; Minimum TTL of 1 day
example.org.

このゾーンのオリジンでもあるドメイン名

ns1.example.org.

このゾーンに対して権威のあるプライマリネームサーバ

admin.example.org.

このゾーンの責任者。@ を置き換えた電子メールアドレスを指定します。 (admin.example.org になります)

5

ファイルのシリアル番号です。 これはファイルが変更されるたびに増加させる必要があります。 現在では多くの管理者は yyyymmddrr という形式をシリアル番号として使用することを好みます。 2001041002 は最後に修正されたのが 2001/04/10 で、後ろの 02 はその日で二回目に修正されたものであるということを意味するでしょう。 シリアル番号は、 それが更新されたときにスレーブネームサーバに対してゾーンを通知するので重要です。

@       IN NS           ns1.example.org.

これは NS エントリです。 このゾーンに対して権威のある返答を返すネームサーバはすべて、 このエントリを一つ有していなければなりません。 ここにある @example.org. を意味します。 @ はオリジンに展開されます。

localhost       IN A    127.0.0.1
ns1             IN A    3.2.1.2
ns2             IN A    3.2.1.3
mail            IN A    3.2.1.10
@               IN A    3.2.1.30

A レコードはマシン名を示します。 上記のように ns1.example.org3.2.1.2 に結びつけられるでしょう。 ふたたびオリジンを示す @ がここに使用されていますが、これは example.org3.2.1.30 に結び付けられることを意味しています。

www             IN CNAME        @

CNAME レコードは通常マシンに別名を与えるときに使用されます。 例では www はオリジン、すなわち example.org (3.2.1.30) のアドレスをふられたマシンへの別名を与えます。 CNAME はホスト名の別名、 または複数のマシン間で一つのホスト名をラウンドロビン (訳注: 問い合わせがあるたびに別の IP アドレスを返すことで、 一台にアクセスが集中することを防ぐ手法) するときに用いられます。

@               IN MX   10      mail.example.org.

MX レコードは、 ゾーンに対してどのメールサーバがやってきたメールを扱うことに責任を持っているかを示します。 mail.example.org はメールサーバのホスト名で、10 はメールサーバの優先度を示します。

優先度が 3,2 または 1 などのメールサーバをいくつも置くことができます。 example.org へ送ろうとしているメールサーバははじめに一番優先度の高いメールサーバに接続しようとします。 そして接続できない場合、二番目に優先度の高いサーバに接続しようとし、 以下、メールが適切に配送されるまで同様に繰り返します。

in-addr.arpa ゾーンファイル (逆引き DNS) に対しても A または CNAME の代わりに PTR エントリが用いられることを除けば、 同じ書式が使われます。

$TTL 3600

1.2.3.in-addr.arpa. IN SOA ns1.example.org. admin.example.org. (
                        5               ; Serial
                        10800           ; Refresh
                        3600            ; Retry
                        604800          ; Expire
                        3600 )          ; Minimum

@       IN NS   ns1.example.org.
@       IN NS   ns2.example.org.

2       IN PTR  ns1.example.org.
3       IN PTR  ns2.example.org.
10      IN PTR  mail.example.org.
30      IN PTR  example.org.

このファイルは上記の架空のドメインの IP アドレスからホスト名への対応を与えます。

22.11.7. キャッシュネームサーバ

キャッシュネームサーバはどのゾーンに対しても権威をもたないネームサーバです。 キャッシュネームサーバは単に自分で問い合わせをし、 後で使えるように問い合わせの結果を覚えておきます。 これを設定するには、ゾーンを何も含まずに、 通常通りネームサーバを設定してください。

22.11.8. 砂場で named を実行する

セキュリティを強めるために named(8) を非特権ユーザで実行し、 砂場のディレクトリ内に chroot(8) して実行したいと思うかもしれません。 こうすると named デーモンは砂場の外にはまったく手を出すことができません。 named が乗っ取られたとしても、 これによって起こりうる損害が小さくなるでしょう。 FreeBSD にはデフォルトで、そのための bind というユーザとグループがあります。

注記:

多くの人々は namedchroot するように設定する代わりに、 jail(8) 環境内で named を実行することを奨めるでしょう。 この節ではそれは扱いません。

named は砂場の外 (共有ライブラリ、ログソケットなど) にアクセスできないので、 named を正しく動作させるためにいくつもの段階を経る必要があります。 下記のチェックリストにおいては、砂場のパスは /etc/namedb で、 このディレクトリの内容には何も手を加えていないと仮定します。 root 権限で次のステップを実行してください。

  • named が存在することを期待しているディレクトリをすべて作成します。

    # cd /etc/namedb
    # mkdir -p bin dev etc var/tmp var/run master slave
    # chown bind:bind slave var/*1

    1

    これらのディレクトリに対して named が必要なのは書き込み権限だけなので、それだけを与えます。

  • 基本ゾーンファイルと設定ファイルの編集と作成を行います。

    # cp /etc/localtime etc1
    # mv named.conf etc && ln -sf etc/named.conf
    # mv named.root master
    
    # sh make-localhost && mv localhost.rev localhost-v6.rev master
    # cat > master/named.localhost
    $ORIGIN localhost.
    $TTL 6h
    @	IN	SOA	localhost. postmaster.localhost. (
    			1	; serial
    			3600	; refresh
    			1800	; retry
    			604800	; expiration
    			3600 )	; minimum
    	IN	NS	localhost.
    	IN	A		127.0.0.1
    ^D

    1

    これは namedsyslogd(8) に正しい時刻でログを書き込むことを可能にします。

  • 4.9-RELEASE より前のバージョンの FreeBSD を使用している場合、 静的リンクされた named-xfer を構築し、砂場にコピーしてください。

    # cd /usr/src/lib/libisc
    # make cleandir && make cleandir && make depend && make all
    # cd /usr/src/lib/libbind
    # make cleandir && make cleandir && make depend && make all
    # cd /usr/src/libexec/named-xfer
    # make cleandir && make cleandir && make depend && make NOSHARED=yes all
    # cp named-xfer /etc/namedb/bin && chmod 555 /etc/namedb/bin/named-xfer1

    静的リンクされた named-xfer をインストールしたら、 ソースツリーの中にライブラリまたはプログラムの古くなったコピーを残さないように、 掃除する必要があります。

    # cd /usr/src/lib/libisc
    # make cleandir
    # cd /usr/src/lib/libbind
    # make cleandir
    # cd /usr/src/libexec/named-xfer
    # make cleandir

    1

    このステップは時々失敗することが報告されています。 もし失敗した場合、次のコマンドを実行してください。

    # cd /usr/src && make cleandir && make cleandir

    そして /usr/obj ツリーを削除します。

    # rm -fr /usr/obj && mkdir /usr/obj

    これはソースツリーからすべての がらくた を一掃します。 もう一度上記の手順を行うと、今度はうまく動作するでしょう。

    バージョン 4.9-RELEASE 以降の FreeBSD を使用している場合 /usr/libexec にある named-xfer のコピーはデフォルトで静的リンクされています。 砂場にコピーするために単純に cp(1) が使えます。

  • named が見ることができ、 書き込むことのできる dev/null を作成します。

    # cd /etc/namedb/dev && mknod null c 2 2
    # chmod 666 null
  • /etc/namedb/var/run/ndc から /var/run/ndc へのシンボリックリンクを作成します。

    # ln -sf /etc/namedb/var/run/ndc /var/run/ndc

    注記:

    これは単に ndc(8) を実行するたびに -c オプションを指定しなくてもよいようにするだけです。 /var/run の中身は起動時に削除されるため、 これが有用だと思うなら、このコマンドをルートの crontab に @reboot オプションを指定して追加してください。 詳細については crontab(5) を参照してください。

  • named が書き込める追加の log ソケットを作成するように syslogd(8) を設定します。 これを行うためには、/etc/rc.conf 内の syslogd_flags 変数に -l /etc/namedb/dev/log を加えてください。

  • 次の行を /etc/rc.conf に加えて named が起動し、 自身を砂場内に chroot するように調整します

    named_enable="YES"
    named_flags="-u bind -g bind -t /etc/namedb /etc/named.conf"

    注記:

    設定ファイル /etc/named.conf砂場のディレクトリに対して相対的な フルパスで表されることに注意してください。 つまり、上記の行で示されたファイルは実際には /etc/namedb/etc/named.conf です。

次のステップは named がどのゾーンを読み込むか、 そしてディスク上のどこにゾーンファイルがあるのかを知るために /etc/namedb/etc/named.conf を編集することです。 下記に例をコメントを加えて示します (ここで特にコメントされていない内容については、 砂場の中で動作させない DNS サーバの設定と同じです)。

options {
        directory "/";1
        named-xfer "/bin/named-xfer";2
        version "";		// Don't reveal BIND version
        query-source address * port 53;
};
// ndc control socket
controls {
        unix "/var/run/ndc" perm 0600 owner 0 group 0;
};
// Zones follow:
zone "localhost" IN {
        type master;
        file "master/named.localhost";3
        allow-transfer { localhost; };
        notify no;
};
zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "master/localhost.rev";
        allow-transfer { localhost; };
        notify no;
};
zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int" {
	type master;
	file "master/localhost-v6.rev";
	allow-transfer { localhost; };
	notify no;
};
zone "." IN {
        type hint;
        file "master/named.root";
};
zone "private.example.net" in {
        type master;
        file "master/private.example.net.db";
	allow-transfer { 192.168.10.0/24; };
};
zone "10.168.192.in-addr.arpa" in {
        type slave;
        masters { 192.168.10.2; };
        file "slave/192.168.10.db";4
};

1

directory/ を指定します。 named が必要とするファイルはすべてこのディレクトリにあります。 (この指定は 通常の (訳注: 砂場内で動作させない) ユーザにとっての /etc/namedb と等価です)。

2

named-xfer バイナリへの (named にとっての) フルパスを指定します。 named はデフォルトで named-xfer/usr/libexec から探すようにコンパイルされているので、これが必要です

3

このゾーンに対するゾーンファイルを named が見つけられるようにファイル名を (上記と同様に directory からの相対パスで) 指定します。

4

このゾーンに対するゾーン情報がマスタサーバからが転送されたあとに、 named がゾーンファイルのコピーを書き込むファイル名を (上記と同様に directory からの相対パスで) 指定します。これが、上記のように設定段階で slave ディレクトリの所有者を bind に変更する理由です。

上記のステップを完了したら、サーバを再起動するか syslogd(8) を再起動し、named(8) を起動してください。その際、 syslogd_flags および named_flags に新たに指定したオプションが有効になっていることを確かめてください。 これで named を砂場のなかで動作させることができているはずです!

22.11.9. セキュリティ

BIND は DNS の最も一般的な実装ではありますが、 常にセキュリティ問題を抱えています。 問題になり得る、また悪用可能なセキュリティホールが時々みつかります。

現在のインターネットおよび FreeBSD のセキュリティ問題について常に最新の情報を得るために CERT および freebsd-security-notifications を購読するとよいでしょう。

ヒント:

問題が生じたとしても、 最新のソースからビルドした named を用意しておけば、 問題にならないかもしれません。

22.11.10. さらなる情報源

BIND/named のマニュアルページ: ndc(8) named(8) named.conf(5)

本文書、および他の文書は ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/ からダウンロードできます。

FreeBSD に関する質問がある場合には、 ドキュメント を読んだ上で <questions@FreeBSD.org> まで (英語で) 連絡してください。

本文書に関する質問については、 <doc@FreeBSD.org> まで電子メールを (英語で) 送ってください。