世界を動かす技術を、日本語で。

自宅での自分専用DNSサーバー – 第1部: IPv4

概要

  • DNS構築 とトラブルの多さに関する有名なミーム「It’s always DNS」の紹介
  • 自宅ネットワーク でのデジタル主権実現を目指し、BINDによるDNSサーバ構築手順を解説
  • 複数ネットワーク (192.168.1.0/24、172.16.0.0/16、10.88.0.0/16)対応の設定例
  • zoneファイルの作成 とBINDの主要設定ポイントの解説
  • 失敗しても影響が小さい 自宅ネットワークでのDNS学習のすすめ

「It’s always DNS」―自宅ネットワークでBINDサーバを構築する

  • DNSトラブル はネットワーク管理者の間でよくある問題として知られるミーム
  • DNS(Domain Name System) はホスト名(例:jan.wildeboer.net)をIPアドレスに変換する仕組み
  • 自宅ネットワークのデジタル主権 を目指し、インターネット接続がなくても動作するDNSサーバ構築に挑戦
  • Raspberry Pi 4 (Fedora 42)をインフラサーバとして利用し、BINDでDNSサービスを提供
  • Fritz Box 7490 をフォワーダーとして、外部解決もカバー

構成ネットワークとホスト

  • 192.168.1.0/24 :自宅IPv4ネットワーク
  • 172.16.0.0/16 :homelabサーバの2ndイーサネット用IPv4ネットワーク
  • 10.88.0.0/16 :Podmanコンテナ用仮想ネットワーク
  • inf01.homelab.jhw (192.168.1.10):Raspberry Pi 4(CAサーバも兼任)
  • hl01/hl02/hl03.homelab.jhw (192.168.1.11-13):ThinkCentre Tiny PC群(RHEL10)
  • Fritz Box 7490 (192.168.1.254):ルーター兼DNSフォワーダー

注意点:TLDの選択

  • .internal TLD の利用が推奨されるが、今回は独自判断で .jhw を使用
  • 将来的に .jhw TLD が公的に利用されるリスクがあるため、推奨はしない

BINDのインストールと基本設定

  • BINDとユーティリティのインストール
    • dnf install bind bind-utils
  • ファイアウォールの設定
    • firewall-cmd --add-service=dns --permanent

BIND主要設定ファイル

  • /etc/named.conf :BINDのメイン設定ファイル
    • どのネットワークでリッスンするか、どのゾーンを管理するかを記述
  • /var/named/forward.homelab.jhw :正引きゾーンファイル(ホスト名→IPアドレス)
  • /var/named/reverse.homelab.jhw :逆引きゾーン(192.168.1.0/24用、IPアドレス→ホスト名)
  • /var/named/reverse2.homelab.jhw :逆引きゾーン(172.16.0.0/16用)

/etc/named.confの主なポイント

  • listen-on port 53 :複数IPでDNSクエリを受け付ける設定
  • allow-query :許可するクライアントネットワークの指定
  • forwarders :外部問い合わせ時の転送先(Fritz Box 7490)
  • recursion yes :再帰問い合わせの許可
  • dnssec-validation no :DNSSECは今回は無効化
  • zone定義 :forwardゾーン(homelab.jhw)、reverseゾーン(1.168.192.in-addr.arpa、16.172.in-addr.arpa)

ゾーンファイルの基本

  • $TTL 3600 :デフォルトTTL(1時間)
  • SOAレコード :ゾーンの権威サーバと管理者メール
  • NSレコード :ネームサーバ指定
  • Aレコード :ホスト名→IPアドレスの正引き
  • CNAMEレコード :別名(例:ca.homelab.jhw→inf01.homelab.jhw)
  • 逆引きゾーン :PTRレコードでIPアドレス→ホスト名を対応付け

運用上の注意

  • ゾーンファイルのシリアル番号 は変更のたびに必ず増やすこと
  • シリアル番号を更新しないとキャッシュや同期の問題発生
  • 新しいホスト追加時はAレコード追加→シリアル更新→systemctl reload named

自宅ネットワークでDNSを学ぶメリット

  • 失敗しても影響範囲が限定的 なため、安心して試行錯誤可能
  • ネットワーク理解の深化 とトラブルシュート力の向上
  • 将来的なネットワーク拡張 や自動化にも応用可能

まとめ

  • BINDによるDNSサーバ構築 は設定ファイルやゾーンファイルの仕組みを理解すれば難しくない
  • 自宅ネットワーク での運用は、DNSのトラブルや挙動を安全に学ぶ最適な場
  • 公式TLDの選択やシリアル番号管理 など、運用上の注意点も押さえる必要あり
  • ネットワーク拡張や自動化 の第一歩として、自前DNS構築は大きな価値

