text

DNSサーバーの構築

DNSサーバーの構築と活用


1.DNSサーバーとは

DNSとは「Domain Name System」の略で、IPアドレスとホスト名を相互変換してくれるサービス。1983年に情報科学研究所 (ISI) のポール・モカペトリスとジョン・ポステルにより開発された。

インターネット、イントラネットに関わらずTCP/IPベースのネットワークでは、パソコンやサーバーからスイッチ、ルーター、プリンタといったネットワーク機器まで、ネットワークに接続して稼動させる機器にはそれぞれネットワーク上での個体識別のためにIPアドレス(例:203.141.134.6)が割り振られることになっている。ネットワークに接続されたコンピュータはお互いのIPアドレスを送信先に指定して通信を行っている。

IPアドレス( 203.141.134.6 )は0〜255の数値を4つ、ピリオドで区切って並べて表記するが、コレは人間にとっては覚えやすいものではない。また、なんらかの理由により相手先ネットワークの構成が変更された場合、IPアドレスは別のものに振り直されたりして変更される事がある。そのような場合には記憶していたIPアドレスでは相手先と接続できなくなってしまう。そのため、より人間が覚えやすく使いやすい”名前”で通信先を指定できるしくみが必要となった。

コンピュータの役割に応じた名前(=ホスト名)ならば、人間は非常に覚えやすくなる。そこで、ホスト名でアクセスできるようにホスト名とIPアドレスとの対応表が作られるようになった。コンピュータネットワークの黎明期ならば数が非常に少数なため、手作業による作業で十分可能だが、現代のようにコンピュータネットワーク全盛の時代では手作業による対応表のメンテナンスは到底不可能になる。そこで、IPアドレスとホスト名とを自動変換する仕組みが考案され、処理を階層化するとともに分散型データベースとしてDNSという仕組みが実装され現在に至る。

2.DNSの歴史

DNSは開発されてから現在までのほぼ20年間、基本設計を変えることなくインターネット上の重要なプロトコルとして利用されてきている。この間にインターネットはめざましい成長をとげ、現在では社会的インフラの1つとして、必要不可欠な存在となった。インターネットの成長を見えない部分から支えてきた技術の1つにDNSがあるとも言及できる。

本章では、インターネットの発展を支えてきたDNSの歴史を学んでいくものとする。

■黎明期の名前解決

インターネットの前身がARPAnetであるという話は、Webサーバーの構築で既に述べたが、コンピュータネットワークが稼働し始めた1970年頃にはまだ、DNSのシステムはなかった。

当時のARPAnetでは、名前解決にHOSTS.TXT というホスト名とIPアドレスの対応表が記述されているテキストファイルを使用していた。現在のUNIX及びそのクローンOSには /etc/hosts というファイルが存在するのはその当時の名残だ。UNIX系OSでなくとも、Windowsにもこの名残がうかがえる。例えば、Windows2000ならば、 %Systemroot%\System32\drivers\etc\hosts のパスを見ることでhostsファイルの存在を確認することができる。

Hostsファイルの記述例

127.0.0.1 localhost
203.141.134.6 criterion.sc

HOSTS.TXTには、1行に『ホスト名』と『IPアドレス』の対が記載されている。現在のUNIX系OSで使用しているhostsファイルとフォーマットは基本的に同じだ。このファイルを自分のPCに設置しておけば、使用するアプリケーションがHOSTS.TXTに全文検索をかけて指定したホスト名に対応するIPアドレスを読み込む。そして、そのIPアドレスを持つホストコンピュータへ接続する。

現代のインターネットで標準となっているTCP/IPという通信プロトコルだが、ARPAnet稼働当初から使用されていたわけではなかった。ARPAnetの進化の過程で開発されたもので、TCP/IP自体は1978年に標準化された。その後、様々なテストを経て1983年の1月1日に正式に実装され、ARPAnetの正式なプロトコルとなった。

ARPAnet上のすべてのホスト情報を収めたHOSTS.TXTは,Stanford Research Institute(SRI)という組織のNIC(= Network Information Center)にて保守・管理され、Anonymous FTPで公開されていた。ARPAnetに新しいホストが加わると、その情報をNICがHOSTS.TXTに反映する。最新のHOSTS.TXTはSRI-NICというホストに置かれ、名前解決をしたいユーザー(=ARPAnetに接続している組織)は、SRI-NICから最新のHOSTS.TXTをFTPで取得して自分のホストに置いてホスト名の名前解決をしていた。

自分のホストの名前とIPアドレスの対応させる情報は各ホストマシンの管理者がSRI-NICにメールで通知していた。SRI-NICではこのメールを受けてHOSTS.TXTの更新作業を行い、公開した。各ホストコンピュータでは定期的にSRI-NICからHOSTS.TXTを入手し、ファイルを更新することになる。

■HOSTS.TXTの破綻

当初、ARPAnetには,わずか数百台のホストしかなかった。そのためARPAnet上のホスト情報すべてをたった1つのHOST.TXTファイルに記載しておくことが可能だった。しかし、ARPAnetが成長していくに従ってこの方法には破綻が生じてきた。
ARPAnetが,現在のインターネットに近い形になった1983年には、接続しているホスト数はおよそ数万台。SRI-NICのFTPサービスは完全に過負荷状態になっていた。既にそのときにはARPAnetは正常にネットワークが機能しなくなりつつあり、HOSTS.TXTファイルによる名前解決は不可能になっていった。
当時のARPAnetには具体的に以下のような問題が発生していた。

(1)SRI-NICの負担増大

ARPAnet上に存在する、すべてのホスト情報を記載したHOSTS.TXTファイルの容量は、大変大きくなっていた。1ホストにつき1行増えるためファイルは何万行にも及んだ。また、当時は現在とは比較にならないほど、接続回線は細いものだった。複数のユーザーが大容量のファイルを転送しようとすれば、当然、回線の帯域は飽和状態なってしまった。
管理の手間もさることながら、そのファイルを保存しておくためのサーバー・リソースや、ファイルを取得しようとアクセスするトラフィックに耐えうるネットワーク・リソースを確保することが難しくなっていった。
もはや、SRI-NICは、ホスト的にも、ネットワーク的にも、その異常ともいえる負荷に耐えられなくなっていたのです。

(2)ホスト名の重複

HOSTS.TXTでは同じホスト名を使用してはならない運用ルールになっており、SRIでもホスト名の重複が起こらないことを保証していた。ところが、保証していたにもかかわらず、SRIにはホスト名の割り当てに関しては、何の権限もなかった。

これは、非常にオカシイはなしで接続するホストに対して運用ルールを適用させる権限を何も持たずにサービスの保証はできないではないか!

当然、新規接続ホストは既存のホスト名を何の問題もなく取得できてしまった。結果、それに連動するようにメールシステム(=当時、FTP転送からSMTPへの移行時期だった)なども、破綻する恐れがあった。意図しないホストへのメールが送られてしまう危険性があったのだ。

(3)古いHOSTS.TXTの使用

HOSTS.TXTは、すべてのホストが最新のファイルを持っていてこそ意味がある。しかし、全ホストが最新のHOSTS.TXTを持っているとは限らない。各ホストコンピュータの管理者がHOSTS.TXTを更新しなければならなかったからだ。
当然、末端のホストのHOSTS.TXTが更新されたときには、SRI-NICに置かれている最新のHOSTS.TXTが、まったく別物になっていることが頻繁にあった( <- 歴史が長いことだけが取り柄の某国の政治体制によく似ている)。こうなると、適切に名前解決できず、接続したいホストに接続できない。

もともと、HOSTS.TXTをSRI-NICから配布する方法は、ネットワークに接続するホストコンピュータが少ない場合に限り可能な方法であることは自明のことだった。だが、当時のコンピュータの性能や導入や運用コスト面などの要因ですぐに有効な対応がうてず、またその必要もなかった。徐々に対策を打っていけばよい、というスタンスだった。ただ、予想を遙かに上回る速度でコンピュータネットワークが発展していったことがこのシステムの破綻を早めたのが誤算だった。

予想よりもコンピュータの導入に対して世間は意欲的であり、まさしく、コンピュータネットワークは時代に選ばれた技術だったといえる。予想外のARPAnetの大成功が「HOSTS.TXTの破綻」につながる、という皮肉な結果につながったと言える。

当然、ARPAnetはそれだけでは終わらず、新たな名前解決の方法を重要課題として検討し始めた。結果、考案された名前解決のシステムが「Domain Name System (DNS) 」なのだ。

■DNSの提唱

『HOSTS.TXTの破綻』を教訓にARPAnetは『新たな名前解決の方法』として以下の条件を満たすシステムを開発しようとした。それが現在のDomain Name System (DNS) だ。

