最小限の設定でDNSを使う
最小限の設定で“おうち用(もしくはSOHO用)”DNSサーバを立ててみた。
DNSサーバはPCが数台のネットワークでは余り使う機会はないと思う。それ程必要性が無いのに加えて設定がややこしい。しかし、仮想マシン環境を使い始めたため、実マシン、仮想マシンを合わせると、おうちの中にPCが10台近く存在することになった。(例えば、“Private Access Serverを作る”の様に幾つかの仮想マシンをサーバとして使ったりもしている。)
また台数の問題だけでなく、仮想マシン環境だと手軽に暫定的なマシンを作ることができ、他の仮想マシンや実マシンと通信するために、その度にhostsファイル等の設定が必要になってくる。
PCが数台であれば /etc/hsots や C:\WINDOWS\system32\drivers\etc\hosts を書き換えたりコピーしても大した手間ではなかったが、上のような状況になるとhostsの設定が煩雑になってしまう。そこでhostsファイルの一元管理が欲しくなった。LinuxでもWindowsでも使える名前解決となるとDNSしかない。DNSをインターネットへ向けた外向きのサーバとしてではなく、内向き限定のhostsファイルの代わりに使うことにした。
ということで、先ずはDNSの仕組みを知っておく必要があるが、それについては“DNSの仕組みの基本を理解しよう”等を参考にした。DNSは大企業やプロバイダなどでも使う仕組みなので、奥が深く真面目に設定すると結構大変だし、サーバも他の複数のDNSサーバに頻繁に問い合わせが発生するため(大したことはないが)負荷も発生する。しかし、やりたいのは外部に対してDNSの情報を提供することは一切せず、LAN内(おうち内)のマシンからの問い合わせにIPアドレスを教えるだけなので、基本的には数か所の変更と追加で済んでしまう。(このDNSサーバはNAT内にあるので、外部からアクセスされることはないという前提。)
■ どんなサーバにするのか、環境は?
DNSサーバの構成には幾つか種類があるが、今回は、おうち内のPCからの問い合わせに対して答えるだけで、自分の知らないマシン(つまりインターネットの世界のマシン)に関してはプロバイダのDNSサーバにそのまま丸投げする“フォーワーダー”設定すればいい。自分はおうちの中のPCのことだけ面倒を見る。
次に、ネットワークの名前。DNSではホスト名だけではなくドメイン名で問い合わせをするので、ネットワークに名前を付ける必要がある。今回は、192.168.0.0/24に対して“localnet”という名前にした。(“ネットワークの名前を考えてみた”を参照。127.0.0.0/8のネットワークのドメイン名は“loopback.”とした。)もし厳密にhostsやnetworksを記述すると次のようになる。
/etc/hosts:
127.0.0.1 localhost localhost.loopback 192.168.0.1 pc-server pc-server.localnet
/etc/networks:
127.0.0.1 loopback 192.168.0.0 localnet
また、今回はDNSサーバとしてUbuntu Server 8.04 LTSが動いているマシンを使った。(これはVMwareのホストマシンでもある。)
■ 前準備
1.DHCPサーバのドメイン名の情報を変更する
DHCPを使っている場合はDHCPサーバからクライアントに配る情報の内、DNSサーバのIPアドレスをこれから設定するサーバのアドレスになるように、またドメイン名が“localnet”になるように dhcp.conf を設定し直してDHCPサーバを再起動する。(私の場合、ブロードバンドルータがDHCPサーバなので、dhcp.confではなくルータの設定画面から。)なお、DNSサーバとして、プライマリサーバはこれから設定しようとするLAN上のDNSサーバのIPアドレス、セカンダリサーバはプロバイダのDNSサーバのIPアドレスを設定しておくといい。もし、おうちDNSサーバがダウンすると、LAN内の全てのマシンが名前解決が出来なくなってしまう。それではマズイので、おうちDNSサーバがダウンした時はプロバイダのDNSサーバへ直接問い合わせるようにする。そうすればLAN内のマシンに関しては名前解決が出来ないが、インターネット上のマシン(例えば、d.hatena.ne.jp等へは問題なくアクセスできる。
2.bindをインストールする
Ubuntu Serverをインストールするときに“利用するサーバ”にDNSサーバを指定していれば、既にbind9というDNSサーバが入っているはずである。もし未実装の場合は、次のコマンドでbind9をインストールする。
% sudo -s # apt-get install bind9
■ BINDの設定
LinuxのDNSソフトウェアであるbindを設定する。bind9をインストールした状態で/etc/bind/の下には次のようなファイルがある。
# ls /etc/bind db.0 db.255 db.local named.conf named.conf.options zones.rfc1918 db.127 db.empty db.root named.conf.local rndc.key
この内、named.conf.options と named.conf.local にちょっと変更を加え、db.localnet、db.192.168.0というファイルを新たに作るだけ。
3./etc/bind/named.conf.optionsを変更する
named.conf.optionsの中の以下の部分を、
// forwarders {
// 0.0.0.0;
// };次のように修正する。
forwarders {
123.45.67.89;
123.45.67.90;
};ただし、“123.45.67.89”、“123.45.67.90”は自分が使っているプロバイダのDNSサーバのIPアドレスとする。この例ではプライマリ・サーバとセカンダリ・サーバがある場合である。プロバイダからDNSサーバとして1つだけアドレスが通知されていれば、ここに記述するアドレスは1つでも良い。プロバイダからは明示的にDNSサーバのアドレスは配布されず、DHCPでDNSのIPアドレスも配布している場合は、プロバイダに直接接続しているルータの情報からDNSサーバのIPアドレスを確認する。
4./etc/bind/named.conf.localを修正する
named.conf.localはコメント行だけであり、実質、空である。そこで、次の内容を追加する。
zone "localnet" {
type master;
file "/etc/bind/db.localnet";
};
zone "0.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.168.0";
};1つ目のブロックがlocalnetの正引き用ファイル(ホスト名⇒IPアドレス)へのポインタ、2つ目がその逆引き用ファイル(IPアドレス⇒ホスト名)へのポインタである。
5./etc/bind/db.localnetを作る
LANに接続している各マシンのホスト名とIPアドレスの対応表(正引き用)を作る。これが基本的にはhostsファイルと同じ内容となる。ここにLAN(おうちネットワーク)に接続されたマシンの名前とIPアドレスを列挙する。
;
; BIND data file for localnet
;
$TTL 86400
@ IN SOA ns.localnet. root.ns.localnet. (
2009010401 ; Serial
8H ; Refresh 28800
4H ; Retry 14400
3D ; Expire 259200
1D ) ; Negative Cache TTL 86400
IN NS ns.localnet.
IN A 192.168.0.1
ns IN A 192.168.0.1
pc-server CNAME ns.localnet.
localhost IN A 127.0.0.1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
firewall IN A 192.168.2.254
defaultgateway IN A 192.168.0.2
pc11 IN A 192.168.0.11
pc12 IN A 192.168.0.12
pc13 IN A 192.168.0.13
pc14 IN A 192.168.0.14
pc15 IN A 192.168.0.15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VMware NAT network
vmhost IN A 192.168.1.1
vmgateway IN A 192.168.1.2
vpc11 IN A 192.168.1.11最初のブロックはDNSサーバへの設定や定義である。大体この通り入力すれば動くはずである。ただし“pc-server”はDNSサーバのホスト名に変更すること。
2つ目のブロックと3つ目のブロックはLAN内のマシンのホスト名とIPアドレスのデータベースとなる。使う環境にあわせて作る。(上の例では3つ目のブロックはVMwareの仮想環境内にある仮想マシンのIPアドレスである。)
ここでのポイントは192.168.0の“localnet”に属していないマシンのIPアドレスも記述していることである(192.168.2にあるfirewallとか192.168.1のVMwareのNAT環境のマシンとか)。クライアントからDNSサーバに通信したいマシンのIPアドレスを問い合わせる時、ホスト名だけでなく自動的に自分のドメイン名を付けて例えば“firewall.localnet”という形で問い合わせる。DNSサーバでそれらのマシンがlocalnetに存在しているとして処理しIPアドレスを返してやれば良い。従って、おうち内のマシンだけでなく、インターネット上のマシンのIPアドレスも自分独自のニックネームを使って同様にここで定義できる。
同様の理由でlocalhostをここでも定義している。DNSサーバへ“localhost.localnet”というドメイン名で問い合わせが来ても127.0.0.1を返答するようになっている。
6./etc/bind/db.192.168.0を作る
逆引き(IPアドレス⇒ホスト名)のデータを用意する。(逆引きの機能を使わないのであれば特に必要はないと思う。)
;
; BIND data file for localnet
;
$TTL 86400
@ IN SOA ns.localnet. root.ns.localnet. (
2009010401 ; Serial
8H ; Refresh 28800
4H ; Retry 14400
3D ; Expire 259200
1D ) ; Negative Cache TTL 86400
IN NS ns.localnet.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
01 IN PTR pc-server.
02 IN PTR defaultgateway.
11 IN PTR pc11.
12 IN PTR pc12.
13 IN PTR pc13.
14 IN PTR pc14.
15 IN PTR pc15.正引き用ではドメイン外のマシンもあたかもドメイン内にあるとしてIPアドレスを返答したが、逆引きではそれは出来ないので、とりあえずlocalnet(192.168.0)にあるマシンの情報だけ記述しておく。
■ bindの再起動と動作確認
設定が終わったらbindを再起動する。
# /etc/init.d/bind9 restart
次にDNSクライアントソフト(リゾルバ)であるnslookup等で動作確認をするが、その前にDNSクライアントがDHCPクライアントであれば、DHCPサーバからDNSサーバのIPアドレスやドメイン名が正しく伝達されているか確認する。DHCPクライアントでなければ、ネットワークのプロパティ(Windows系)や/etc/resolv.conf等(Linux/UNIX系)の設定が正しいか確認する。
・ DHCPクライアントの場合の確認(Windows系の場合)
C:\Documents and Settings\adsaria>ipconfig /all Windows IP Configuration Host Name . . . . . . . . . . . . : pc11 Primary Dns Suffix . . . . . . . : Node Type . . . . . . . . . . . . : Unknown IP Routing Enabled. . . . . . . . : No WINS Proxy Enabled. . . . . . . . : No DNS Suffix Search List. . . . . . : localnet Ethernet adapter ローカル エリア接続: Connection-specific DNS Suffix . : localnet Description . . . . . . . . . . . : Intel(R) PRO/100 VE Network Connection Physical Address. . . . . . . . . : 01-23-45-67-89-AB Dhcp Enabled. . . . . . . . . . . : Yes Autoconfiguration Enabled . . . . : Yes IP Address. . . . . . . . . . . . : 192.168.0.11 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.0.2 DHCP Server . . . . . . . . . . . : 192.168.0.2 DNS Servers . . . . . . . . . . . : 192.168.0.1 123.45.67.89 Lease Obtained. . . . . . . . . . : 2009年1月29日 22:56:30 Lease Expires . . . . . . . . . . : 2009年1月30日 10:56:30
# cat /etc/resolv.conf domain localnet nameserver 192.168.0.1 nameserver 123.45.67.89
IP関連の設定を確認できたら、nslookupで名前解決が出来るか試してみる。(nslookupはWindowsでもLinuxでも使える。)
# nslookup > pc-server Server: 192.168.0.1 Address: 192.168.0.1#53 pc-server.localnet canonical name = ns.localnet. Name: ns.localnet Address: 192.168.0.1 > > > pc11 Server: 192.168.0.1 Address: 192.168.0.1#53 Name: pc11.localnet Address: 192.168.0.1 > > > localhost Server: 192.168.0.1 Address: 192.168.0.1#53 Name: localhost.localnet Address: 127.0.0.1 > > > firewall Server: 192.168.0.1 Address: 192.168.0.1#53 Name: firewall.localnet Address: 192.168.2.254 > > www.hatena.ne.jp Server: 192.168.0.1 Address: 192.168.0.1#53 Non-authoritative answer: Name: www.hatena.ne.jp Address: 59.106.108.86 >
問題がなければ、おうちDNSサーバの出来上がり。後はマシンの追加・削除の時にdb.localnetとdb.192.168.0を変更しbind9を再起動すれ、全てのマシンで最新のデータが使える。
■ loopbackゾーンの設定
以上の設定だけで通常は問題なく使えるはずだ。しかし、更に完璧な設定にするのであればloopbackドメインの設定をしておく。
今回、127.0.0.0/8のアドレスには“loopback”という名前をつけた。従って127.0.0.1のマシンの正式名はlocalhost.loopbackとなる。DNSクライアントへ単に“localhost”と指定するとDNSサーバへは“localhost.localnet”として問い合わせをすることになる。しかし、ソフトウェアによっては“localhost.loopback”という正式名で問い合わせるものもあるかも知れない。その時に上記の設定だけで不十分となる。
# nslookup > localhost.loopback Server: 192.168.0.1 Address: 192.168.0.1#53 ** server can't find localhost.loopback: NXDOMAIN >
そこで次の4行をnamed.conf.localに追加し、
zone "loopback" {
type master;
file "/etc/bind/db.loopback";
};
次の内容のdb.loopbackというファイルを作成する。
; ; BIND data file for local loopback interface ; $TTL 604800 @ IN SOA loopback. root.loopback. ( 2 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS loopback. @ IN A 127.0.0.1 @ IN AAAA ::1 localhost IN A 127.0.0.1
これでbind9を再起動してnslookupで確認すると、今度はlocahost.loopbackでも名前解決できることが確認される。
# nslookup > localhost.loopback Server: 192.168.0.1 Address: 192.168.0.1#53 Name: localhost.loopback Address: 127.0.0.1 >
■ セキュリティに関して
今回のDNSサーバはNAT内で外部のネットワークからはアクセスされないという仮定でセキュリティに関しての設定は省いている。しかしDNSはセキュリティ上、もっとも脆弱な部分でもあるので、セキュリティを確保する設定も追加すべきであろう。
named.conf.optionsに次のようなオプションを追加する。
options {
:
:
:
allow-query {
127.0.0.0/8;
192.168.0.0/24;
192.168.1.0/24;
};
};allow-queryはこのDNSサーバに対する問合せをDNSサーバ自身とLAN内のマシンからに限定する。
更にnamed.conf.localに次のような追加するなど。(本来はnamed.confに設定すべきだが、修正点をnamed.conf.localに集約した方が管理がやり易いと思う。)
include "/etc/bind/rndc.key";
controls {
inet 127.0.0.1
allow { 127.0.0.1; }
keys { rndc-key; };
};rndcというネットワークを経由してDNSサーバを制御するソフトがあるが、上記のcontrolsの例はリモートではなく自身のマシンからしか操作できないようにしている。
また、今回はプロバイダのDNSへforwardする設定になっているが、信頼できるプロバイダのDNSサーバ(というか信頼できるプロバイダ)を使おう。プロバイダのDNSサーバの管理がズサンだと“DNSキャッシュ・ポイゾニング”で偽サイトへ誘導されてしまう。
■ hostsファイルを削る!
セキュリティに関連して、また運用管理上のトラブルを避けるためにhostsファイル(Linux/UNIX系であれば /etc/hosts、Windows系であれば C:\WINDOWS\system32\drivers\etc\hosts の内容を必要最小限にする。特にDHCPクライアントでは例えば次の様に。
127.0.0.1 localhost ::1 ip6-localhost ip6-loopback
(IPv6を使わないのであれば3行目は必要ない。)
DNSを使えるようにしてもhostsファイルがあるとそちらを優先して使うため。hostsの内容とDNSの情報が同じであれば良いが、違うと、幾らDNSを直しても古いhostsの内容を使ってしまう。
■ 参考リンク
named.conf の設定 : bindの設定ファイルで使う項目が良くまとめられている。