Hackerたちの意見

家でunboundを使って権威あるネームサーバーを設定したんだけど、BINDの設定よりずっと簡単に感じる。でも、まだ完全には理解できてないかな。DNS(ネットワーク全般もだけど)はちょっと難しいよね。

NSDを試してみて。unboundとは違って、NSDはプロジェクトの実際の権威あるネームサーバーだよ。

90年代半ばから家でBINDを使ってる。ISDNの頃からだね。始めたときはO'Reillyの「DNS and BIND」本が頼りだった。

DNS(ネットワーク全般もだけど)はちょっと難しいよね。ダイナミックルーティングは楽しい :)

unboundはあまり間違えようがないし、めちゃくちゃ速くて軽いよ。BINDやPowerDNSで泣く男たちもいるけど、これらのサーバーはおもちゃ箱を丸ごと持ってるからね。BINDのデーモンをたくさん立ち上げたことがあるよ。昔、MySQLのレプリケートバックエンドを持つPDNSサーバーを2台運用してた。今は、インターネットに公開されていてかなり制限されたPDNSをACME DNS-01(Lets Encrypt)用に使ってる。CAコンソーシアムは、SSL証明書の有効期限を3年以内に40日程度に短縮するように求めてる。顧客のためにかなりの数のSSL証明書を管理してるよ。とにかく、ホームラボをやってるなら、Pi Holeを考えてみるのもいいかも(Piで動かす必要はないし、VMでも大丈夫)。もう少しハードコアな選択肢としては、https://technitium.com/dns/(ウェブGUI - やった!)もある。pfSenseにはunboundが組み込まれてるし、OPNSenseもそうだと思う。どちらもルーターとしてはいい選択肢だよ。OpenWRTにもunboundが入ってるはず。unboundはあまり間違えようがないって言ったけど、本当にそう思ってる。動けば、ほぼ確実に正しく設定されてるよ。

同じく、広告ブロックも使ってるよ。

私も家でunboundを使ってる。unboundの大きな利点は、ワイルドカードに対して何でも返せることだと思う。TLDのワイルドカードも含めてね。セイシェルのDNSは完全にハイジャックされてて、マルウェアしか提供してない?.sc全体を無効化しちゃう?いや、うちではそれは解決しないよ。などなど。だからunboundは、古いRaspberry Piでも、何十万行もあるブロックリストを使っても楽に動いてる。

DNSは実際かなり簡単なんだよね。問題は、Bindのゾーンファイルが本当に使いにくいインターフェースで、実際よりも10倍難しく感じさせること。あんまり不満はないけど(だってフリーソフトだし、あまり文句は言えないと思ってるから)、他のDNSソリューションと比べると、簡単さが雲泥の差だよね。例えば、WindowsのDNSサーバーを運用するのは(家でやることではないけど)すごく簡単で、Microsoftがユーザー体験を磨いてるからね。Linuxにももっと洗練された代替があると思うけど、どれがあるかよく知らないから、具体的な例を挙げられないんだ。

自分でdns4jを使ってコードを書いたよ。自分のドメインを提供するだけなら10行のコードで済むんだ。でも、すべてのドメインを提供しようとすると問題が出てくると思う。どのデータベースがベストなんだろう?単にMySQLでintから名前のテーブルを作る感じ?DNSの問題は、ポート53が開いている固定の外部IPが必要なことだよね。安く手に入れるのは簡単じゃない。

家にはOpenBSDのボックスがあって、ネットワークゲートウェイとしてunboundとnsdを動かしてる。unboundがキャッシュと再帰を担当して、nsdがローカルの名前解決をしてるんだ。小さなユーティリティ(2つのシェルスクリプトと1つのPythonスクリプトで構成されてる)を作って、/var/db/dhcpd.leasesの変更を監視して、変更を解析してnsd用のゾーンファイルを生成してる。追記: https://paste.rs/vgr7t.txt

スクリプトのアプローチはいいアイデアだね。私もあなたが言ってるようなOpenBSDのボックスを持ってるけど、ISC dhcpdとBINDを使ってる。これが古いスタイルのダイナミックDNSを実現する唯一の設定なんだ。DHCPサーバーがリースが発生したときにBINDにゾーンの更新を送るから。でも、BINDは嫌いだし、この設定はDHCPv6ともうまくいかない(理由はわからないけど、原則的にはできるはず…)だから、「リースを読み取ってゾーンファイルを生成するスクリプト」のアプローチに切り替えた方がいいかも。

