自宅DynamicDNS(BIND)の設定(SuSE編)


おやじが自宅サーバを始めたころは日本語で使用できるDDNSが少なく、DiCEのサイト一覧から見つけたZive.orgさんに長いことお世話になってきました。しかしながら、2005年に入りZiveさんが有料化の検討を開始し、プレアナウンスの内容では費用も契約プロバイダのDDNSサービスなら独自ドメインが使える額とのことで、これではサブドメインでZiveさんのお世話になる理由がなくなってしまいます。
と言うことで、この先同じような問題が発生するのも煩わしいのとランニングコストを考えて、この際なので新たに独自ドメインを取得して自分でDynamicDNSを動かしてしまうことにしました。当然、固定IPにしてしまえばわざわざこんな面倒くさいことをしなくても済むのですが、諸般の事情からメインのプロバイダを変更できないことと、当該プロバイダの固定IPサービス料金が高いため、サブプロバイダとして導入している固定IPの回線を使用してDDNSを動かすことにしました。

■DynamicDNS(BIND)の概略動作

BINDによるDynamicDNSに関しては、こちらに詳しく書かれており参考にさせてもらいました。概略の動作としては、新たに取得したドメインを既存の固定IPに割り付け、動的IPの回線のIPアドレスをルータからスクリプトで検出し、それを元にサブドメインの外向きのzoneファイルを書き換えるという動きです。おやじ宅のDDNSの基本的な動かし方は以下のとおりです。

  1. 新たにDDNS用のドメインを取得する。ここでは説明上、既存の固定IP用のドメインを example.com、DDNS用のドメインを examplex.comとする。なお、利用するサブドメインは「acorn.examplex.com」とする。

  2. DDNS用ドメイン(examplex.com)を既存の固定IPでレジストラに登録する。これにより、既存の example.comとexamplex.comは同じ固定IPにマッピングされる。

  3. 動的IPアドレスの書き換えは、ルータからスクリプトでアドレスを検出し、変化があればBINDのnsupdateコマンドを利用して行う。

  4. DDNSのIPの設定をBINDのnsupdateコマンドで行う場合、内向きと外向きで同じゾーンが存在するとnamed.confで定義されている最初のゾーン、即ち内向きのzoneファイルを変更してしまうため外向きの動的IP用のサブドメイン名の登録ができない。そこで対策として、内向きと外向きを別々のデーモンとして2つ動作させ、かつ、それぞれのデーモンがlistenするアドレスを変えることにより、外向きのデーモン用のアドレスを指定して外向きのzoneファイルを書き換えることにした。
    ここで使用する内向き、外向きDNS用の二つのアドレスは、WWWやFTPのIPアドレスベースのバーチャルホストで使用している二つのアドレス(LANに付与した仮想アドレス)をそのまま利用し、主に固定IPのドメインで使用しているアドレスを外向き用に、動的IPのドメインで使用しているアドレスを内向きDNSで使用した。別にDNS専用に仮想アドレスを容易しても良いが、管理が増えるだけなので流用することにした。

■BINDの設定

BINDはデフォルトではインストールされませんので、インストールできていなかったらYaSTでインストールしてください。以下、ステップ毎に設定と動作確認していきます。

◆名前解決の遅延対策

SuSEのBINDはデフォルトでipv6対応になっており、ipv6でつながっていない環境でそのまま使用すると、.jpドメインの名前解決が異常に遅くなる現象が発生するとのことです。ずいぶん悩まされましたが、ipv6を使わない場合はBINDで無効にしてやればipv6での名前解決に行かずに、この問題が解消されるとのこと。
解決策としては、ipv6 を disable した RPM を作成してインストールしてもよいのですが、/etc/modules.conf.local (カーネル2.4ならmodules.confでもよいが、カーネル2.6では未サポートのため変更)/etc/modprobe.conf.localに以下のように追加してシステムを再起動すれば、ipv6機能が停止して名前解決が早くなります。(参考:The Unofficial Fedora FAQ 日本語版 - Fedora Core 2用)

# vi /etc/modules.conf.local
# vi /etc/modprobe.conf.local

# Turn off IPv6
alias net-pf-10 off
alias ipv6 off


「Esc」、「:」、「w」、「q」で保存。

◆BINDの二重起動の設定

SuSE の起動スクリプトは、YaSTと連携して動作するようになっており非常に複雑です。少し調べたところ、SuSEのBINDの起動スクリプト関係は、SuSE9.0 -> 9.1 -> 9.2 と複雑化しており、SuSE9.0はある程度見通せますが、SuSE9.2になるとあちこちに処理が飛んでいるため非常にわかりにくくなっています。おやじは、SuSE9.0では起動スクリプト(/etc/init.d/named)の改造を、SuSE9.2では起動スクリプト(/etc/init.d/named)の改造と更に外向きデーモン用のnamed.conf関係のチェックスクリプト(/usr/share/bind/createNamedConfIncludeo)をベースのスクリプトを改造して作成することで対処しました。SuSE9.1用は、今後使用することもないので未作成です。今後のバージョンアップを考えると、割り切ってchrootを前提にしてchroot動作に必要なファイル類は手動でコピーするようにして、スクリプトを簡略化してしまった方が正解かもしれません。
二重起動用の各ファイルを作成するパッチを用意してあるので、こちらからダウンロードして利用してください。
ダウンロードしたパッチを解凍し、ベースファイルとバージョン毎に用意してあるパッチを使って外向きデーモン用のファイルを作成します。SuSE9.0では起動スクリプトとsysconfigのデータを、SuSE9.2では更にnamedo.conf関係のチェックスクリプトを作成する。

