bind-8 で、外向けと内向けの DNS を 1 台で運用する


(1998/06/29 作成)

はじめに

今までは、デュアルホームのファイアーウォール上で外向け、内部 LAN 上のホストで内向けと、2 台の DNS を運用してきました。bind-8 になって、これを 1 台で運用できるようになったという話があり、さっそくやってみました。Linux-Users-ML の須藤 清一さんと石塚@杉並さんには大変お世話になりました。この場を借りてお礼申し上げますm(__)m

一応動いているような気がするんですけど、こういう風にしたらもっといいよ、などのアドバイスがありましたら hotta@net-newbie.comまでお願いいたしますm(__)m

プラットフォームは Linux Slackware 3.4 (kernel 2.0.33) です。bind-8.1.2 のインストールはbind-8 のインストールメモを参照してください。

初期導入であればいろいろ試行錯誤もできるんでしょうが、すでに DNS や sendmail が稼働中なので、思い切った実験ができなくてつらいところです。と言いつつも、まともに動かなくて結局何度か試行錯誤する羽目になってしまいましたが(^^;

参考資料:src/bin/named/named.conf(サンプル)の和訳(再掲)。訳しといてよかった(^^;

コンセプトとしては、

内部、外部ともドメイン名を同じにする
(内部をサブドメインにしない)

ことを目標にしています。これを実現するためにはどうも named を 2 つ立ち上げるしかなさそうです。内部をサブドメインにしてもよいのであれば、allow-query ディレクティブを利用して named を 1 つで運用することもできます。これに関しては、花井さんのページを参照してください。

制限事項

内側と外側が完全に独立したゾーンとなっているため、ファイアーウォールの外側の自ドメインに属するパブリックなアドレスを持つホストに関しては、内側からは引けません。しょうがないのでこの分だけは、named-inner 配下のゾーンファイルにパブリックなアドレスを直に書いています。

実際の設定

  1. 現在の状態を確認。

    ns:~# ps ax|grep named
    27224  ?  S     0:03 /usr/sbin/named 
    

    外向けの named が稼働中です。

  2. named.conf を 2 つ作る。

    分かりやすいように、内向けと外向けの named.conf を、それぞれ named-inner.conf と named-outer.conf としました。ついでに設定ファイルを格納するためのディレクトリも 2 つに分けました。ホスト ns は、これまで外向けの DNS が動いていたファイアーウォール・マシンです。ここに内向けサーバを追加します。

    ns:~# cd /etc
    ns:/etc# cp named.conf named-inner.conf
    ns:/etc# cp named.conf named-outer.conf
    ns:/etc# mkdir namedb-inner namedb-outer
    
  3. named-inner.conf(内向け用設定ファイル) の編集。

    内側から見ると、hoge は 192.168/16 のアドレスを持つノードで構成されているように見えます。

    //
    //  named-inner.conf
    //
    options {
        directory "/etc/namedb-inner";  //内向け用設定ファイルのディレクトリ
        listen-on   {
            127.0.0.1;
            192.168.0.254;              //内側からのアクセスのみを許可
        };
        pid-file "/var/run/named.pid-inner";  //ここがミソ
    };
    
    zone "." {                         //キャッシュファイルの設定
        type hint;                     ※最初はいらないと思っていたが、
        file "root.cache";               これがないと内側から外の名前を
    };                                   引けなくなる。
    
    zone "localhost" {                 //localhost 用正引き設定。
        type master;
        file "localhost";
    };
    zone "0.0.127.IN-ADDR.ARPA" {      //localhost 用逆引き設定。
        type master;
        file "0.0.127.in-addr.arpa";
    };
    
    zone "hoge" {       //内側のドメイン用正引き設定。
        type master;                  ※プライベートアドレスおよび
        file "hoge";        自ドメイン内のパブリックな
    };                                  アドレスを登録したもの。
        //
        //      本来は、自ドメイン内のパブリックなアドレスの
        //      逆引き用ゾーンを設定するべきです。
        //
    zone "0.168.192.IN-ADDR.ARPA" {     //内側のドメイン用逆引き設定1。
        type master;
        file "0.168.192.in-addr.arpa";
    };
    zone "3.168.192.IN-ADDR.ARPA" {    //内側のドメイン用逆引き設定2。
        type master;
        file "3.168.192.in-addr.arpa";
    };
    zone "4.168.192.IN-ADDR.ARPA" {    //内側のドメイン用逆引き設定3。
        type master;
        file "4.168.192.in-addr.arpa";
    };
    zone "5.168.192.IN-ADDR.ARPA" {    //内側のドメイン用逆引き設定4。
        type master;
        file "5.168.192.in-addr.arpa";
    };
    
  4. named-outer.conf(外向け用設定ファイル) の編集。

    //
    // named-outer.conf
    //
    options {
        directory "/etc/namedb-outer";  //外向け用設定ファイルのディレクトリ
        listen-on   {
            //  127.0.0.1;      //  これを記述すると、named の(再)起動に
                                //  2 分以上かかるので、やめました。
            210.xxx.yyy.zzz;            //外側からのアクセスのみを許可。
        };
        pid-file "/var/run/named.pid-outer";  //ここがミソ
    };
    
    zone "." {                          //キャッシュファイルの設定
        type hint;
        file "root.cache";
    };
        //
        //  外側にも localhost が必要です。
        //  これがないと、外側からは localhost が引けなくなります。
        //
    zone "localhost" {                 //localhost 用正引き設定。
        type master;
        file "localhost";
    };
    zone "0.0.127.IN-ADDR.ARPA" {      //localhost 用逆引き設定。
        type master;
        file "0.0.127.in-addr.arpa";
    };
    
    zone "hoge" {           //外側のドメイン用正引き設定。
        type master;                      ※もちろんパブリックなアドレス
        file "hoge";            しか登録しちゃだめよ。
    };
    zone "zzz.yyy.xxx.210.IN-ADDR.ARPA" { //外側のドメイン用逆引き設定。
        type master;
        file "zzz.yyy.xxx.210.in-addr.arpa";
    };
    
  5. ndc も 2 重にする。

    named を操作するためのフロントエンドとして ndc というシェルスクリプトがありますが、named を同時に 2 つたち上げるために、これも 2 つ必要になると思い、新しく明示的に 2 つ作りました。これらの違いは、pid ファイル(2 重起動防止用)のファイル名と、起動時に明示的に指定する boot ファイル名です。

    ns:~# cd /usr/sbin/
    ns:/usr/sbin# cp ndc ndc-inner
    ns:/usr/sbin# cp ndc ndc-outer
    ns:/usr/sbin# vi ndc-inner       ←内向け用
    (変更点は以下の通りです)
    ns:/usr/sbin# diff ndc-inner ndc
    10c10
    < PIDFILE=/var/run/named.pid-inner
    ---
    > PIDFILE=/var/run/named.pid
    52c52
    <               /usr/sbin/named -b /etc/named-inner.conf && {
    ---
    >               /usr/sbin/named && {
    73c73
    <               /usr/sbin/named -b /etc/named-inner.conf && {
    ---
    >               /usr/sbin/named && {
    ns:/usr/sbin# vi ndc-outer       ←外向け用
    ns:/usr/sbin# diff ndc-outer ndc
    10c10
    < PIDFILE=/var/run/named.pid-outer
    ---
    > PIDFILE=/var/run/named.pid
    52c52
    <               /usr/sbin/named -b /etc/named-outer.conf && {
    ---
    >               /usr/sbin/named && {
    73c73
    <               /usr/sbin/named -b /etc/named-outer.conf && {
    ---
    >               /usr/sbin/named && {
    ns:/usr/sbin# chmod +x ndc-*     ←実行属性を付けておきます。
    ns:/usr/sbin# ls -l ndc*
    -rwxr-xr-x   1 root     root         1518 Jun 17 18:32 ndc*
    -rwxr-xr-x   1 root     root         1574 Jun 29 11:51 ndc-inner*
    -rwxr-xr-x   1 root     root         1575 Jun 29 11:50 ndc-outer*
    
  6. 古い外向け DNS を終了させます。

    ns:/usr/sbin# ndc stop
    ns:/usr/sbin# cd /var/run
    ns:/var/run# ls
    inetd.pid        sendmail.pid     utmp
    klogd.pid        syslogd.pid
    (ちゃんと死んでいるか確認)
    ns:/var/run# ps ax|grep named|grep -v grep
    ns:/var/run# 
    
  7. 新しい外向け/内向け DNS を起動します。

    ns:/var/run# ndc-outer start
    ns:/var/run# ndc-inner start
    ns:/var/run# ls
    inetd.pid        named.pid-inner  sendmail.pid     utmp
    klogd.pid        named.pid-outer  syslogd.pid
    ns:/var/run# ps ax|grep named|grep -v grep
      738  ?  S     0:00 /usr/sbin/named -b /etc/named-outer.conf 
      850  ?  S     0:00 /usr/sbin/named -b /etc/named-inner.conf 
    

    2 つともちゃんと動いているようです。

  8. 外側からの動作確認

    dmz1:~# nslookup - ns
    Default Server:  ns.hoge
    Address:  210.xxx.yyy.zzz
    Aliases:  zzz.yyy.xxx.210.in-addr.arpa
    
    > set q=MX
    > hoge
    Server:  ns.hoge
    Address:  210.xxx.yyy.zzz
    Aliases:  zzz.yyy.xxx.210.in-addr.arpa
    
    hoge        preference = 10, mail exchanger = ns.hoge
    hoge        nameserver = ns.hoge
    hoge        nameserver = ns-tk012.ocn.ad.jp
    ns.hoge     internet address = 210.xxx.yyy.zzz
    ns-tk012.ocn.ad.jp      internet address = 203.139.160.74
    
    > server1
    Server:  ns.hoge
    Address:  210.xxx.yyy.zzz
    Aliases:  zzz.yyy.xxx.210.in-addr.arpa
    
    *** ns.hoge can't find server1: Non-existent host/domain
    (内側の正引きはできません)
    > 192.168.0.15
    Server:  ns.hoge
    Address:  210.xxx.yyy.zzz
    Aliases:  zzz.yyy.xxx.210.in-addr.arpa
    
    *** ns.hoge can't find 192.168.0.15: Non-existent host/domain
    (内側の逆引きもできません)
    
  9. 内側からの動作確認

    server1:~# nslookup - ns
    Default Server:  ns.hoge
    Address:  192.168.0.254
    
    > set q=MX
    > hoge
    Server:  ns.hoge
    Address:  192.168.0.254
    
    hoge        preference = 10, mail exchanger = exp5800.hoge
    hoge        nameserver = ns.hoge
    exp5800.hoge        internet address = 192.168.0.114
    ns.hoge     internet address = 192.168.0.254
    
    > server1
    Server:  ns.hoge
    Address:  192.168.0.254
    
    Name:    server1.hoge
    Address:  192.168.0.1
    
    > 192.168.0.1
    Server:  ns.hoge
    Address:  192.168.0.254
    
    Name:    server1.hoge
    Address:  192.168.0.1
    
    > dmz1
    Server:  ns.hoge
    Address:  192.168.0.254
    
    Name:    dmz1.hoge
    Address:  210.xxx.yyy.www
    (ちゃんと外側も引けます)
    
  10. rc.* ファイルの書き換え

    このままではリブートすると元の木阿弥ですから、忘れないうちにブート時の自動起動スクリプトを変更しておきます。

    ns:~# cd /etc/rc.d/
    ns:/etc/rc.d# grep named *
    rc.inet2:if [ -f ${NET}/named ]; then
    rc.inet2:  echo -n " named"
    rc.inet2:  ${NET}/named
    ns:/etc/rc.d# cp rc.inet2 rc.inet2.orig
    ns:/etc/rc.d# vi rc.inet2
    ns:/etc/rc.d# diff rc.inet2 rc.inet2.orig 
    49,50c49
    <   ${NET}/named -b /etc/named-inner.conf
    <   ${NET}/named -b /etc/named-outer.conf
    ---
    >   ${NET}/named
    

    この後リブートし、正常に動作することを確認しました。

古い DNS 内向けサーバの撤去

ホスト名をごまかすのであれば DNS の CNAME でどうにでもなりますが、DNS サーバ自体の IP アドレスは、通常各クライアントにおいて IP アドレスで設定されています(でないと鶏と卵になってしまいますよね(^^;)。LAN 上の各クライアントに直書きで設定されている IP アドレスを片っ端から変えて回るのはたまりません。ここでは、Linux の IP-Aliasing というやつを使って、新しい DNS サーバを古い DNS サーバに見せかけるということで逃げようと思います。

  1. カーネル再構築

    make menuconfig で

        Network options ---> Network aliasing と
                             aliasing support 
        

    を [*] にして、カーネルを再構築します。よくわからない方はカーネルの再構築を参照してください。

    無事に終了したら、マシンをリブートします。

    念のため、リブート後に IP Aliasing が有効になっているかどうかをチェックします。

    ns:~# ls /proc/net/alias*
    /proc/net/alias_types  /proc/net/aliases
        

    この 2 つができていました。

  2. IP エイリアスの設定

    例によってさっぱりわからんので、JFの部屋を見たら、Linux-IP-Alias-mini-HOWTOというのがありました。さすが JF です。で、これに従って設定します。特に難しくもなさそうです。

    ns:~# ifconfig -a        ←設定前の状況
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
              UP BROADCAST LOOPBACK RUNNING  MTU:3584  Metric:1
              RX packets:14 errors:0 dropped:0 overruns:0
              TX packets:14 errors:0 dropped:0 overruns:0
    
    eth0      Link encap:10Mbps Ethernet  HWaddr 00:A0:24:94:6B:D8
              inet addr:192.168.0.254  Bcast:192.168.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:5483 errors:0 dropped:0 overruns:0
              TX packets:2167 errors:0 dropped:0 overruns:0
              Interrupt:10 Base address:0x7040 
    
    eth1      Link encap:10Mbps Ethernet  HWaddr 00:60:97:50:00:E1
              inet addr:210.161.96.66  Bcast:210.161.96.79  Mask:255.255.255.240
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1458 errors:0 dropped:0 overruns:0
              TX packets:1843 errors:0 dropped:0 overruns:0
              Interrupt:10 Base address:0x7000 
    
    ns:~# /sbin/ifconfig eth0:0 192.168.0.8
    
    (192.168.0.8 は、現在存在しないノードです。)
    
    ns:/usr/src/linux# ifconfig
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
              UP BROADCAST LOOPBACK RUNNING  MTU:3584  Metric:1
              RX packets:40 errors:0 dropped:0 overruns:0
              TX packets:40 errors:0 dropped:0 overruns:0
    
    eth0      Link encap:10Mbps Ethernet  HWaddr 00:A0:24:94:6B:D8
              inet addr:192.168.0.254  Bcast:192.168.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:7211 errors:0 dropped:0 overruns:0
              TX packets:2496 errors:0 dropped:0 overruns:0
              Interrupt:10 Base address:0x7040 
    
    eth0:0    Link encap:10Mbps Ethernet  HWaddr 00:A0:24:94:6B:D8
              inet addr:192.168.0.8  Bcast:192.168.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0
              TX packets:0 errors:0 dropped:0 overruns:0
    
    eth1      Link encap:10Mbps Ethernet  HWaddr 00:60:97:50:00:E1
              inet addr:210.161.96.66  Bcast:210.161.96.79  Mask:255.255.255.240
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1315 errors:0 dropped:0 overruns:0
              TX packets:1672 errors:0 dropped:0 overruns:0
              Interrupt:10 Base address:0x7000 
        
  3. 動作確認

    ns:~# nslookup - 192.168.0.8
    (しばらくだんまりとなって、)
    *** Can't find server name for address 192.168.0.8: No response from server
    *** Default servers are not available
        

    これは、named で 192.168.0.8 を listen していないからです。追加しましょう。

    /etc/named-inner.conf の options - listen-on のエントリに、192.168.0.8 を追加して ndc-inner reload を行います。今後はちゃんと引けるようになりました。

  4. 旧 DNS サーバの撤去

    ダウンタイムを極力0にしたいので、ここは注意深く行いました。

    ということで、ダウンタイム 20 秒ほどで無事に移行できました。

  5. ちょっとヒヤリ。

    無事に移行を終え、このドキュメントを更新している時、確認のために ns 上で nslookup - server2(旧 DNS サーバのホスト名)とやるとだんまりになってしまいます。アレッと思って ping server2(自分自身の eth0:0) とやると、やはり応答なし。変だなあ、他のノードからの ping には返事してくれるのに?

    これは経路の問題でした。

    ns:~# route add -host 192.168.0.23 dev eth0:0
        

    とやることでうまくいきました。うーん奥が深い。前述のLinux-IP-Alias-mini-HOWTOには記述があったので、/etc/rc.d/rc.inet1 には登録しておいたんですけどね。