t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Raspberry PiにBIND9を入れて自宅ローカルDNSサーバーの構築テスト

今回はネットワーク関連のトピックでDNS(ドメイン・ネーム・システム)の話である。

DNSについて

DNSは名前を送るとIPアドレスを教えてくれるシステムで、普段は意識しないけどネットを使っている人であれば100%お世話になっている。
例えば我々がgoogle.comという名前でGoogleにアクセスできるのはDNS(ドメイン・ネーム・システム)が裏で仕事をしているおかげである。

例えばコマンドでDNSシステムにgoogle.comのIPアドレスを聞いてみる。
f:id:t-hom:20220228112940p:plain

そうすると、アドレスとして172.217.25.174が返ってきた。

これをブラウザに貼り付けると。。
f:id:t-hom:20220228113140p:plain

Googleが開く。
f:id:t-hom:20220228113730p:plain

DNSを自宅で構築する意味

何も意識しなくても使っているDNSをわざわざ自分で構築する理由としては、自宅の端末同士も名前で識別したいから。
一般ユーザーは基本的に端末から公開サービス(Webサイト・メールサーバー・クラウドストレージ・Webアプリなど)へのアクセスがメインなので、端末と端末をネットワーク越しに繋ぎたいなんてことは思わないかもしれない。

ただ、自宅でサーバー運用等を始めるとどうしてもIPアドレスを使用した通信が面倒くさくなってくる。
NTTのホームゲートウェイを覗いてみたところ、今まさに接続されている機器だけでも8台ある。
f:id:t-hom:20220228114854p:plain

ざっと思い出してみよう。。
パソコン・スマホ・スマートウォッチ・ラズパイ3B+・ラズパイZero・ラズパイ4・M5Stack。。。
あれ、あと一人だれ???


あ、Google Homeか。


てな具合である。

hostsファイルじゃダメなの?

少しパソコンに詳しい方ならhostsファイルに名前とアドレスを書いておけばローカルで名前解決ができることをご存じかと思う。
確かにPCから端末への通信ならhostsでも良いんだけど、開発環境などを含めるとネットワークに繋がるマシンは30台ほどになり、PC以外にもラズパイからラズパイに繋いだりする為、マシンのhostsを最新に保つのも管理が面倒くさい。
hostsだと、ちょっとIPアドレスの割り当て設計を変えたくなったら全端末のhostsを更新する羽目になる。

それに自分でDNSを組んだほうがネットワークの勉強になる。いつか仕事で役に立つかもしれない。

え?役に立たなかったら無駄だって?

まぁうだうだとhostsを使わない言い訳を書いたけど、一番の理由はオレオレDNSが欲しい!!というただのロマン案件だったりする。

よってどう転んでもDNSサーバーは必要という結論になる。異論は認めない。
つまるところ、これは道楽なんだ。

構築 (テスト)

そもそもまだ作ってみただけでセキュリティも何も考慮してないし、本運用には課題があることが分かったのであくまでテスト扱い。

主に参考にしたのがこちらの記事。
kykyblog.air-nifty.com

DNSサーバーインストール

Raspberry PiへのDNSサーバーインストールは次のコマンド一発。

sudo apt -y install bind9

※現時点で最新のラズパイOS(bullseye)を使ってるので皆さんの環境でどうかは分からない。

DNSサーバー設定

ファイル /etc/bind/named.conf.local の書き換え

私の設定は次のとおり。追記ではなくてまるっと書き替えた。

zone "local.thom.jp" IN {
	type master;
	file "local.thom.jp.zone";
	allow-update {
		192.168.1.0/24;
	};
};

皆さんが設定するときに最低限可変の箇所は、local.thom.jpという文字列2箇所と、192.168.1.0/24の部分。
local.thom.jpのところは参考サイトだとAAAA.comとなってたのでまぁ別になんでも動くんだけど、たとえばgoogle.comとかにしてしまうと本当のgoogle.comにはつながらなくなってしまう。

私のように内部LAN専用のDNSだと、他と被らない名前が良いかと思った。
たまたま私はWebサイトの運用でthom.jpというドメインを持っているので、これなら他人と被ることはない。
これでいいやと「thom.jp」を使ったら、LANからインターネットにある自分のサイトにアクセスできなくなった。。www.thom.jpは外のレンタルサーバーなので当たり前か。。

ということでlocal.thom.jpという使っていないサブドメインを勝手に名乗って使うことにした。

192.168.1.0/24は自宅のLANがどう区切られてるのかによる。
フレッツ光隼の契約で特に何もネットワークいじってなかったら同じ設定だと思う。
ただDNSサーバー立てようって人なら説明しなくても分かるはず。

ファイル /etc/bind/named.conf.options の書き換え

ここでの最低限の可変項目は2箇所ある192.168.1.0/24と、forwardersのアドレス。

options {
	directory "/var/cache/bind";
	listen-on port 53 { localhost; 192.168.1.0/24; };
	allow-query { localhost; 192.168.1.0/24; };
	forwarders { 2001:4860:4860::8888; 2001:4860:4860::8844; };
	recursion yes;

	dnssec-validation auto;
	listen-on-v6 { any; };
};

192~の変更の要否は前述のとおり。
forwardersに書いてる2001なんちゃらというのはGoogleが提供するDNSサーバーのipv6アドレスで、local.thom.jp以外のアドレスはGoogle様に聞いてね!という転送設定なので、これが無いと外のサービスにアクセスできなくなる。別にGoogleのじゃなくてもISPが提供するDNSでも良い。公開DNSなら何でも良いかと思う。