# tar zxfv ddns-1.1.tar.gz
# cd ddns-1.1
# cp -p /etc/init.d/named /etc/init.d/named.bak
# patch /etc/init.d/named ./9.x/init.named.patch
# cp -p /etc/sysconfig/named /etc/sysconfig/namedo
# patch /etc/sysconfig/namedo ./9.x/sysconfig.named.patch
# cp -p /usr/share/bind/createNamedConfInclude /usr/share/bind/createNamedConfIncludeo
# patch /usr/share/bind/createNamedConfIncludeo ./9.2/createNamedConfInclude.patch

◆事前準備

設定前に、外向きデーモン用の基本的なファイルをベースのファイルから作成します。作成するのは以下のファイルです。

  1. /etc/namedo.conf --------- 外向きデーモン用のconfファイル
  2. /etc/namedo.conf.include --- 外向きデーモン用の追加confファイル
  3. /var/lib/namedo/ --------- 外向きデーモン用chrootディレクトとファイル(最後のコマンドでchrootディレクトリの名称を変更。忘れると起動できないので要注意。)

# cp -p /etc/named.conf /etc/namedo.conf
# cp -p /etc/named.conf.include /etc/namedo.conf.include
# cp -pr /var/lib/named /var/lib/namedo
# mv /var/lib/namedo/var/lib/named /var/lib/namedo/var/lib/namedo

◆基本動作の設定

通常、DNS の基本的な動作の設定は、YaST の /etc/sysconfig エディターで行いますが今回は全て手動で行いました。
今までは、view文により内向きと外向きの設定をnamed.conf一つで書いていましたが、前述のようにDDNSでnsupdateコマンドで登録アドレスを変更する場合、同じゾーンファイルがnamed.conf内にあるとうまく動作しません。従って、今回は内向き用にnamed.confを外向き用にnamedo.confをそれぞれ作成し、別々のデーモンとして起動しました。以下にchroot時のファイルの関係を示します。

 /var/lib/named/ ・・・・・・・・・各ゾーンファイルを置くディレクトリ
       |    |-- named.d/
       |    |     |-- rndc.access.conf ・YaSTでIncludeするファイルを指定。デフォルトで
       |    |                             rndcに関する設定ファイルがincludeされている。
       |    |-- etc/
       |    |     |--named.conf
       |    |
       |    |-- master/
       |    |     |-- example.zive.net.zone
       |    |     |-- example.com.local
       |    |     |-- acorn.examplex.com.local
       |    |     |-- 192.168.1.zone
       |    |
       |    |-- slave/
       |    |
       |    |-- root.hint
       |    |-- localhost.zone
       |    |-- 127.0.0.zone
       |
       |-/namedo/ ・・・・・・・・・各ゾーンファイルを置くディレクトリ
            |-- named.d/
            |     |-- rndc.access.conf ・YaSTでIncludeするファイルを指定。デフォルトで
            |                             rndcに関する設定ファイルがincludeされている。
            |-- etc/
            |     |-- namedo.conf
            |
            |-- master/
            |     |-- example.com.zone
            |
            |-- dyn/
                  |-- examplex.com.zone

◆named.conf/namedo.conf の設定

前述のとおり、おやじは YaST を使用しないことにしましたので、下記内容を、named.conf/namedo.conf に直接記述しました。 SuSE のデフォルトは尊重しつつも、バッサリと今までの設定を継承したところもありあまり一貫性はありません。なお、named.conf/namedo.confの編集は、/etc配下のファイルで行うようにしてください。chrootディレクトリ配下(/var/lib/named等)のファイルを変更しても、named起動時に/etc配下のファイルがコピーされて元に戻ってしまいます。

[named.conf]
options {
    listen-on { 127.0.0.1; 192.168.1.100; };
    directory "/var/lib/named";
    dump-file "/var/log/named_dump.db";
    statistics-file "/var/log/named.stats";
    notify no;
    allow-query { 127.0.0.1; 192.168.1.0/24; };
    allow-transfer { 127.0.0.1; 192.168.1.0/24; };
    forwarders { 1.2.3.4; 5.6.7.8; };
    forward only;
};

logging {
    # Log queries to a file limited to a size of 100 MB.
    channel query_logging {
        file "/var/log/named_querylog" versions 3 size 100M;
        print-time yes;                 // timestamp log entries
        severity info;
        print-category yes;
    };
    category queries {
        query_logging;
    };
    # Don't log lame server messages.
    category lame-servers { null; };
};

# ルートのゾーン設定
zone "." in {
    type hint;
    file "root.hint";
};

# 正引きのループバックのゾーン設定
zone "localhost" in {
    type master;
    file "localhost.zone";
};

# 逆引きのループバックのゾーン設定
zone "0.0.127.in-addr.arpa" in {
    type master;
    file "127.0.0.zone";
};

# 正引きのおやじ宅内のゾーン設定
zone "example.zive.net" in {
    type master;
    file "master/example.zive.net.zone";
};

# acorn.examplex.comの正引きのゾーン設定
zone "acorn.examplex.com" in {
    type master;
    file "master/acorn.examplex.com.local";
};

# 逆引きのおやじ宅内ゾーンの設定
zone "1.168.192.in-addr.arpa" in {
    type master;
    file "master/192.168.1.zone";
};