(1)分散管理できること

これは、HOSTS.TXTの二の舞を演じないために不可欠の条件だった。HOSTS.TXTのように1カ所に管理を集中すれば、そのホストは過負荷状態になりシステムダウンしてしまうことは実証済みだった。

(2)階層的にホスト名(名前空間)を管理できること

現在のドメイン名などを見ると「.」で区切られて、階層化されていることが伺える。これもHOSTS.TXTの失敗に学んだ条件で、階層的な名前空間を使用することによってホスト名が重複するのを避けるようにした。階層化という発想自体は、UNIXのファイル・システムから生み出されたものだと思われる。

(3)更新した情報が瞬時に反映されること

新たなホストが接続された場合や接続ホストに変更があった場合には、更新情報がすぐに反映されなければならない。HOSTS.TXTに起こった『タイム・ラグ』が発生してはならないのだ。

(4)ネットワークのすべてのホストが参照できること

『名前解決をできるホスト』と『名前を解決できないホスト』があっては困る。ネットワークに接続しているすべてのホストから、参照できる必要がある。

今でこそ当たり前のシステムなのだが、このような条件を満たすシステムは当時はなかった。そのため、既存のシステムを流用することはできず、システムの設計から始める必要があった。
1983年11月、条件を満たすシステムをJon Postel氏、南カリフォルニア大学情報科学研究所(SIS)に所属していたPaul Mockapetris氏、そして、Craig Partridge氏を開発の中心人物としたInformation Sciences Institute(ISI)が3つのRFC(Request For Comments)としてまとめ、発表した。これが「Domain Name System (DNS) 」の誕生だ。しかし、これらのRFCは“たたき台”に過ぎず、DNSの“完成形”までには研究者たちの長い議論を必要とした。

■DNSの実装

まず議論の対象となったのは、『ドメイン名の表記方法』についてだった。ドメイン名は www.criterion.sc と記述されるように『.』で区切られた階層構造をしている。ドメイン名が重複しないように階層構造にすることは既に決まっていたが、どのような順番で表記するのかについては決まっていなかった。これは、単純に取り決めの問題なので”sc.criterion.www”でも、構わなかったのだ。

最終的に、Jon Postel氏らは『固有の名前から一般的な名前』で記述する、欧米でのアドレス(住所)表記と同様の表記方式を採用することに決めた。まず番地を書いて、最後に国名を書くアドレス表記と同様で最初にマシン(ホスコンピュータ)名を書き、最後にもっとも範囲が広い『トップレベルドメイン(TLD)』を書くことに決めた。

議論はこれだけでは終わらなかった。次に問題になったのは、『ドメイン名をどのように命名するか?』についてだった。すなわち、『.』と『.』の間に、どのような文字列を使用するのかが、議論の対象となった。

とくに問題になったのは、現在は『com』などで構成されている、トップレベルドメインだ。例えば、出資者であるDARPAやMITなどを、トップレベルドメインとして使うべきだ、という意見があった。議論の末、『com』、『net』、『org』、『edu』、『mil』、『int』、『gov』の7つ、そして、移行用として『arpa』を採用することで合意された。

単にドメイン名の表記方法を決めるだけの議論に、結局、1年以上も費やしてしまった。そのためARPAnetがユーザーに対して、DNSを考慮したドメイン名の利用を働きかけ始めたのは、1985年からだった。1986年1月に西海岸で開かれた、第1回目のInternet Engineering Task Force(IETF)ミーティングで、『DNSは本当に信頼できる』という統一見解が出され、徐々に普及していくことになった。

長期にわたる議論の結果は、RFCに反映された。仕様が変更された部分は、第1回IETFミーティングと同じ1986年の1月に再びMockapetirs氏により、RFC973 *5 で文書化された。そして、1987年11月に変更部分も含めて、RFC882と883は、それぞれRFC1034と1035 に書き直された。

現在も、RFC1034と1035を補足する新しいRFCは、発表され続けている。例えば、RFC2136やRFC2874などが挙げられます。
これらは、後から追加された機能の説明であり、RFC2136は、DNSの動的更新などにあたる。RFC2874で提案されたのは、DNSのIPv6対応の部分だ。今後、IPv6が普及していくことを考えると、必須の追加機能といえる。

ここまでで述べてきたように、DNSは様々な紆余曲折があり現在の形式へと発展してきた。今後も、DNSにはさらに機能が追加され、より多機能になっていくと考えられる。それに伴い、RFCも改訂され続けることが予想される。長い議論の末、ようやく認められたDNSだが、これからも成長し続けることだろう。

2.本実習の目的

インターネット上では、FQDN(Fully Qualified Domain Name)からIPアドレスを取得するDNSが広く利用されている。
DNSはホスト名とIPアドレスとの対応を提供するDBだが、他のサーバーと連携して規模が大きい点やデータベースを提供する範囲をネットワークごとに指定できるなどの特徴がある。この実習ではDNSソフトウェアの代表であるBINDの設定を利用方法に応じて学習する。

3.DNSの仕組み

かつて、『ドメイン』は企業や大学、研究機関、各省庁等の組織がインターネットにつながったネットワークを構築する際にのみ必要とされるものだった。あくまで『法人』のネットワークに付与するべくもので、基本的に個人には必要がなかった。

2001年の日本語ドメインや多言語ドメインの実装が話題を集め、低価格高速インターネットの爆発的普及でインターネットが特別なものではなくなった。さらに、当時『オンリーワン』というキーワードが流行した背景もあり、”自分ブランド”の嗜好の波及効果なのか個人でドメインを取得して運用する傾向が出てきた。

本章ではドメインの運用など、これからDNSと付き合おうとしている方々を対象に「DNSの概念や運用の考え方」の基本を解説していくものとする。BINDなど、DNSに関する具体的な設定方法については『5.BINDの基本設定』以降を参考にしてほしい。

3ー1.DNSの役割 − ドメイン・ツリーと分散環境

DNSについては既に『2.DNSの歴史』である程度述べた。そこで、本章ではDNSの必要性について歴史的な背景を踏まえて述べていくものとする。
かつて、ARPAnetではDNSの前身としてHOSTSファイルで名前解決を行っていた。接続ホスト数が少ない時期は非常に単純な対照表で運用も設定も楽だったのだが、登録されるホスト名が増えれば逆に非効率的な仕組みであることもあり、結局はDNSに取って代わられた。

1984年から運用の始まったDNSだが、HOSTSファイルの対照表の機能を専用サーバー(=DNSサーバー)に集約させ代替させただけではない。
単にHOSTSファイルの機能をサーバーに代替させただけでは、問題が残るからだ。

仮に世界中にネットワークに接続したホストが1億台あったとすると、DNSは1億台分のIPアドレスとホスト名の対応情報が登録されていればよい。しかし、たった1つのDNSサーバだけで全世界に存在するホスト情報を処理するのでは負荷に耐えられないだろう。当然の帰結として、複数サーバによる運用が必要となる。だが、それらで完全に同じデータを持ち合うのでは、非常に非効率だ。インターネットに接続する組織で全世界に存在するホスト情報を保持しなければならないのならば、サーバーへの負荷が高すぎる。

では、1億台分のリストはどのように得られるのだろうか?
そう、ここで「ホスト名のユニーク性」の確保の問題が浮かび上がる。インターネット上のホスト名は同じものが2つとしてあってはならないのだ。ホスト名の命名の際に、世界中のホストが登録されたデータに対して、手作業で重複の有無を確認しなければならない、というのは現実的に不可能だ。
この問題に対する実現可能なアプローチとしては、ホスト命名に関してある種の規則を用いて運用することだ。これを可能とする技術に『ドメインツリー』というものがある。

普段使用されるドメイン名などと呼ばれるホスト名は、『.』でいくつかの階層に区切られる。それぞれの階層ごとに、それ以下に含まれる下位ドメイン名やホスト名を管理するという『分散型』サービスとなっている。


 ドメインツリーの概念

このツリーの『枝分かれ』部分に該当するのが『ドメイン』である。『criterion.sc』など、上位ドメイン名を付けたものと区別するために『ノード』とも呼ばれこともある。また、このようなデータ構造を含む名前を『名前空間(ネーム・スペース:Name Space)』などとも呼ぶ。

各ノードでは、自身の下位ドメイン(サブドメイン)として何があるのか。そのサブドメインの情報を持っているDNSサーバは何か、自身に所属するホストの情報(IPアドレスなど)などの情報が管理される。これらを管理しているのが、それぞれのノードに位置して、そのドメインを管理するDNSサーバである。
ドメインのレベルによっては主にサブドメイン情報のみを管理するサーバもあれば、自ホストしか管理していないサーバもある。だが、それぞれのDNSサーバの挙動や役割に大差はない。