個人的には、BINDは設定が本当にひどいDNSサーバーだと思う。ArchやGentooを設定するようなもので、たくさんの設定があって、システムのあらゆる部分について学べるけど、実際には触れるべきフィールドはほんの数個なんだ。私の選ぶDNSサーバーはPowerDNSだよ。certbotや利用可能なウェブUIとのAPIも使いやすいと思う。

Bindがデプロイされる場合、named.confはたぶんこうなってるべきだったと思う:options { allow-recursion { localhost; localnets; }; forwarders { 1.1.1.1; 8.8.8.8; 4.2.2.2 }; forward only; }; これで、求めてる仕事は同じようにできるはず。これ、すべてのインターフェースにバインドして、サイトの多くの設定行がやってるようにデフォルトパスを明示的に再指定する必要もないし、大多数の人がsyslogに記録したいことをログに残して、プライベートサブネットやローカルマシンからのリクエストを転送するよ。代わりに、ディストリビューションには、特定のカスタマイズが施されたデフォルトファイルが付属してると思うから、これにこの3行を追加するだけで済む。残りの8%の人が「本物」のDNSサーバーを運用する場合、ゾーン定義の構文はちょっと冗長かもしれないけど(特に多くのドメインや逆引きゾーンを扱う場合)、そんなに複雑ではないと思う。最後の2%は、bindのドキュメントが焦点を当ててるような、意味不明に見える構文を気にするかもしれないけど… ただ、bindがゾーンファイルのシリアル番号を手動でインクリメントすることを期待してるのは文句言いたいな… でも、こういうデプロイ(あるいはいくつかのドメインのネームサーバーとして機能するもの)には、実際にはそれが必要ないことが多い。PowerDNSを選ぶことについては文句なし。これに関しては間違えることはないよ。

家でコンテナの中にTechnitium DNSサーバーを立ててる。DoH、DoT、複数の上流リゾルバー(と複数の上流クエリ)、広告ブロックのサポート、他にもいろいろ便利な機能(API)に対応してるよ。内部リゾルバーを自分でホスティングしてるなら、ぜひチェックしてみて。piholeよりこっちの方が好きだな。https://technitium.com/dns/

piholeよりこっちの方が好きだな。なんでそう思うかもっと教えてくれる?

自分のホームラボネットワークには公式の.internal TLD(トップレベルドメイン)を使うべきなんだけど、やめたんだ。将来的に誰かが公開の.jhw TLDを提供するリスクがあるからね。それを受け入れる代わりに、家では3文字のTLDを使うことにした。俺みたいにならないで!代わりに.internalを使って。さて、次に進もう。なんで.lanじゃないの?キーワードは「公式」?

自分が好むのは、公開で解決可能なドメインを登録して、それを内部でだけ使うこと。そうすれば、必要な場合には公開の信頼できるTLS証明書も取得できるし、自分のプライベートCAを使うこともできるけど、少なくとも選択肢があるからね。

重要な概念は、他人の失敗から学ぶことだよ。過去数十年、誰もが使わないと100%確信していた「内部」トップレベルドメイン名を選んでしまった人たちの例がたくさんある… でも、誰かがその考え方の結果として使い始めたこともある。* https://jdebp.uk/FGA/dns-use-domain-names-that-you-own.html * https://news.ycombinator.com/item?id=45144631 dev.のケースは、ここ数年Hacker Newsでたくさん議論されてるよ。

特定のRFCで.lanが予約されているのは見なかったけど、提案された標準RFC 8375ではhome.arpaが推奨されてるね。https://datatracker.ietf.org/doc/html/rfc8375

彼がすでに持っている公開ドメインの下にサブドメインを作ればいいんじゃない?インタラクティブな使用では、正しく設定された検索リストでドメインの一部だけを使うことが多いし。外部にIPv6でホストを簡単に公開できる利点もあるよね。内部接続は特定のホストに直接行き、外部はリバースプロキシ経由で特定のサービスを公開する。全体的に、彼は典型的なシンプルな内部DNSセットアップを説明してるだけだと思った。タイトルからは、どうやって自宅で公開ドメイン用の安定した権威DNSサーバーを立ち上げたのか(「二つのネームサーバー」の要件をどうクリアしたのか)を話すのかと思ってた。プラス面としては、今の自宅の接続が三つの権威DNSサーバーの一つをホストするのに十分安定してることに気づいたから、月に約7ユーロ節約できるかも。