# example.comの正引きのゾーン設定
zone "example.com" in {
    type master;
    file "master/example.com.local";
};

include "/etc/named.conf.include";            // デフォルトでrndc 関係をincludeしている

[namedo.conf]
options {
    listen-on { 192.168.1.101; };
    directory "/var/lib/namedo";
    dump-file "/var/log/named_dump.db";
    statistics-file "/var/log/named.stats";
    notify yes;            // zone設定に変化があったらnsで定義されたdnsにnotify通知。
    recursion no;          // 再帰的検索の禁止
};

logging {
    # Log queries to a file limited to a size of 100 MB.
    channel query_logging {
        file "/var/log/named_querylog" versions 3 size 100M;
        print-time yes;                 // timestamp log entries
        severity info;
        print-category yes;
    };
    category queries {
        query_logging;
    };
    # Don't log lame server messages.
    category lame-servers { null; };
};

key "examplex.com" {
    algorithm hmac-md5;
    secret "L7TFIweh/s/Dcf・・・(省略)・・・";
};

# example.comの正引きのゾーン設定
zone "example.com" in {
    type master;
    file "master/example.com.zone";
    allow-transfer { yyy.yyy.yyy.yyy; };  // セカンダリDNSのIPアドレスを記述(セカンダリDNSのみに転送)
    allow-query { any; };                 // 問合せは全て可
};
# examplex.comの正引きのゾーン設定 zone "examplex.com" in { type master; file "dyn/examplex.com.zone"; allow-transfer { zzz.zzz.zzz.zzz; }; // セカンダリDNSのIPアドレスを記述(セカンダリDNSのみに転送) allow-query { any; }; // 問合せは全て可 allow-update { key examplex.com; }; // Updateはkeyが一致したら可 }; controls { }; // rndcの二重起動防止対策 #include "/etc/namedo.conf.include"; // デフォルトでrndc 関係をincludeしている

  1. listen-on

    listen-onで、デーモンがlistenするアドレスを指定する。内向きのnamed.confでは127.0.0.1(localhost)と、内部のDNS用アドレスとしてWWWやFTPでDDNSのドメインを主に扱っている192.168.1.100を指定し、外向きのnamedo.confでは主に固定IP用ドメインを扱っている192.168.1.101を指定した。これにより、インターネット側からのDNSの問い合わせは192.168.1.101が受け持つので、ルータのポートフォワーディング等の設定もそれにあわせて変更した。(このアドレスについては、WWW/FTPのバーチャルホストを参照のこと。)

  2. directory

    directoryはchrootするディレクトリを指定するもので、内向きのnamed.confでの指定はデフォルトの/var/lib/namedとし、外向きのnamedo.confでは中身はほとんど不要なものばかりであるが、/etc/lib/named をコピーして作成した/var/lib/namedoとして新規に指定した。ここで指定したディレクトリに、内向き/外向きの各zoneファイルを置く。

  3. dump-file

    「rndc dumpdb」でキャッシュされているメモリ内のデータをダンプ出力させるファイル名を指定する。内向きも外向きもデフォルトのままでよいが、実際にはそれぞれchrootしているのでフォルダは異なる。

  4. statistics-file

    「rndc stats」でサーバーの統計情報をダンプ出力させる統計情報ファイル名を指定する。内向きも外向きもデフォルトのままでよいが、実際にはそれぞれchrootしているのでフォルダは異なる。

  5. notify

    内向き DNS では、notify通知は行わないので 「notify no;」とした。外向きはnotify通知を行うので、「notify yes;」とした。notify の設定は、zone 情報に変化があったことを ns で定義された dns にnotify 通知するか否かを指定するためのもので、yesとしておくことにより、セカンダリへの zone データの変更が速やかに行われる。デフォルトで yes なので記述しなくても、マスタで zone 設定を変更して再起動すれば、すぐにセカンダリに反映される。( serial 番号の変化で見ているので、内容を変更した場合は必ず serial 番号を上げることを忘れずに。)

  6. allow-query/allow-trasfer

    allow-queryとallow-trasferで、デフォルトでは設定情報を外部に出さないように localhost と家庭内のネットワークを設定する。外向きの情報は、外向きゾーン設定のところで開放する。(optionsでの設定より優先される)
    RedHat のときは acl を使用して Alias で設定したが、YaST では acl の設置ができず、直接 named.conf に記述しても YaST に消されてしまう。従って、allow-query/allow-trasfer の設定で、以下のようにアドレス/ネットワークを [ ; ] で区切って直接記述する。

    オプション

    概 要

    設定内容

    備 考

    allow-query 問合せ元制限 { 127.0.0.1; 192.168.1.0/24; } アドレス/ネットワークを [ ; ] で区切って直接記述し、全体を { } でくくる。最後のアドレスの後ろの[ ; ]も忘れずに。
    allow-trasfer 転送先制限 { 127.0.0.1; 192.168.1.0/24; }

  7.  forwarders/forward

    外部への問合せ先として forwarders で契約プロバイダの DNS を設定することにより、家庭内からの DNS 問合せを高速化できます。本設定がない場合、キャッシュされていないドメインに関しては、常に root に問合せに行くのでレスポンスが遅くなる。これを、契約プロバイダの DNS 経由にすれば非常に多くの方が使用しているので、キャッシュにヒットする確率が高くなり、レスポンスが改善する可能性がある。但し、おやじは元々契約プロバイダの DNS が重いので内向きDNS を建てた経緯もあり、設定はしていない。

    オプション

    概 要

    設定内容

    備 考

    forwarders 問合せ先指定 { 1.2.3.4; 5.6.7.8; } 契約プロバイダの DNS を [ ; ] で区切って直接記述し、全体を { } でくくる。最後のアドレスの後ろの[ ; ]も忘れずに。
    forward forward動作指定 first first 指定で、まずフォワーダーに問合せ、駄目なら rootから検索する。

  8. recursion

    外向きデータは、recursion noとして再帰的な検索を禁止する。yesとするとキャッシュデータ等も検索される。

  9. ログ関係

    /var/log 配下に named_querylog と言う名称で、クエリーのログを採ることにした。ファイル名の後ろの「versions 3 size 100M」は、100Mbyteのログファイルを 3世代保存するというデフォルト設定であるが、サイズが大きすぎて扱いにくいので、10Mぐらいにして世代を増やしたほうが実用的である。
    severity info は、最低限のレベルのログ内容を出力する設定。ある程度詳細に採取したければ infoをnoticeに、動作検証時などで非常に詳細なログ内容を出力したければ debugにすればよい。デバッグにすると膨大なログが出力されるので、注意が必要。通常はinfoで十分である。
    print-time yes; print-category yes; でログに時間とカテゴリを出力する。
    category lame-servers { null; } で逆引きのエラーログは捨てる。(apacheで逆引きしており、逆引きに失敗して非常に多くの「lame server ・・・・」ログが出るので設定した。)

  10. key

    DDNS用のexamplex.comのゾーンは、allow-update で書き換え可能な相手を指定することができる。今回はサーバ機自身のスクリプトで書き換えるので、{ localhost; }; で localhostからの変更のみ許可することもできるが、TSIG(共有鍵)でのガードができるのでこちらの方法とした。おやじは、アドレス詐称はルータでガードしているのでアドレス制限でもよいかと思ったが、アドレスガードだと起動時に警告が出るのと、万全を期すに越したことはないのでTSIGでのガードとした。共有鍵の作成方法等は以下のとおりである。

    1. 共有鍵は後でスクリプトから参照するので、スクリプトを置くディレクトリ作成しそこに作成する。

      # mkdir /usr/local/bin/ddns
      # cd /usr/local/bin/ddns

    2. dnssec-keygenコマンドで共有鍵を作成する。ドメイン名(examplex.com)のところは各自の環境に合わせる。

      # dnssec-keygen -a HMAC-MD5 -b 512 -n HOST examplex.com
      Kexamplex.com.+157+62830

    3. 作成すると***.keyと***.privateという2つのファイルができるので、***.keyファイルから共有鍵(下記の緑字部分)を抜き出し、key文のsecretのところに埋め込む。key名称(key文で指定した"examplex.com")は、examplex.comゾーンのallow-update で指定する。

      # ls
      .  ..  Kexamplex.com.+157+62830.key  Kexamplex.com.+157+62830.private
      # more Kexamplex.com.+157+62830.key
      examplex.com. IN KEY 512 3 157
      L7TFIweh/s/Dcf・・・(省略)・・・

  11. 外向きゾーンの、allow-transfer { yyy.yyy.yyy.yyy; };  では、セカンダリ DNS のみにゾーン転送するよう、セカンダリ DNS の IP アドレスを記述する。
    allow-query { any; }; で、 問合せは全てから許可する。なお、ループバック以外のmasterファイルはmasterディレクトリに置くようにした。但し、DDNS用はSuSEの場合、dynという専用ディレクトリがあるのでそちらに置くことにした。

  12. controls

    namedo.confのみ空のcontrols文( controls { }; )を置き、下記のincludeをコメントアウトしてある。これは、内向きデーモンが動作している状況で外向きデーモンを単純に起動時するとデフォルトでrndcが起動されるようになっているのでのrndcが二重起動されてしまうための対策である。実害はないがエラーがでるので、空のcontrols文で二重起動を防止している。

  13. include

    include の指定でデフォルトで localhost のみ rndc が使用できるようになっている。 rndc の使用範囲等、rndc関係の設定は include 先の /etc/named.d/rndc-access.conf を編集すれば良い。rndc 関係の設定について変更するなら、RedHat のコンテンツを参照のこと。