基本的に各ノードに位置するDNSサーバ自身は、自身の管理するドメイン内情報とサブドメインのDNSサーバ名しか知らない。そこで、外部のDNSへの問い合わせを行うDNSクライアント(=スタブリゾルバ)は、この階層を上位から順にたどって検索を行っていく。ルートからscドメインのDNSサーバへ、scドメインのDNSサーバはcriterion.scドメインのDNSサーバを知っているので、criterion.scドメインのDNSサーバへ尋ねる。最終的には、 www.myportal.criterion.sc のIPアドレスを知るDNSサーバ(=myportal.criterion.scドメインのDNSサーバ)までたどり着ける。

非常に煩雑に見えるかもしれないが、このようなデータが配置できれば各ノードで分散して情報を保持できるし、あるノードにおいて『example』というホストを登録しても、ノード内のユニーク性さえ保証すれば、ドメイン名をホスト名に付加することで、自動的にユニーク性が保証される。実は、非常に効率的かつ柔軟なシステムなのでだ。

DNSとは、全世界に張り巡らされた『分散協調型データベース・システム』とも考えることができる。

運用を行う上で上位ドメイン(=上位ノード)はサブドメインのDNSサーバ情報のみを保持しており、そのサブドメイン以下の情報についてはまったく関与していない。サブドメインを完全に信頼しているため、サブドメイン以下にどのようなホストが含まれているかについては、そのサブドメインに一任しまうことになる。サブドメインを設置しているからと、ノード毎にDNSサーバを設置しなくとも1台のDNSサーバで自身のドメインとサブドメイン情報の両方を管理する事は可能だ。しかし、腕のよい管理者ならば、サブドメインの情報の管理は、別のDNSサーバに任せてしまう方がよい。

理由として、一度組織にドメインが割り当てられれば、そのドメインで内でどのようなサブドメインを作ろうがホスト名を登録しようが、自由だ。ドメイン以下のことはそれぞれのドメイン管理者に任せてしまった方が管理効率は向上する。これを、上位ドメインからサブドメインに対する『権限委譲(delegation)』という。権限委譲とは、自身から別のDNSサーバへその部分の管理権限を委譲する、という意味である。すなわち、ドメイン・ツリーは世界中の無数のDNSサーバをつなぐ『信頼の連鎖』ツリーでもあるのだ。


 権限委譲とドメインの概念図

本稿をご覧になっている貴殿の会社のドメインも必ず、上位ドメインから権限委譲されている。例えば、criterion.scというドメインはscドメインから管理権限を委譲されている。各組織で該当ドメインを管理するためのDNSサーバーをインターネットに公開して(=外向きDNS)上位ドメインへ該当ドメインの権限委譲を登録すると、DNSでIPとホスト名を検索することが出来るようになる。

3ー2.DNS検索の仕組み

ここでは、どのようにしてDNSが名前解決をしているかについて解説していく。

すでに述べたように、DNSの名前解決はドメイン・ツリーに沿って行われる。下図のように、DNSはIPアドレスとホスト名を対応させるデータベースを持っている。端末からのホスト名に対するIPアドレスの問い合わせが発生した際に、DNSは自身のDBに登録されているリストの中から対応するIPとホスト名の組み合わせを探し出し、問い合わせてきた端末に対して結果を送り返す。

すべての、IPアドレスとホスト名の対応表をDBに持っているDNSが世界に1台あればよいというわけではない。その方法では、山のようにあるIPやホスト名の対応情報を漏れなく登録することは実質不可能になる。この問題を解決する手法としてDNSのリゾルバ機能だ。

今、クライアントが“hermes.criterion.sc”にアクセスしたいと思った場合、ネットワークのトポロジィ上1番近いDNSに問い合わせをかけるのだが、そのDNSが必ずしも“hermes.criterion.sc”を知っているとは限らない。このような場合、ローカルDNSはまず「ルートサーバー」と呼ばれるサーバー(これは世界に13台ある)に問い合わせを掛けることになっている。ルートサーバーは、“hermes.criterion.sc”の最後の“sc”に着目し、“.sc”というトップドメインを管理しているDNSのIPアドレスを返してくる。そこでローカルDNSは次に“.sc”を管理しているサーバーにリクエストを出すと、“criterion.sc”を管理しているサーバーのIPを得るわけで、3度目にはついに“hermes.criterion.sc”のIPアドレスを得ることができ、これがクライアントに返ってくる。

実は、DNSの処理の仕組みは、拠点から中枢に向かって処理を集めて一括処理を行い、結果を拠点に返すという旧来の日本型の一括集中処理を行っている。

この方式により、DNSは自分が知らないホストのIPアドレスも、問題なく取得できるようになっている。基本的にルーサーバーに向けてDNSは問い合わせをしているのだが、いっせいに世界中からルートサーバーに向けて問い合わせが発生したら、たった13台しかなくともルートサーバー処理する。DNSは分散してIP-ホスト名の情報を持っているが、最終的にはルートサーバーが問い合わせに対して返答しているので、負荷分散ではない。

上記でも述べたように、ルートサーバーへの負荷はそれなりに大きい。そこでDNSサーバーは一定期間ならば、1度問い合わせた結果はキャッシュに格納することでルートサーバーへの不用意なトラフィックを増やさない、という工夫(=DNSラウンドロビン)でルートサーバーへの負荷軽減を実施している。

例えば、クライアントが“hermes.criterion.sc”をリクエストするたびに、もう1度ルートサーバーからアクセスしなおすのは無駄だ。そこで1回目に“criterion.sc”ドメインから“hermes.criterion.sc”の IPアドレスを取得した際に、“hermes.criterion.sc”=“203.141.134.6”を自分のキャッシュに蓄えておき、2 度目以降はこのキャッシュをみて即座にクライアントにIPアドレスを返すという仕組みが備わっている。もちろんこのキャッシュの仕組みはDNSのみならず、クライアント側でも有効となっている。
ただし、キャッシュの場合は適当な頻度で更新をかけないと、データが変わっている場合がある。DNSでは、値を返す際にその値の有効期限(TTL:Time To Live)も一緒に返しており、値を取得してからTTLに定められる時間が経過したあとは、キャッシュをいったん破棄してもう1度サーバーから最新の値を取得することが必要とされている。

一般的に、サードレベルのドメイン(=sentan-college)は基本的に組織単位で持つ。組織内のDNSとは、1つのDNSの中にキャッシュサーバーとドメインサーバーとがある。キャッシュサーバーは内部のネットワークからのリゾルバによって組織外のDNSへ問い合わせる。ドメインサーバーは組織外からの問い合わせに返答する、というように明確に分かれている。組織内のDNSリゾルバの処理をしたいだけならば、キャッシュサーバーだけで十分、ということもありうる。

リゾルバ(resolver)とは、ドメイン名を元にIPアドレスの情報を検索したり、IPアドレスからドメイン名の情報を検索する、といった名前の解決(name resolution)を行うプログラムのことをを示す。ネームサーバがDNSの情報提供を担う側であるのに対し、それを利用してドメイン名から必要な情報を解決(resolve)する側になる。リゾルバには「フルサービスリゾルバ (Full-Service Resolver)」と「スタブリゾルバ(Stub Resolver)」があるが、単に「リゾルバ」と呼んだ場合には、「スタブリゾルバ」を一般的に指す場合が多い。スタブリゾルバは、利用者から出される要望を元に、端末側で動作する検索プログラムに該当する。

Webブラウザやメールソフトでドメイン名を入力する場面では、そのアプリケーションは、実際に通信を行うサーバのIPアドレスを調べるために、スタブリゾルバを呼び出す。スタブリゾルバはフルサービスリゾルバとの橋渡しとして動作し、調べたいドメイン名に関して再起検索をしてもらい情報を得る。

スタブリゾルバは、フルサービスリゾルバやコンテンツサーバとは異なり、単独の名前の付いたプロセスではない。関数やライブラリとしてOSから提供されることが多い。Windowsの「TCP/IP のプロパティ」や UNIX 系OSの/etc/resolv.confにネームサーバのIPアドレスを指定する箇所があるが、これはスタブリゾルバの動作を制御するもので、交信するフルサービスリゾルバを指定している。

ネームサーバは、以下の3つの働きが組み合わされてる。

コンテンツサーバ(Contents Server)

自分が管理しているゾーンに対する問い合わせだけに回答する。名前解決ができなくてもほかのネームサーバへの問い合わせはせず、自らが管理しているデータベースに該当する情報がなければ「情報はない」と答える。