自分でネームサーバーをホスティングしてて、メール通知付きのカスタムダイナミックDNSスクリプトもあるんだ。正直、ドメインレジストラも変えられたらいいのに、公開のTLDを持ちたいな。50百万ドルくらいで、.sh TLDが手に入るかも。

arstechnica.comのリー・ハッチンソンが、少し前にbindをdhcpdと組み合わせて自己ホスト型CAを設定する方法を詳しく説明してたよ。https://arstechnica.com/information-technology/2024/02/doing... でも、私は結局踏み出せなかったな。dnsmasq、adguardhome、そしてLet's Encryptで十分だし。

このHNのコメントのゴールドナゲット[0]には、公開されているルートゾーンデータを使った自己ホスト型DNSの素晴らしいレシピが載ってるよ。著者はランダムなユーザー名だけど、今日はアクティブに投稿してるみたい。もしこれを見たら、1vuio0pswjnm7、情報ありがとう![0] https://news.ycombinator.com/item?id=31385133

ISC DHCPが廃止されたから、dnsmasqに切り替えたんだ。それで、ローカルのdhcpホスト名登録が続けられるように、家のDNSサーバーもunboundからdnsmasqに変更した。dnsmasqはちょっとおもちゃみたいだと思ってたけど、実際には感心してる。今のところ完璧に動いてるし、プロセスを再起動せずに再設定できるのが特にすごい。唯一の不満はdnsmasqに特有のものではなくて、ipv6に関すること。デバイスが基本的にランダムなアドレスを自分で割り当てるから、そのアドレスからのDNSルックアップと実際にリクエストを出しているデバイスを関連付けるのが不可能なんだ。この問題の明らかな解決策である完全管理型のDHCP6設定はdnsmasqではあまりサポートされてないみたいだけど、たとえサポートされてても、DHCP6をサポートしていないデバイスが多いから、結局はslaacだけなんだよね。だから全体的にちょっと混乱してる。

SIGHUPで設定を再読み込みしてくれたらいいのに、そうならないんだよね。https://manned.org/man/dnsmasq#head6

この問題の明らかな解決策である完全管理型のDHCP6設定はdnsmasqではあまりサポートされてないみたいだけど、たとえサポートされてても、DHCP6をサポートしていないデバイスが多いから、結局はslaacだけなんだよね。関連情報: https://issuetracker.google.com/issues/36949085 Android Public Tracker - DHCPv6(RFC 3315)のサポート - ステータス: won't fix

dnsmasqのスケーリング問題がわかったのは、約2万台のブレードサーバーがdhcpでアクセスしてきたときだった。UDPトラフィックが原因で、かなり強力なサーバーでも落ちちゃったよ。Keaに切り替えたら、その問題は解決した。

先月初めて自分でルーターを作って、isc-dhcpdを選んだんだ。ソフトウェアは「完成した」と呼ぶのが正確だと思う。コードベースはかなり成熟してるし、DHCPプロトコルはそんなに変わらないからね。LANのDHCPサーバーとして必要なことは全部できるし、BINDとも簡単に統合できる。基本的なセキュリティアップデート以外はこれを更新する必要がないと思ってるんだけど、切り替える強い理由ってあるのかな?

この明らかな解決策、完全管理されたDHCP6セットアップは、私が使っているdnsmasqではあまりサポートされていないみたい。私はDHCPv6にdnsmasqを使ってるけど、結構うまく動いてるよ。"dig AAAA"でDHCPv6対応デバイスの正しいアドレスが返ってくる。 > でも、たくさんのデバイスがDHCP6をサポートしていないから、たとえそうでも関係ないよね、slaacだけだし。理論的には"--dhcp-range=slaac,ra-names"で動くはずなんだけど、実際には私には何も効果がないみたい。[0]: https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html#:~:t...

djbdnsが好きだったけど、開発が停滞しているみたい。好きだったのは、名前解決(dnscache)と権威DNSサーバー(tinydns)の分離だね。

powerdnsも同じことをしてると思う。三つのデーモンに分かれてるんだ:キャッシュとルーター、権威サーバー、再帰的リゾルバー。

ゾーンファイルに変更を加えるたびにシリアルを増やすのを絶対に忘れないで!さもないとDNS地獄が待ってる。 > すべてのホスト名レコードは.で終わる。これを忘れるよ。これを修正することになる。 > 終わりにドットを付けて。ドットを忘れないで! > 終わりにドットを付けて。シリアルは更新した? :) こういうコメント大好きだわ。今日は最高の日になった! :D