◆root.hint の設定(ルートゾーン)

このファイルはルートゾーンを定義しており、時々変更になるので、その場合はアップデートが必要になります。変更は数年に1回で、最近では2002年11月、2004年1月に変更になり、2007年11月に変更が予定されています。新しいルートヒントファイルは、以下のURLから入手できます。

変更は手動または自動でできますが、手動で変更する場合は以下のようにやればよいでしょう。

# cd /var/lib/named
# wget -O root.hint.new ftp://ftp.internic.net/domain/named.root
# mv root.hint.new root.hint

ルートヒントファイルの変更にあたっては一般的に猶予期間が半年ほどありますが、おやじは変更漏れがないように簡単なスクリプトを書いて対応することにしました。
適当なディレクトリ(おやじは、 /usr/local/bin 配下)に、こちらのスクリプトを適当な名前で設置し、設定を適宜行い実行権限を変更しておきます。

# cd /usr/local/bin
# wget http://www.aconus.com/~oyaji/dns/root.hint.check
# chmod 755 root.hint.check

後は、cronで適当なタイミングで実行すればよいだけです。/etc/crontab に下記を追記する。(下記は、毎週土曜日の1:23に実行する例である。)
# root.hintファイルの更新チェック
23 1 * * 5 root /usr/local/bin/root.hint.check