フルサービスリゾルバ(Full-Service Resolver)

スタブリゾルバから送られる「再帰(Recursive)検索」要求を受け、名前解決が完了するまで、それぞれの名前についてほかのネームサーバに「反復(Iterative)検索」という形で問い合わせをする。また、その結果をスタブリゾルバに返答する。
このとき、同じ問い合わせを何度も繰り返すという非効率を避けるため、一度名前解決をしたドメイン名を内部にキャッシュして再利用することから「キャッシュサーバ」とも呼ばれる。最近では、こちらの呼び名の方が出現頻度は高くなっている。

スタブリゾルバ(Stub Resolver) 利用者側から出される要望を基にフルサービスリゾルバと交信し、調べたいドメイン名を渡して必要な情報を教えてもらう、端末側で動作する検索プログラム。単に「リゾルバ」と呼ばれることもある。

このように、普段クライアントPCへ設定している『DNSサーバ』の項目は、多くの場合、実はマスタ・サーバではなく、フルサービスリゾルバなのだ。DNSサーバにはさまざまな機能が実装されており、多様な使用方法があるということなのだが、技術書によっては、これらの違いは当然のこととして表されている場合も多い。最初は分かりにくいと思われるので、しっかりと把握して混乱しないようにしたいところだ。

3ー3.ルートサーバー

既に述べているが、DNSのルートサーバーは世界中に13台存在する。 この記事を読んでいる聡明な方は不安を覚えるのではないだろうか。世界中に分散しているとはいえ、たったの13台のサーバーでインターネットという巨大なネットワークのDNSのルートサーバーを担ってると言うことに。 実は、ルートサーバー13台というのは、ルートサーバーのグローバルIPが13個という事だ。全てではないが、負荷分散やリスク分散のために同一のグローバルIPアドレスを持つルートサーバーを複数の地域に配置していたりする。そのため、災害やテロなどで13台のうちのどれかグローバルIPの割当たったルートサーバーが運悪く破壊されたとしても、ルートサーバーの台数が減ったり、処理能力ががた落ちになることは基本的にはない。

すべてのルートサーバは"*.ROOT-SERVERS.NET" のホスト名 を持ち、各DNSサーバはこれらのIPアドレスを問い合わせることなしにあらかじめ知っている必要がある。 "*" の部分には、AからMまでのアルファベット一文字が入る。 ルートサーバは世界各国の企業・団体が管理しているが、サーバ本体と同様にその多くはアメリカ合衆国の団体が管理しており、アメリカ政府(アメリカ合衆国大統領等)や支配層による、法的・政治的介入の危惧等、インターネットの管理・運営の問題点のひとつとして挙げられている。もちろん日本の団体が管理するルートサーバもあり、WIDEプロジェクトが管理しているルートサーバのM.ROOT-SERVERS.NETがそれである。

(1) ルートサーバの特徴

世界中に分散配置している13台のルートサーバーは各々が同じデータを持ち、負荷分散を行っている。既に知られている範囲では、米VeriSign社に2台、ネットワーク管理団体IANA、ヨーロッパのネットワーク管理団体RIPE-NCC、米PSINet社、米ISI(Information Sciences Institute)、米ISC(Internet Software Consortium)、米Maryland大学、米航空宇宙局(NASA)、米国防総省、米陸軍研究所、ノルウェーのNORDUnet、日本のWIDEプロジェクトで各1台ずつ、といった具合に分散配置して各々の団体で管理している。

よく勘違いされがちなのが、分散配置されている国や地域ごとの特性(=地域性)は上記で述べた理由によりルートサーバーが持つことはない。地域性のような特徴を持つのは ".com" ".jp" ".net" といったトップレベルドメインのDNSサーバーだ。ルートサーバーは全てのトップレベルドメインのDNSサーバー のIPアドレスを持つのが特徴だ。

(2) インターネットの弱点

ルートサーバはインターネットの大動脈のひとつであり、非常に重要な位置を占めている。仮にルートサーバがダウンすると、ホスト名やドメイン名によるアクセスが一切不可能になり、通常のURLやメールアドレスも機能しなくなる。また、各DNSサーバはルートサーバのIPアドレスをあらかじめ知っている必要があるので、ルートサーバのIPアドレスを変えると全てのDNSサーバを再設定する必要が出てくる。そのため、ルートサーバのIPアドレスを変更することは滅多に無い。

(3) ルートサーバの過不足

上記でも述べたがルートサーバー13台というのはあくまでグローバルIPの数であり、実際には冗長構成によりサーバー機台数では13台以上が稼働している。では、ルートサーバは13台(=13個のグローバルIP)だけで本当に足りるのだろうか、という疑問が聡明な方は考えるだろう。

じつは、最上位のルートサーバなら既にトラフィック・応答負荷に関しては間に合っているレベルまで構成をされており、 プライマリ1台 、 セカンダリ12台 で全く問題がないため現在このような構成となっている。そもそも、最上位のルートサーバは各国別のトップレベルドメインのみを記憶して順次下の階層のDNSサーバーに問い合わせればよいので13台で十分なのだ。

4.サーバー構築の手順

(1)IPアドレスと名前解決の方法

/etc/hostsファイルとDNS
DNSの必要性

(2)ネットワークの構成とDNSのカバー範囲

ネットワークの公開範囲の確認
DNSでカバーする範囲の確認(外向けのみか、外と内の両方か)
キャッシュサーバー

(3)DNSの設定

/var/named/etc/named.conf
/var/named/standard/root.hint ・・・ ルートサーバーの設定ファイル
/var/named/standard/hades.criterion.zone ・・・localhostの正引きファイル
/var/named/standard/hades.criterion.rev ・・・ localhostの逆引きファイル


正引きゾーンファイル ドメイン名 -> IPアドレス
逆引きゾーンファイル IPアドレス -> ドメイン名

従来のUNIX系OSでは/etc/named.confや/var/named/以下にファイルが置かれている。FedoraCoreほどではないが、深い階層に設定ファイルを設置する理由としては、従来とはパスを変えて第三者に分かりにくくするセキュリティ対策と考えることが出来る。

(4)サービスの起動と停止

(5)DNSの動作環境

ローカルホストでのDNSの動作確認テスト

クライアントテストWindowsネットワーク設定(TCP/IP)でのDNS設定に相当

※ 本実習でのドメイン名はcriterion.scとします。

5.BINDの基本設定

DNS(Domain Name Service)はIPアドレスとホスト名とを相互に変換するデータベースでドメインネットワーク内のIPとホスト名との対応を管理している。UNIXやUNIXクローンOSの多くで利用されるDNSはBIND(Berkley Internet Name Domain)というインターネットの世界では最も多く利用されている。いわばデファクトスタンダードだ。いかに、Microsoftが物量戦を仕掛けてこようとも、ネットワークの創世記からインターネットの隆盛とともに成長を続けてきたBINDには導入実績や信頼性ではかなうものではない、というのが現状だ。
本実習実習環境のOpenBSDに含まれるバージョンはBIND9であり、BIND8と比較してもセキュリティ面が大幅に強化されたものとなっており、IPv6にも対応している。

一般にBINDの設定すべきファイルは

/var/named/etc/named.conf
/var/named/standard/直下の
正引きゾーンファイル(ホスト名 -> IPアドレス)
逆引きゾーンファイル(IPアドレス -> ホスト名)
正引きループバックファイル
逆引きループバックファイル

■hostsファイル

DNSの原型となるプレーンテキストファイルで、1行ごとに名前解決を定義する。hostsファイルはlocalhost内でのみ名前解決に利用できる。したがって、hostsファイルでLAN内の名前解決をしたいときはLAN内のすべての端末及びサーバーに同じ内容のhostsファイルを用意する必要がある。

#vi /etc/hosts

hostsファイルを下記のように記述する。

127.0.0.1 localhost localhost.domain
10.0.1.100 hades.criterion.sc

※ 本実習ではサーバーのアドレスを10.0.1.100、サーバーのホスト名をhades.criterion.scとする。

host.confファイルはlocalhost内での名前解決に利用する仕組みの優先順位を指定する。

# vi /etc/host.conf

order dns,hosts

■DNSクライアント

UNIXおよびそのクローンOSをDNSクライアントとして利用する場合には、設定ファイル/etc/resolve.confにDNSサーバーのIPアドレスを設定する。

(設定例)

#vi /etc/resolve.conf

lookup file bind
nameserver 10.0.1.100

■プライマリDNSサーバ-の設定

DNSサーバーは、同一ドメイン内にマスターサーバーと、スレーブサーバー(=バックアップ用)を用意するのが通例で、スレーブサーバーは何台あってもかまわない。
実際、マスターサーバーにLAN内のDNSを指定し、スレーブサーバーにプロバイダのDNSを指定することも多い。