ただ確かプロバイダとIPv6契約してないとIPv6での通信はできないと思うので、その場合は以下のようにするか、ISPが提供するDHCPアドレスで良いと思う。。どちらもgoogleの提供する公開DNS。

	forwarders { 8.8.8.8; 8.8.4.4; };
ファイル /var/cache/bind/local.thom.jp.zone の新規作成

このファイルは参考サイトを真似たのだが、/var/cacheという置き場所が少し怪しいなぁと思っている。
まだちゃんと勉強してないので間違ってるか合ってるかは断言できないけど、キャッシュという名称から何かのタイミングでクリアされるんじゃないかという懸念がある。本運用する場合はもう少しちゃんと調べたい。

内容は以下のとおり。正直まだ全然分からん。。

$TTL 86400

@ IN SOA ns.local.thom.jp. root.local.thom.jp. (
	2018050600
	3600
	900
	604800
	86400
)
@	IN	NS	ns.local.thom.jp.
@	IN	A	127.0.0.1
@	IN	AAAA	::1
ns	IN	A	192.168.1.102
rpi4	IN	A	192.168.1.102
rpi3	IN	A	192.168.1.101
prod	IN	CNAME	rpi3

可変箇所は3か所のlocal.thom.jpと、最後の4行。
このファイルのlocal.thom.jpはjpの後にドットが付いてて、これは要るらしい。理由はこれから学ぶつもりなので知らないけど。。

2018050600とそれに続く整数群の意味は分からない。タイムアウト秒数とかが含まれているようなので、アドレス系ではなくて何かしら設定なんだろうと思う。

最後の4行のうち1行目はnsという行のIPをDNSサーバーのIPアドレスに設定するようで、このnsというのは参考サイトのとおり必要っぽいので残している。ネームシステムの略かな。。他のレコードと同列なのか、nsだけは特別で必須なのかも不明。
不明だらけで申し訳ないけど、今回はとりあえず動作した設定を紹介するという趣旨なのでご容赦いただきたい。
rpi4とrpi3はラズパイにつけた名前とIPアドレスの対応付け。

DNSサーバーは実際にこのIPを返してくれる。

最後のCNAME は別名(エイリアス)とのことで、prodという名前でもrpi3(つまり192.168.1.101)にアクセスできる。

DNSサーバーを再起動して設定を読み込む

次のコマンドでbind9を再起動すると設定内容が読み込まれる。

sudo systemctl restart bind9

以上でとりあえずDNSサーバー側は準備ができた。

自宅DNSの目下の課題

さて、割と冒頭のほうで「本運用には課題がある」と書いたけどまさに今から書くとろこが課題。
今のところ、結局クライアント側でDNSサーバーを指定しないといけないのだ。。

もともとルーターにはDHCPという機能が備わっているので、LANケーブルをつないだり無線接続をするだけで機器にIPアドレスを自動的に割り当ててくれる。
NTTのホームゲートウェイにもDHCP機能があるのだが、このDHCPはクライアントが参照すべきDNSサーバーのアドレスも一緒に配布するようになっていて、このおかげで特に難しいことを考えなくてもgoogle.comへアクセスすればGoogleが見られるという仕組みである。

つまり、クライアント側で明示的にDNSサーバーを指定しない場合はDHCPサーバーが勝手にプロバイダーが指定するDNSサーバーを見に行くようにされてしまうので、宅内にDNSを立てても使われないということ。

これを解消するにはホームゲートウェイのDHCP機能を無効にしつつ、別途DHCPサーバーを立てるかDHCP機能を持った別のルーターを使う必要がある。

今は手元に機材が無いのでとりあえず適当なLinuxクライアントの参照先DNSを変更してテストしようと思う。

DNSを使うクライアント側でテスト

ファイル /etc/resolv.confの書き換え

今回のファイル編集はクライアント側なのでDNSサーバー上の作業と間違えないように注意。
開くと#で書かれたコメントが大量に出てきたあと既存のnameserver設定があるので#でコメントアウトし、次のようにDNSサーバー側で指定したドメインとDNSサーバーのIPアドレスを記入する。

~前略
#nameserver 127.0.0.53
#options edns0
#search flets-west.jp

domain local.thom.jp
nameserver 192.168.1.102

ファイルを保存するとすぐ有効になる。
完全に書き換えでも動くけど元に戻すのが大変なのでコメントアウトがおススメ。

pingテスト

まずはlan内。resolv.confでドメインを指定したので何もつけないでrpi4などとした場合は自動的にrpi4.local.thom.jpのことだと判断されてうまくいく。もちろんつけてもうまくいく。

次のpingコマンドはいずれもちゃんと返答を返してくれた。

ping rpi4
ping rpi3
ping ns
ping root
ping rpi4.local.thom.jp
ping rpi3.local.thom.jp
ping ns.local.thom.jp
ping root.local.thom.jp

次に外部。これもうまくいく。local.thom.jpに属してないthom.jpやwww.thom.jpは通常どおり外のサーバーのアドレスを返してくれる。

ping google.com
ping thom.jp
ping www.thom.jp

おわりに

というわけで、とりあえず動くDNSサーバーができた。
実際に運用するにはDHCPを何とかするのと、ちゃんとDNSレコードの意味や設定を学習してマトモなセキュリティを導入することが課題である。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。