◆localhost.zoneの設定(正引きのループバックゾーン)

root.hint を含め このファイル(localhost.zone)と次のファイル(127.0.0.zone)のデフォルトの3つのファイルは一切変更は不要です。極端な話、ループバックの2つのファイルは hosts ファイルがある限り使われることはありませんし。

$TTL 1W
@      IN SOA  @   root (
               42      ; serial (d. adams)
               3H            ; refresh
               15M           ; retry
               1W            ; expiry
               1H )          ; minimum

       IN NS   @
       IN A    127.0.0.1

◆127.0.0.zoneの設定(逆引きのループバックゾーン)

$TTL 1W
@      IN SOA  localhost.   root.localhost. (
               42           ; serial (d. adams)
               3H            ; refresh
               15M           ; retry
               1W            ; expiry
               1H )          ; minimum

       IN NS   localhost.
1      IN PTR  localhost.

◆example.zive.net.zoneの設定(正引きの家庭内ゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   pdns.example.zive.net. root.example.zive.net. (
                   2005020501      ; serial    (3)
                   3H              ; refresh   (4)
                   15M             ; retry     (4)
                   1W              ; expiry    (4)
                   1H )            ; minimum   (4)

          IN NS    pdns.acorn.zive.net.        (5)
          IN MX    10 acorn.zive.net.          (6)

@         IN A     192.168.1.100               (7)
router    IN A     192.168.1.1                 (8)
oyaji     IN A     192.168.1.2                 (8)
rina      IN A     192.168.1.3                 (8)
akko      IN A     192.168.1.4                 (8)
printer   IN A     192.168.1.10                (8)
pdns      IN A     192.168.1.100               (8)
www       IN CNAME pdns                        (9)
mail      IN CNAME pdns                        (9)
ftp       IN CNAME pdns                        (9)

(1) 家庭内で使用するdnsのFQDNを指定。(最後に ' . '(ピリオド)を忘れずに) (5)とあわせること。
(2) サーバ管理者のメールアドレス(' @ 'を ' . 'に変えて指定。最後に ' . '(ピリオド)を忘れずに)ドメインは(6)とあわせること。
(3) データベースのシリアル番号。(変更するたびに必ず値を増やすこと。年月日+追番がよい)
(4) リフレッシュ・リトライ・有効・生存時間(デフォルトのまま)
(5) ネームサーバ名を指定(サーバ名の最後に ' . '(ピリオド)を忘れずに) (1)とあわせること。
(6) メールエクスチェンジャの指定。(CNAMEは使用しないこと)
(7) acorn.zive.netでサーバのローカルアドレスを返すための設定。
(8) 各ホストの正引きデータを指定。
(9)別名定義を指定。(おやじは、サーバだけ用途毎の別名を登録した。DNSは、別名定義しないこと。)素直に、(8)項と同様にAレコードで定義しても良い。

◆acorn.examplex.com.localの設定(正引きの家庭内ゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   pdns.acorn.examplex.com. root.acorn.examplex.com. (
                   2005020501      ; serial    (3)
                   3H              ; refresh   (4)
                   15M             ; retry     (4)
                   1W              ; expiry    (4)
                   1H )            ; minimum   (4)

          IN NS    pdns.acorn.examplex.com.    (5)
          IN MX    10 acorn.examplex.com.      (6)

@         IN A     192.168.1.100               (7)
router    IN A     192.168.1.1                 (8)
oyaji     IN A     192.168.1.2                 (8)
rina      IN A     192.168.1.3                 (8)
akko      IN A     192.168.1.4                 (8)
printer   IN A     192.168.1.10                (8)
pdns      IN A     192.168.1.100               (8)
www       IN CNAME pdns                        (9)
mail      IN CNAME pdns                        (9)
ftp       IN CNAME pdns                        (9)

(1) 家庭内で使用するdnsのFQDNを指定。(最後に ' . '(ピリオド)を忘れずに) (5)とあわせること。
(2) サーバ管理者のメールアドレス(' @ 'を ' . 'に変えて指定。最後に ' . '(ピリオド)を忘れずに)ドメインは(6)とあわせること。
(3) データベースのシリアル番号。(変更するたびに必ず値を増やすこと。年月日+追番がよい)
(4) リフレッシュ・リトライ・有効・生存時間(デフォルトのまま)
(5) ネームサーバ名を指定(サーバ名の最後に ' . '(ピリオド)を忘れずに) (1)とあわせること。
(6) メールエクスチェンジャの指定。(CNAMEは使用しないこと)
(7) acorn.examplex.comでサーバのローカルアドレスを返すための設定。
(8) 各ホストの正引きデータを指定。
(9)別名定義を指定。(おやじは、サーバだけ用途毎の別名を登録した。DNSは、別名定義しないこと。)素直に、(8)項と同様にAレコードで定義しても良い。

◆example.com.localの設定(内向きのexample.comの正引きのゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   pdns.example.com. root.example.com. (
                   2005020501       ; serial    (3)
                   3H               ; refresh   (4)
                   15M              ; retry     (4)
                   1W               ; expiry    (4)
                   1H )             ; minimum   (4)

          IN NS    pdns.example.com.            (5)
          IN MX    10 example.com.              (6)
@         IN A     192.168.1.101                (7)
pdns      IN A     192.168.1.101                (8)
www       IN A     192.168.1.101                (8)
mail      IN A     192.168.1.101                (8)
ftp       IN A     192.168.1.101                (8)

(1) 家庭内で使用するdnsのFQDNを指定。(最後に ' . '(ピリオド)を忘れずに) (5)とあわせること。
(2) サーバ管理者のメールアドレス(' @ 'を ' . 'に変えて指定。最後に ' . '(ピリオド)を忘れずに) ドメインは(6)とあわせること。
(3)〜(4) 前述と同一
(5) ネームサーバ名を指定。 (1)とあわせること。
(6) メールエクスチェンジャの指定。(外向きと合わせた)
(7) example.comでサーバのローカルアドレスを返すための設定。
(8) 各ホスト名をAレコードで定義(CNAMEのほうが簡単であるが)

◆192.168.1.zone の設定(逆引きの家庭内ゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   pdns.acorn.examplex.com. root.acorn.examplex.com. (
                   2005020501      ; serial    (3)
                   3H              ; refresh   (4)
                   15M             ; retry     (4)
                   1W              ; expiry    (4)
                   1H )            ; minimum   (4)

          IN NS    pdns.acorn.examplex.com.    (5)
1         IN PTR   router.acorn.examplex.com.  (8)
2         IN PTR   oyaji.acorn.examplex.com.   (8)
3         IN PTR   rina.acorn.examplex.com.    (8)
4         IN PTR   akko.acorn.examplex.com.    (8)
10        IN PTR   printer.acorn.examplex.com. (8)
100       IN PTR   pdns.acorn.examplex.com.    (8)
101       IN PTR   ns1.example.com.            (8)

(1)〜(5)は、前述と同一.
(8)は、正引きの(8)で指定したホストの逆引きデータを指定。(別名定義したものではない)

◆example.com.zoneの設定(外向きのexample.comの正引きのゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   ns1.example.com. root.example.com. (
                   2004060600       ; serial    (3)
                   3H               ; refresh   (4)
                   15M              ; retry     (4)
                   1W               ; expiry    (4)
                   1H )             ; minimum   (4)

          IN NS    ns1.example.com.             (10)
          IN NS    nsx.zoneedit.com.            (11)
          IN MX    10 example.com.              (12)
@         IN A     xxx.xxx.xxx.xxx              (13)
ns1       IN A     xxx.xxx.xxx.xxx              (14)
www       IN A     xxx.xxx.xxx.xxx              (14)
mail      IN A     xxx.xxx.xxx.xxx              (14)
ftp       IN A     xxx.xxx.xxx.xxx              (14)

(1)〜(5)は、前述と同一.
(10) プライマリネームサーバ名を指定(レジストラに登録した自分のDNS)
(11) セカンダリネームサーバ名を指定(レジストラに登録したセカンダリDNS。とりあえずはなくても可。)
(12) メールエクスチェンジャの指定。(1)とあわせること。
(13) example.comでサーバのローカルアドレスを返すための設定。
(14) 各ホスト名をAレコードで定義

◆examplex.com.zoneの設定(外向きのexamplex.comの正引きのゾーン)

$TTL 86400               (1)                 (2)
@         IN SOA   ns1.examplex.com. root.acorn.examplex.com. (
                   2005020501       ; serial    (3)
                   3H               ; refresh   (4)
                   15M              ; retry     (4)
                   1W               ; expiry    (4)
                   1H )             ; minimum   (4)

          IN NS    ns1.examplex.com.            (10)
          IN NS    nsx.zoneedit.com.            (11)
          IN MX    10 examplex.com.             (12)
@         IN A     xxx.xxx.xxx.xxx              (13)
ns1       IN A     xxx.xxx.xxx.xxx              (14)

(1)〜(5)は、前述と同一.
(10) プライマリネームサーバ名を指定(レジストラに登録した自分のDNS)
(11) セカンダリネームサーバ名を指定(レジストラに登録したセカンダリDNS。とりあえずはなくても可。)
(12) メールエクスチェンジャの指定。(1)とあわせること。
(13) example.comでサーバのローカルアドレスを返すための設定。
(14) 各ホスト名をAレコードで定義

■ルータ/iptablesの設定

外向きでDNSを建てた場合、ルータやiptablesの設定変更が必要になります。ゾーン転送にはUDPの53番ではなく、TCPの53番を使用してセカンダリDNSからアクセスがあります。従って、WWWサーバ等と同様に、TCPの53番をサーバにポートマッピングしてフィルタを開けてあげる必要があります。このとき、セカンダリDNSのアドレスはわかっているので、アドレス指定を併用し不必要なアクセスは遮断すべきです。なお、セカンダリDNSがゾーンデータの変更チェックを行う時はUDPの53番を使用します。
ゾーンの転送は、以下のような時に発生します。

■DNSの動作確認

DDNSの動作以前に普通のDNSとして動作していないことには話にならないので、まずはDNSの動作確認を行います。DNS動作確認は、BINDを起動してdigで行いますが、起動に先立ち各設定ファイルに誤りがないか確認しておきます。但し、内容そのものの正常性は確認できず、文法的な問題がないかをテストしてくれるだけなので、後で、内容についてはそれぞれ試験する必要があります。

  1. まず、named.confファイルが正常か確認する。確認には、named-checkconfコマンドを使用するが、普通はnamed-checkconfとするだけでいいが、今回は外向けデーモン用にもconfファイルがあるのでファイル指定でチェックする。named-checkconfでは文法的に問題がないかチェックしてくれ、下記は外向きデーモン用のnamedo.confの8行目で認識できないオプションがあり、それはoptionである(正解は、options)と指摘している例である。問題がなければプロンプトに戻るだけである。

    # named-checkconf /etc/namedo.conf
    # /etc/namedo.conf:8: unknown option 'option'

  2. 続いて、named-checkzoneコマンドで各ゾーンファイルが正常か確認します。zone名とファイル名を入力してチェックします。問題がなければ、下記のようにserial番号が表示され、「OK」と表示される。全てのファイルをチェックしておく。下記は、外向きのexamplex.comゾーンのファイルをチェックしている例である。

    # cd /var/lib/namedo
    # named-checkzone examplex.com ./dyn/examplex.com.zone
    zone example.com/IN: Loaded serial 2005020501
    OK

  3. 設定ファイルでエラーがでなくなったら、下記で一応、chkconfig でチェックして各ランレベルでの起動確認をし、BINDを起動する。

    # chkconfig --list named
    named           0:off    1:off    2:off    3:off    4:off    5:off    6:off
    # chkconfig named on
    # chkconfig --list named
    named           0:off    1:off    2:off    3:on    4:off    5:on     6:off
    # /etc/init.d/named start
    Starting name server BIND 9 done

    事前に設定ファイルをテストしているので、正常に起動するはずであり、ログファイル(/var/log/messages)に下記のようなメッセージが出力されているはずである。ログの内容は多少違うかもしれないが、最低限各インタフェースで「listening」が53番ででるはず。

    Feb 6 01:26:23 server named[7588]: starting BIND 9.2.2 -c /etc/named.conf -t /var/lib/named -u named
    Feb 6 01:26:23 server named[7588]: using 1 CPU
    Feb 6 01:26:23 server named[7590]: loading configuration from '/etc/named.conf'
    Feb 6 01:26:23 server named[7590]: listening on IPv4 interface lo, 127.0.0.1#53
    Feb 6 01:26:23 server named[7590]: listening on IPv4 interface eth0:1, 192.168.1.100#53
    Feb 6 01:26:23 server named[7590]: command channel listening on 127.0.0.1#953
    Feb 6 01:26:23 server named[7601]: starting BIND 9.2.2 -c /etc/namedo.conf -t /var/lib/namedo -u named
    Feb 6 01:26:23 server named[7601]: using 1 CPU
    Feb 6 01:26:23 server named[7603]: loading configuration from '/etc/namedo.conf'
    Feb 6 01:26:23 server named[7603]: listening on IPv4 interface eth0, 192.168.1.101#53

    一応、netstatでnamed、rndcが起動しているか確認しておく。TCPでの53番および953番、UDPの53番があれば大丈夫である。

    # netstat -ln
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State
           :
         (snip)
           :
    tcp        0      0 192.168.1.100:53        0.0.0.0:*               LISTEN
    tcp        0      0 192.168.1.101:53        0.0.0.0:*               LISTEN
    tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
           :
         (snip)
           :
    tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN
           :
         (snip)
           :
    udp        0      0 192.168.1.100:53        0.0.0.0:*
    udp        0      0 192.168.1.101:53        0.0.0.0:*
    udp        0      0 127.0.0.1:53            0.0.0.0:*

  4. 続いて、digで外部のドメイン、アドレスに対する正引き・逆引き、家庭内の各パソコン等の正引き・逆引きをしてチェックしてみる。digの使い方については、manや他サイトを参照してください。
    今回は、アクセスするサーバのアドレスが内向き(127.0.0.1/192.168.1.100)と外向き(192.168.1.101)で異なるので、@***.***は意識して指定しないとチェックにならないので注意が必要である。また、既存環境から移行する場合は、割り付けたアドレスにもよるが、クライントのDNSの設定やサーバ機自身のDNSの設定の見直しが必要になるので注意が必要である。おやじは、テスト中にサーバ機のDNS設定変更を忘れ、AntiVirのアップデートエラーのメールで気づいたが、数時間サーバ発のDNS検索がうまく動作していなかった。(WWW/FTPサーバテストも迷惑をかけたはず・・。)
    なお、example.zive.netやexample.comで牽くとサーバのプライベートアドレスが返り(example.zive.net.zoneの(7)の設定)、WAN側のグローバルアドレスを牽くことができません。といっても、家庭内からこのドメインを牽いたときにADSLルータのWAN側アドレスが牽けても、一般的なルータではローカル側からWAN側アドレスを指定しても、ping以外は無視されるか、WWWの場合は、ルータの設定画面が表示されてしまうのでほとんど役に経ちません。(自分のグローバルアドレスをCGI等でほしいときなど、不便です。)

■DynamicDNS(BIND)関係

DNSとしての基本的な動作確認が終了したら、DDNSとして動作させるための設定とテストを以下で行っていきます。

◆DynamicDNS(BIND)用スクリプトのインストールと設定

DDNSへの登録は、ZiveへのIPアドレス登録用に作成したスクリプトを流用して動的IPアドレスの変化を検出し、BINDのnsupdateコマンドでサブドメインのA/MXレコードを登録・変更するようにしました。なお、汎用化は簡単と思いますが、今回は特殊な事例なのでスクリプト(ddns.cgi)は狙い撃ちで作成しており、ルータはMN8300専用として、指定したホスト名でA/MXレコードを登録・変更するだけのものです。作成したスクリプト類(ddns.cgi)は、先に解凍した二重起動用パッチのddnsディレクトリ配下に同梱してあります。このスクリプトはEUCで書かれているので、Windows環境で編集したりする場合は必ずエディタを使用してください。Shift-JISでは、動作しません。
  1. このスクリプトではlibwww-perl(LWP) を使用するので、インストールされていなければYaSTでインストールする。

    1. YaST コントロールセンタを起動し、「ソフトウェア」の「ソフトウェアのインストール/削除」を起動する。

    2. 「フィルタ」 を 「検索」 とし検索欄に 「libwww-perl」 と入力し 「検索」 ボタンを押す。

    3. 右側に該当するパッケージが出てくるが、その中の「perl-libwww-perl」にチェックマークを入れて 「了解」 を押しておしまい。

  2. アーカイブを解凍した中にあるddnsディレクトリを適当なディレクトリ(おやじは、/usr/local/bin)にコピーする。単純コピーすると上書きしてしまうので、バージョンアップ時は他で解凍後、必要なもののみコピーすること。
    Windowsの場合は適当なソフトで解凍すること。
     
    • ddns.cgi      : スクリプト本体
    • old_ip.dat     : 前回検出したグローバルアドレスの格納ファイル
    • ip_check.dat :外部スクリプトのURIを格納したファイル
    • log             : 各種ログファイルを格納するフォルダ

  3. まずは、スクリプト本体(ddns.cgi)に動作に必要な条件を以下により設定します。

    No.

    パラメータ

    設 定 内 容

    1

    $router_url  ルータのLAN側アドレスを指定 ( 192.168.1.1 ) 

    2

    $isp ・MN8300/W
     Zive.orgに登録したいルータの接続先No.を指定 (1〜8)
     外部スクリプトで検出する場合は、0を指定。ルータでの検出とは背反

    3

    $router_user ルータのログインユーザ名を指定

    4

    $router_pass ルータのログインパスワードを指定

    5

    $dir このスクリプトを設置したディレクトリを指定 ( /usr/local/bin/ddns )

    6

    $domain DDNSのドメイン名 ( examplex.com )
    7 $host 登録ホスト名 ( example )
    8 $ttl DDNSのTTL ( 600: 秒で指定 )

    9

    $dns 外向けDNSのアドレス ( 192.168.1.101 )
    10 $key update用共有鍵ファイル ( ./Kexamplex.com.+157+62830.key )

    11

    $debug デバッグ用でルータから受信したメッセージを記録するか否か指定 ( 0:off 1:on )

◆動作確認と起動設定

設定が終わったら、

# perl /usr/local/bin/ddns/ddns.cgi


 と入力してスクリプトを起動し、イベントが正常に実行されるか確認します。初回起動時は、必ず更新動作をします。正常に実行されたかどうかは、ログ(./log/event.log)及びdigで確認します。ANSWER SECTION の アドレスが現在のルータのWAN側に割り当てられたグローバルアドレスになっているか確認してください。今回のスクリプトでは、MXも同時に登録しているのでそれも確認します。

# dig @192.168.1.101 acorn.examplex.com A

; <<>> DiG 9.2.2 <<>> @192.168.1.101 acorn.examplex.com A
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6614
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 3

;; QUESTION SECTION:
;acorn.examplex.com. IN A

;; ANSWER SECTION:
acorn.examplex.com. 600 IN A yy.yy.yy.yy

;; AUTHORITY SECTION:
examplex.com. 86400 IN NS ns1.examplex.com.
examplex.com. 86400 IN NS nsx.zoneedit.com.

;; ADDITIONAL SECTION:
ns1.examplex.com. 86400 IN A xx.xx.xx.xx
nsx.zoneedit.com. 97598 IN A zzz.zzz.zzz.zzz

;; Query time: 2 msec
;; SERVER: 192.168.1.101#53(192.168.1.101)
;; WHEN: Tue Feb 8 20:58:06 2005
;; MSG SIZE rcvd: 160

なお、DDNSで登録を行うといきなりexamplex.comのゾーンファイルが更新されるわけではなく、examplex.comのゾーンファイルと同じディレクトリにexamplex.com.jnlという一時ファイルが作成され、その後、ゾーンファイルを書き換えます。このファイルは元のゾーンファイルの差分データになっているので、ゾーンファイルへの反映前にゾーンファイルを変更するとエラーになり正常にDDNSのアドレスが牽けなくなってしまいます。こうなってしまったら、examplex.com.jnlを削除してnamedを再起動してください。
こういう事態を想定して、スクリプトではアドレスが変化したら更新するのではなく、登録したいホストのアドレスが既にあるか否かをチェックしてなければ無条件に登録し、存在すればアドレスが異なる場合のみ登録するようにしてますので、未登録状態でexamplx.comゾーンのファイルを編集してしまってもexamplex.com.jnlを削除して再起動すれば次周期で登録されるので大丈夫です。

 正常に動作していることが確認できたら、cronで周期的(5分毎)に起動するようにします。/etc/crontabに以下のように追加すれば、5分毎に登録状況とアドレス変化を監視し、変化すれば更新されます。
0-59/5 * * * * root perl /usr/local/bin/ddns/ddns.cgi


Top Pageへ