6.named.confの設定

ここからは、いよいよDNSの設定に関わる設定ファイルを変更していく。

■/var/named/etc/named.confの設定

UNIXや他のUNIXクローンOSでは/etc/named.confに相当するが、OSに標準で用意されているnamed.confの内容を以下に示す。
ちなみに、OpenBSDでは標準でIPv6対応に関するzoneの記述部分が追加されているので、自身でDNSサーバーを建てるときに参考にするとよいだろう。

(named.confのデフォルトの記述)

// $OpenBSD: named-simple.conf,v 1.6 2004/08/16 15:48:28 jakob Exp $
//
// Example file for a simple named configuration, processing both
// recursive and authoritative queries using one cache.


// Update this list to include only the networks for which you want
// to execute recursive queries. The default setting allows all hosts
// on any IPv4 networks for which the system has an interface, and
// the IPv6 localhost address.
//
acl clients {
localnets;
::1;
};

options {
version ""; // remove this to allow version queries

listen-on { any; };
listen-on-v6 { any; };

allow-recursion { clients; };
};

logging {
category lame-servers { null; };
};

// Standard zones
//
zone "." {
type hint;
file "standard/root.hint";
};

zone "localhost" {
type master;
file "standard/localhost";
allow-transfer { localhost; };
};

zone "127.in-addr.arpa" {
type master;
file "standard/loopback";
allow-transfer { localhost; };
};


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.arpa" {
type master;
file "standard/loopback6.arpa";
allow-transfer { localhost; };
};

zone "com" {
type delegation-only;
};

zone "net" {
type delegation-only;
};


// Master zones
//
//zone "myzone.net" {
// type master;
// file "master/myzone.net";
//};

// Slave zones
//
//zone "otherzone.net" {
// type slave;
// file "slave/otherzone.net";
// masters { 192.0.2.1; [...;] };
//};

DNSサーバーの設定時に施すnamed.confファイルへの変更はゾーンファイル記述の追加だ。

ゾーンファイル記述はnamed.confの末尾、zone "127.in-addr.arpa" {のコードブロックの末尾と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.arpa" {の間に行を挿入し、記述する。

(記入例)

zone "criterion.sc" {
type master;
file "standard/hades.criterion.zone";
allow-transfer { localhost; };
};


zone "1.0.10.in-addr.arpa" {
type master; file "standard/hades.criterion.rev";
allow-transfer { localhost; };
};

ゾーン名称はDNSサーバーが所属するネットワークに対応した正しい名称を設定する。対応するゾーンファイル名は/var/named/standard/(※通常のUNIXやそのクローンOSの場合は/var/named/)下に存在するファイル名であれば何でもよい。ただし、そのファイルが正引きなのか逆引きなのか分かるものにしてあることが好ましい。一般的には正引きファイルは*.zone(例:hades.criterion.zone)、逆引きファイルは*.rev(例:hades.criterion.rev)、といったファイル名が好まれる傾向にある。

■/var/named/etc/named.confの内容

上記で紹介したnamed.confのそれ以外の記述の注目点について解説する。

32行目の記述。

zone "." {

コレは、ルートサーバーの情報を参照することを示している。

34行目の記述。

file "standard/root.hint";

これは、外部のDNSへの問い合わせは、RootServerに問い合わせるという意味。named.confを記述しているサーバーがスタブサーバーの時にはコメントアウトするか書かない。それ以外の場合は、必ず書くことが必須である。

37行目の記述。

zone "localhost" {

コレは、ローカルホストの正引きを示している。

50行目の記述。

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.arpa" {

コレは、IPV6用のローカルホストの逆引き。

■ゾーンファイルの設定

OpenBSDのゾーンファイルの実体は、/var/named/standard/に作成するようになっている。

ゾーンファイルにはそれぞれレコードが定められていて、DNSのサービスを提供している。下記にそのレコードとその役割について説明する。

SOA(Start Of Arthority) ・・・ ゾーンデータベースの最初に記述する。
NS(Name Service) ・・・ ゾーンを管理するDNSサーバー一覧
MX(Mail Exchange) ・・・ メールの配送先
A(Address) ・・・ ホスト名に対応したIPアドレス
CNAME(Canonical Name) ・・・ サーバーに別名をつける。
PTR(Pointer) ・・・ IPアドレスからホスト名に変換

以下に正引きゾーンファイルと逆引きゾーンファイルの記述例を示す。

■正引きゾーンファイル(hades.criterion.zone)の記述例

$ORIGIN hades.criterion.zone.
$TTL 86400
@ IN SOA hades.criterion.zone root.criterion.zone. (
2006071503 ; Serial (d. adams)
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum

IN NS hades.criterion.zone.
IN MX 10 mail.criterion.sc.
hades IN A 10.0.1.100
dns IN CNAME hades
www IN CNAME hades
mail IN CNAME hades

正引きゾーンファイルの記述について解説していく。
まず、1行目の$ORIGIN以降の記述だが、これは管理するネットワーク(=ドメイン名)を記述する。
2行目の$TTL(=Time To Live)はDNSサーバーのキャッシュ生存期間。ココでは86400(秒)と書かれている。これは、DNSサーバーのキャッシュが24時間有効であることを示している。
3行目の@ IN SOAの以降は、このIPアドレス(=10.0.1.100)のホストの名前解決をするホスト名を記述する。上記の例では、hades.criterion.scとroot.criterion.scのホスト名をこのIPアドレス(=10.0.1.100)として解決している。解決したいホスト名が複数ある場合は半角スペースで区切る。最後のホスト名の末尾に.(ピリオド)を入れることを忘れないように注意。 上記の3行は先頭にスペースやタブをいれずに右詰めで記述しないと、DNSが有効にならないので注意すること。 4〜10行目はスペースやタブをいてれもかまわない。 Serial・・・更新フラグを示す。ゾーンファイルを書き換えるたびに更新日時を書き込んで記録しておく。
Refresh・・・DNS情報のリフレッシュ間隔(秒)
Retry・・・ココで記述した時間(秒)応答がなければタイムアウトする。
Expire・・・DNSの認証期間(秒)
IN NS以降の記述は、このゾーン(=該当のドメインのネットワーク範囲)を管理しているDNSサーバーの一覧を記述する。複数台記述は可能だが、ホスト名とホスト名はスペースで区切り、最後のホスト名の末尾には必ず、.(ピリオド)を入れることを忘れないように注意。
10行目の記述、 IN MX 10 mail.criterion.sc.だが、これは、DNSサーバーが要求を受け付けたメールの配信先サーバーを記述する。上記の例では、1台しか書いていないが複数台記述することが出来る。MXの後に、10と云う記述があるが、これはDNSが要求を受け付けたメール配信サーバーの優先順位である。
MX 10 ・・・ 第1優先
MX 20 ・・・ 第2優先
MX 30 ・・・ 第3優先
第2優先、第3優先のメールサーバーを記述した際には、下にIPアドレスとホスト名の対応、サーバー名に対する別名を記述する必要がある。 11行目以降は再び、先頭にスペースやタブを入れては設定が有効にならない。コレからは、ホスト名に対するIPアドレスとの対応やゾーン内のサーバーの別名をつける。
hades IN A 10.0.1.100 ・・・ IPアドレス10.0.1.100のホストをこのゾーンではeaa00140として名前解決する。
dns IN CNAME hades ・・・ DNSサーバー(=dns)は上記で登録したhadesとして名前解決する。
www IN CNAME hades ・・・ WEBサーバー(=www)は上記で登録したhadesとして名前解決する。
mail IN CNAME hades ・・・ Mailサーバー(=mail)は上記で登録したhadesとして名前解決する。

hadesのホスト上では、DNS、WWW、MAILサーバーがそれそれ稼働していると仮定するため、上記のような記述になる。
また、DNS( = 10.0.1.100)、WWW( = 10.0.1.110)、MAIL( = 10.0.1.120)の各サーバーがそれぞれ独立したホストで稼働している場合は以下のように記述するとよい。

(各サーバーがそれぞれ独立したホストの場合)

$ORIGIN hades.criterion.zone.
$TTL 86400
@ IN SOA hades.criterion.zone root.criterion.zone. (
2006071503 ; Serial (d. adams)
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum

IN NS hades.criterion.zone.
IN MX 10 mail.criterion.sc.
@ IN A 10.0.1.100
hades IN A 10.0.1.100
dns IN A 10.0.1.100
www IN A 10.0.1.110
mail IN A 10.0.1.120

実際のサーバー運用では、1台のサーバーマシンでは複数のサーバーサービスを稼働させないのが常識だ。
Webサーバーとして稼働させているマシンならば、Webサーバー(例:Apache)しか稼働させないで他のサービスはすべて無効化しておく。

■逆引きゾーンファイル(hades.criterion.rev)の記述例

$ORIGIN 1.0.10.in-addr.arpa.
$TTL 86400
@ IN SOA hades.criterion.sc. root.criterion.sc. (
2007071501 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS hades.criterion.sc.
100 IN PTR hades.criterion.sc.

逆引きゾーンファイルの記述について解説していく。
まず、1行目の$ORIGIN以降の記述だが、これはDNSサーバーたる自サーバーのIPアドレスを逆に書く。例えば、IPアドレスが、10.0.1.100だったとする。ホストアドレス(.100)を抜いた値(10.0.1)の逆並びを記述し、その直後に.in-addr.arpa.と書く。以降9行目の記述までは上記の正引きゾーンファイルの記述と役割は同じである。
10行目、100 IN PTR hades.criterion.sc.100だが、これはDNSサーバーのIPアドレス(10.0.1.100)のホスト部分の100である。コレを記述しないと逆引きが出来ない。

7.BINDの起動確認

■ファイアウォール設定の変更

DNSサーバーに対するUDPポート場号53の開放をファイアウォールで設定する。

# vi /etc/pf.conf

pass in quick on fxp0 proto udp from any to 10.0.1.100 port 53 keep state

内部向けのDNSサーバーならば上記の設定でよいが、外部向けのプライマリDNSサーバーならばこれだけでは不十分。
下記のようにTCPとUDPの53番ポートを In Bound / Out Bound 設定をしておくことが望ましい。

# vi /etc/pf.conf

pass in quick on fxp0 proto { udp,tcp } from any to 10.0.1.100 port 53 keep state
pass in quick on fxp0 proto { udp,tcp } from any port 53 to 10.0.1.100 keep state

『(2) DNSにおけるUDPの制限』でも述べているがDNSでのデータのやりとりとしてUDPで接続する。UDPで接続していてデータ量が512byteを超えたときにはTCPで接続するように設計されている。
基本的にDNSはUDPの53番ポートの解放のみで十全に稼働するように設計されている。実際に、UDPの53番ポートのみを解放したDNSサーバーでも名前解決(正引き / 逆引き)ができる。

TCP 53番ポートを開放するのは、主にセカンダリDNSサーバーにゾーン転送をする場合に必要となる。また、ドメイン名の問い合わせに対して、不完全な応答をDNSレゾルバ(=DNSクライアント)に返すと、DNSレゾルバがTCP 53番ポートへ接続しに来る。
通常、DNSレゾルバはUDP 53番ポートを使用して複数のDNSサーバーへ問い合わせを行い、最も応答の速いDNSサーバーの回答を採用してキャッシュする。

外向きDNS構築の際にはプライマリとセカンダリのDNSがそれぞれ必要になる。実際に構築すれば分かることだが、プライマリDNSを自前で構築してセカンダリを契約ISPや外部のホスティング業者などに外部委託することが多い。すると、プライマリとセカンダリのDNSがそれぞれ別のネットワークに存在することになる。異なるネットワークにそれぞれ設置している場合は、TCP 53番ポートと外向きのUDP 53番を解放しておかないと、外部ネットワークからDNSが引けなくなってしまう。

PFに上記の記述をしたら、変更を反映させるためにPFを再起動する。

# pfctl -f /etc/pf.conf

■デーモン(named)の状態確認

ここまで設定が済んだら、BINDの動作確認を行うために、デーモンたるnamedを起動する。
デーモンが起動していれば下記のように表示される。

number of zones: 8
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is OFF
recursive clients: 0/1000
tcp clients: 0/100
server is up and running

■初期起動設定

今の状態では、サーバーを再起動した際にBINDは停止したままになってしまう。
以下のように/etc/rc.conf を編集して起動・再起動時にも自動的にBINDが起動するようにしておく。

named_flags="" # for normal use: ""

8.DNSサーバーとUDP

(1) DNSがUDPを使う理由

DNSにおける名前解決では、やりとりされるデータが小さいことから原則として問い合わせ・応答ともに1パケットのUDPで行えるように設計されている。これはTCPに比べてUDPはプロトコルオーバヘッドが小さいという利点に起因している。

TCPでは、実際にデータを送信するまでにセッション確立の処理や、送信データの受信チェック、受信されなかった場合には再送要求を出すなどの通信の信頼性を確保するためにさまざまな処理を行っている。そのため、クライアントおよびサーバ上での処理に掛かるプロトコルオーバヘッドはUDPに比べて大きい。また、小さなデータをやりとりするときでも、TCPはこれらの一連の処理を行うので非効率的だ。

UDPは、TCPのような通信の信頼性確保のための処理を行わず、その分クライアントおよびサーバ上でのプロトコルオーバヘッドは小さくなる。

このことからDNSのように小さなデータをやりとりする場合においては効率的、かつ高速に動作する。UDPで信頼性が必要な場合はアプリケーション側(=DNSサーバ、リゾルバ)で再送要求を出すなどの処理が必要となる。

(2) DNSにおけるUDPの制限

DNSの名前解決では、問い合わせ及び応答メッセージはDNSが利用するUDPの制限で、512bytesまでと決まっている。これはIPパケットがフラグメンテーションを起こさないことが保証される最大サイズから設定されている。

この制限がないと、サイズの大きなUDPパケットはIPパケットがフラグメンテーションを起こし、パケットがロスした場合の処理やパケットの到着順番を変えるなどの複雑な処理が必要となる。DNSではこのような複雑な処理を実装することはせず、必要に応じてUDPの代わりにTCPを利用することにしている。

メッセージの大きさが制限されることにより、やりとりする情報の量も制限を受ける。ルートサーバの数が全世界で13台しかないのも実はこの制限により、やりとりできるNSレコードの数の上限が決まってしまうことによる。

またDNSサーバがIPv6のレコードであるAAAAを持つ場合においては、IPv6のアドレス長が128bitsとIPv4に比べて4倍になっているため、このサイズ制限をさらに圧迫する。

現在、DNSSECやIPv6の名前解決などの、より多くの情報量が必要となるものに対しては、DNSの拡張プロトコルであるedns0を使用することで、より大きなサイズのUDPパケットを扱うことが可能となっている。世の中で使用されているDNSサーバソフトウェアがすべてedns0に対応しているわけではないが、これが広まればこのUDPのサイズ制限問題が緩和されることになる。

9.DNSサーバーの動作確認

DNSサーバーによる名前解決が出来ているか、動作確認。
DNSでエラーが起こっていればログファイル/var/log/messagesにDNSのエラー内容が記述されるので以下のようにコマンドを打ち込んで、確認する。

# tail -f /var/log/messages

DNSクライアントとして/etc/resolv.confの記述で下記の記述があることを確認する。

domain local
nameserver 10.0.1.100 <- 対象のDNSサーバーのIPアドレスを入力すること

■nslookupで動作確認

(正引き)

#nslookup
> hades.criterion.sc
Server: 10.0.1.100
Address: 10.0.1.100#53

Name: hades.criterion.sc
Address: 10.0.1.100
> dns.criterion.sc
Server: 10.0.1.100
Address: 10.0.1.100#53

dns.criterion.sc canonical name = hades.criterion.sc.
Name: hades.criterion.sc
Address: 10.0.1.100
> www.criterion.sc
Server: 10.0.1.100
Address: 10.0.1.100#53

www.criterion.sc canonical name = hades.criterion.sc.
Name: hades.criterion.sc
Address: 10.0.1.100
> mail.criterion.sc
Server: 10.0.1.100
Address: 10.0.1.100#53

mail.criterion.sc canonical name = hades.criterion.sc.
Name: hades.criterion.sc Address: 10.0.1.100

(逆引き)

# nslookup
> 10.0.1.100
Server: 10.0.1.100
Address: 10.0.1.100#53

100.1.0.10.in-addr.arpa name = hades.criterion.sc.

上記のような結果が返ってくれば、サーバー上ではDNSの稼動が確認できた。

次に、同一ネットワーク上のクライアントPCからDNSサーバからの名前解決が可能かを確認する。

C:\nslookup
>hades

Server: 10.0.1.100
Address: 10.0.1.100#53

Name: hades.criterion.sc
Address: 10.0.1.100

C:\nslookup
>10.0.1.100
Server: 10.0.1.100
Address: 10.0.1.100#53

100.1.0.10.in-addr.arpa name = hades.criterion.sc.

上記のような結果が返ってくれば、クライアントPC上でのDNSの稼動が確認できた。

10.DNS実装の More One Trick

独自のドメインを取得してサーバーを稼働させると言うことは、サーバーが常時インターネットに接続されていることが前提となる。近年、急速に高速インターネットが普及したことにより、フレッツADSLやフレッツFTTHなどのような低価格での常時接続が当たり前の環境となったのは個人でサーバーを運用する上では大きな利点だ。

本章では、一般的なブロードバンドインターネット利用者が自前で構築したサーバーにドメイン名を割り当てて運用していく方法について説明していくものとする。

10ー1.DDNSとは

サーバにアクセスするためには、サーバのグローバルIPかドメインを指定する必要がある。毎回IPアドレスを入力するのが煩わしい問題もあるが、固定IPサービスでない限りはプロバイダから割り当てられるグローバルIPはしばしば変わるため、その都度グローバルIPを調べなければならない。これは非常に面倒な作業であり、とてもではないが多くの方に自宅サーバーを訪れてもらうわけにはいかない。分かりやすいドメイン名で自宅サーバーにアクセスできるようにしたい。

通常ドメインでサーバーにアクセスするためには、固定のグローバルIPをサーバーに割り当てている必要がある。
ならば、固定IPサービスを申し込もうとISPのサービス案内を読み進めるうちに月々の使用料金がバカにならないことに気ずく。そんな場合は、動的なIPでもドメインが使えるDDNSサービスはいかがだろうか。

DDNS(Dynamic DNS)とは動的グローバルIPとドメイン名を結びつけるサービスだ。まずはDDNSサービスで利用できるドメインを取得する。そして、サービスのウェブサイトでプロバイダから割り当てられたグローバルIPを登録する。すると外部の人はいつも同じドメイン名を指定することで貴殿の構築したサーバーに接続できるようになる。DDNSサービスは有料のものから無料のものまで、多くの種類のサービスが提供されている。ご自身にあったサービスを選んで利用してみよう。

無料のDDNSではサーバーが公開できない、というわけではない。取得できるドメインやDDNSに対応させることの出来るドメインに制約が出来るだけだ。本格的にドメインを運用したいのであるのなら、有料のDDNSにサービス利用を申し込んでみると良いだろう。

独自ドメインを取るのは難しいように思えるが、実際にやってみると意外と簡単だったりする。現在では、オンライン決済でドメインの取得ができるので書面のやりとりは不要だ。早ければその日のうちに独自ドメインの設定ができてしまう。

小生は手続きが出来るだけ簡単で運用の煩わしさが極力少なさそう、という理由でお名前.comというレジストラを選択した。通常、独自ドメインでサーバ運用するには、独自ドメイン取得 -> DDNSサービスの登録 -> レジストラにDNSサーバ設定を行う。お名前.comではこの一連の手続きが一括して行うことが出来る。

本件作業で注意すべき箇所はDNSサーバーの設定だ。DNSサーバーの設定を行わないと該当のサーバーに閲覧者を誘導することができない。DNSサーバーとはユーザーがドメイン名を入力したときに、対応するIPアドレスを返すものだ。

ユーザーがドメイン名でサーバーにアクセスしようとしたとき、まずDNSのルートサーバーにドメイン名に対応するIPアドレスを問い合わせる。しかし、ルートサーバーはすべてのドメイン名とIPアドレスの対応を記憶しているわけではなく、実際に対応を記録しているDNSサーバーのアドレスをかえす。自宅サーバーの場合は自分が登録したDDNSサービスにこの対応は記録されている。そして、ユーザーにはDDNSサービスからドメイン名のIPアドレスを通知する。

ここで問題になるのが、自分のドメイン名のIPアドレスを格納したDDNSサービスの情報を、あらかじめルートサーバーに登録しておかなければならないところだ。ユーザーが直接ルートサーバーに情報を登録できるわけではないので、レジストラにDDNSのアドレスを登録しておくと登録を代行してくれる。DDNSサービスへの登録を行ってもレジストラへの登録を忘れるといつまでたっても『ドメイン名は見つかりません』のエラーになってしまうので、レジストラへは忘れずにDDNSの情報を登録するようにしておこう。

10ー2.外向きDNSの構築

既に幾度か述べてきたことだがDNSとはホスト名に割り振られているIPアドレスとホスト名(=ドメイン名)を対応させる機構である。これには、イントラネットもインターネットも基本的な違いがない。
閉じたネットワーク(=イントラネット)内でホスト名とIPアドレスの対応を行うのが内向きDNSならば、公開されたネットワークでIPアドレスとドメイン名を対応させるのが外向きDNSである。

10-2-1.DNSサーバの種類

外向きDNSを扱う上で、まず理解しなければならないのは、『プライマリDNS』と『セカンダリDNS』という言葉である。

本稿を読み進みながら実際に作業を行ってきた貴殿はご理解いただけると思うが、通常ネットワーク管理者がドメインのホスト情報を追加・変更・削除を行う場合、プライマリDNSに対してその操作を行う。そして、プライマリDNSに登録情報( = ゾーン情報)の変更を反映させると、自動的にセカンダリDNSへその設定内容がコピーされる( = ゾーン転送)。基本的にセカンダリDNSは定期的にプライマリDNSへ接続し、プライマリDNSに設定されているゾーン情報を取得して、同じくDNS問い合わせに応答するためのサーバだ。

プライマリDNSとセカンダリDNSの違いは、ゾーン情報をローカルのゾーン情報ファイルから入手するか、ほかのDNSサーバ(=プライマリDNS)から入手しているかの違いでしかない。問い合わせ側ではとくに区別はできない。リゾルバは通常、複数のDNSサーバからランダムに選択して利用することになる。視点を変えて観察すると、複数台のDNSサーバがすべてプライマDNSという設定も可能だ。見かけ上はプライマリセカンダリの違いは分からないのだから問題はない。ただし、ゾーン情報をそれぞれのサーバで設定することとなり、手間が増える。・・・あまり意味はないだろう。

プライマリDNSがドメインに1つだけ存在するのに対し、セカンダリDNSはいくつあってもかまわない。複数台のDNSサーバをそのドメインのセカンダリDNSサーバとすることで、障害時の対応や問い合わせ負荷の分散を行ってくれる。
インターネット上にサーバを公開する場合、DNSは最低でも2つ(=プライマリDNS、セカンダリDNS)指定しなければならないことになっている。

WHOISでドメインを検索すると、そのドメイン情報を登録しているネームサーバーの情報を調べることが出来る。
題材に本ドメインを取り上げると、DNSは4つある。WHOISの検索結果だけではどれがプライマリのDNSかは分からないが、4つのうちの1つでも正常稼働していればインターネットサービスが停止するおそれはない。

10-2-2.外向きDNSの実装

ここまでの作業で内向きのDNSは稼働するようになっているかと思われる。
本章では、外向きDNSの構築方法について学んでいくものとする。

(1) 正引き

DNSの設定ファイルを一部改変して、内側向きだけでなく外向きのDNSとしても使えるように変更してみよう。
bind9になってからview機能が実装され、LAN側設定とWAN側設定を簡単に分けて記述できるようになった。
では、/var/named/etc/named.confを以下のように書き換えてview機能を実装させてみよう。

プライマリDNS(外向き)のnamed.confの記述例

// $OpenBSD: named-simple.conf,v 1.6 2004/08/16 15:48:28 jakob Exp $
//
// Example file for a simple named configuration, processing both
// recursive and authoritative queries using one cache.


// Update this list to include only the networks for which you want
// to execute recursive queries. The default setting allows all hosts
// on any IPv4 networks for which the system has an interface, and
// the IPv6 localhost address.
//
acl clients {
localnets;
::1;
};

options {
version ""; // remove this to allow version queries

allow-transfer {
203.141.134.6; // -> プライマリのDNS
203.141.128.33; // -> セカンダリのDNS
};

listen-on { any; };
listen-on-v6 { any; };

// allow-recursion { clients; };

};

logging {
category lame-servers { null; };
};

view "inner" { // LAN側の設定
match-clients { clients; };


// Standard zones
//
zone "." {
type hint;
file "standard/root.hint";
};

zone "localhost" {
type master;
file "standard/localhost";
allow-transfer { localhost; };
};

zone "127.in-addr.arpa" {
type master;
file "standard/loopback";
allow-transfer { localhost; };
};

zone "criterion.sc" {
type master;
file "standard/hades.criterion.zone";
allow-transfer { localhost; };
};


zone "1.0.10.in-addr.arpa" {
type master; file "standard/hades.criterion.rev";
allow-transfer { localhost; };
};


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.arpa" {
type master;
file "standard/loopback6.arpa";
allow-transfer { localhost; };
};

zone "com" {
type delegation-only;
};

zone "net" {
type delegation-only;
};


// Master zones
//
//zone "myzone.net" {
// type master;
// file "master/myzone.net";
//};

// Slave zones
//
//zone "otherzone.net" {
// type slave;
// file "slave/otherzone.net";
// masters { 192.0.2.1; [...;] };
//};
}; // -> LAN側設定完了

view "outer" { // -> WAN側の設定
match-clients { any; };

zone "criterion.sc" { // -> 自ドメインの正引き
type master;
file "standard/hades.criterion.outer.zone";
allow-transfer { 203.141.128.33; }; // -> セカンダリのDNSへ転送する
};

zone "6/32.134.141.203.in-addr.arpa" { // -> 自ドメインの逆引き
// 203.141.134.6/32を左右逆転させると6/32.134.141.203となる
type master;
file "standard/hades.criterion.outer.rev";
allow-transfer { 203.141.128.33; }; // -> セカンダリのDNS(逆引き可)へ転送する
};

}; // -> WAN側の設定完了

本稿で扱っているサーバーは自宅サーバであり、回線やサーバが落ちたらアクセスできない。したがって、セカンダリDNSは不要とも考えられる。しかし、よく考えてみよう。
障害時にネガティブキャッシュに落ちてしまう可能性もある。そうなると、障害が復旧してもすぐにはアクセスできない事態が十分に想定される。迅速な復旧のためにはプライマリDNSのバックアップとして稼働するセカンダリDNSが必要不可欠なのだ。

これが、DNSでは必ずプライマリとセカンダリを準備する理由だ。小生は契約しているISPのセカンダリDNSを利用することにした。

プライマリとは異なりセカンダリDNSには選択肢が多い。貴殿の状況に合わせて適切なセカンダリDNSを事前に用意しておくことをお勧めしておく。

次に、外向けDNS用の正引きファイル(=hades.criterion.outer.zone)を作成する。
記述方法は基本的に内向きの場合と同じ。ただし、外向きに多少のアレンジを加える。

hades.criterion.outer.zoneの記述例

; $OpenBSD: db.localhost,v 1.2 2005/02/07 06:08:10 david Exp $

$ORIGIN criterion.sc.
$TTL 24h

@ IN SOA hades.criterion.sc. root.criterion.sc. (
20061222 ; serial
1h ; refresh
30m ; retry
7d ; expiration
1h ) ; minimum

IN NS hades.criterion.sc. // プライマリのDNS(自DNS)
IN NS tegtan1.interlink.or.jp. // セカンダリのDNS
IN MX 10 mail.criterion.sc.
@ IN A 203.141.134.6
hades IN A 203.141.134.6
dns IN A 203.141.134.6
www IN A 203.141.134.6
mail IN A 203.141.134.6

(2) 逆引き

最近の大手ISPでは固定IP(=グローバルIP)を割り当ててくれても、ISPが権限委譲してくれないために逆引きの設定をDNSに施しても逆引きが出来ないケースが多い。そのため、わざわざ逆引きの記述まで触れているサイトは少ない。そこで、当サイトでは逆引きファイル(=hades.criterion.outer.rev)の記述にも触れていきたい。

基本的に内向きDNSの場合と同じだが、外向きDNSということで多少のアレンジを加えると以下のようになる。

hades.criterion.outer.revの記述例

; $OpenBSD: db.loopback,v 1.2 2005/02/07 06:08:10 david Exp $

$ORIGIN 134.141.203.in-addr.arpa.
$TTL 24h

@ IN SOA hades.criterion.sc. root.criterion.sc. (
20061222 ; serial
1h ; refresh
30m ; retry
7d ; expiration
1h ) ; minimum

NS hades.criterion.sc. // プライマリのDNS(自DNS)
NS tegtan1.interlink.or.jp. // セカンダリのDNS
6 PTR hades.criterion.sc.

/etc/resolv.conf を以下のように変更する。

lookup file bind
nameserver 203.141.134.6 //プライマリのDNS(今回構築したDNSサーバーのグローバルIP)
nameserver 203.141.128.33 //セカンダリDNSを委託しているDNSのIP
nameserver 203.141.128.34 //プロバイダのDNS

ココまで作業が完了したら、残す作業は下記の3つのみ。

1.BINDの再起動

2.レジストラ情報の変更

小生は、独自のドメインを取得するときに”お名前.com”というレジストラで登録を行った。
本稿では、お名前.comをレジストラとして利用している場合を前提に説明をする。

[手順]

1) お名前.comにアクセス
2) ログインページから『ドメインNavi』にログインする
3) 『ホスト登録』から自身の固定IPをns.criterion.sc(=ネームサーバー名)として登録

  ネームサーバー名は基本的に自由だが、一般的にホスト名にnsを付けるのが通例となっている。

4) 『ネームサーバーの変更』から”ns.criterion.sc”をプライマリ、”(用意したセカンダリDNS)”をセカンダリDNSとして登録

3.動作確認

digコマンドで、DNSサーバから自分のIPが引けるか確認する

dig @ns.criterion.sc www.criterion.sc

(3) セカンダリDNSの引き受け

上記でも述べたが、セカンダリDNSの選択肢はそれなりに広い。選択肢の1つに、自宅サーバーを構築・運用している同志にセカンダリDNSを引き受けてもらう、という方法もある。

今回は、同志からセカンダリDNSを頼まれたと仮定してみよう!

実は、既に運用しているDNSサーバーでセカンダリDNSを引き受けるための設定は、実は簡単なのだ。
作業は実に、単純でnamed.confの外向きのViewのコードブロックにセカンダリDNSを引き受けるドメインのエントリーを追加するだけでよい。

今回 hogehoge.org というドメインのセカンダリDNS(-> プライマリDNSのIPは 10.20.30.40 とする)を引き受けるものとする。

(変更前)

view "outer" { // -> WAN側の設定
match-clients { any; };

zone "criterion.sc" { // -> 自ドメインの正引き
type master;
file "standard/deborah.criterion.outer.zone";
allow-transfer { 203.141.128.33; };
};

zone "6/32.134.141.203.in-addr.arpa" { // -> 自ドメインの逆引き
type master;
file "standard/deborah.criterion.outer.rev";
allow-transfer { 203.141.128.33; };
};

}; // -> WAN側の設定完了

(変更後)

view "outer" { // -> WAN側の設定
match-clients { any; };

zone "criterion.sc" { // -> 自ドメインの正引き
type master;
file "standard/deborah.criterion.outer.zone";
allow-transfer { 203.141.128.33; };
};

zone "hogehoge.org" { // -> セカンダリDNSを引き受けるドメインの正引き
type slave;
file "slave/hogehoge.org";
masters { 10.20.30.40; }; // -> セカンダリDNSを引き受けるドメインのプライマリ DNSのIP
};


zone "6/32.134.141.203.in-addr.arpa" { // -> 自ドメインの逆引き
type master;
file "standard/deborah.criterion.outer.rev";
allow-transfer { 203.141.128.33; };
};

}; // -> WAN側の設定完了

(4) ドメイン情報の反映に時間がかかる理由

本稿をご覧になっている貴殿はDNS情報の設定ミスやネットワーク障害により特定のサーバへ数日間接続できない、という経験はないだろうか。この場合、IPルーティングによるサーバへの到達性はあるので、ただ単にDNSによる名前解決ができないだけなのだが、WebなどはURLを打ち込んでもページが表示されないために困ってしまう。
それ以外では、新規のドメインやサーバを構築した場合にも、同様の現象に見舞われることがある。なぜ、数日もDNSへ内容が反映されないような状況が起こり得るのだろうか。

まず第1に、プライマリDNSからセカンダリDNSへのゾーン転送に時間がかかっている場合が考えられる。
通常、セカンダリDNSは定期的にゾーンが更新されているかどうか確認するので、少なくとも瞬時に反映できるとは限らない。しかし多くの場合はたかだか数時間おきにゾーン情報の更新が行われ、更新はその組織内の作業で済むために可能性があるが、たいていの場合は問題にならないタイムラグだ。またプライマリDNSさえ正常に稼働していれば、可能性はより低くなる。

実際にタイムラグとなり得るのは、キャッシュ・サーバが保持するキャッシュ情報の問題だ。すべてのDNSキャッシュは必ずTTLを保持し、定期的に最新キャッシュに更新される。しかしこの間隔は、多くの場合1日〜数日に設定されており、この間は古い情報しかクライアントは参照できない。プライマリDNSやセカンダリDNSは、世界中のキャッシュ・サーバからの要求に応じてゾーン情報を配布しているので行き渡った情報が最新のものに差し替わるまでにそれだけの時間が必要になるのだ。