Ubuntu 24.4で自宅サーバ(DNS・DHCPサーバ構築編)[5/6]

スマートホーム
スポンサーリンク
このエントリーをはてなブックマークに追加

はじめに

自宅サーバが古くなってきたので、以下のような構成の新しい自宅サーバを構築していきます。

この自宅サーバを構築するために、全6回に分けて記事を掲載予定であり、今回は5回目の記事となります。今回はHomeサーバに家内のDHCPサーバとDNSサーバを構築していきます。

第1回:Ubuntuインストール編
第2回:KVMとCockpitで仮想サーバ構築編
第3回:ApacheとWordpressでWebサーバ構築編
第4回:PostfixとRainloopでメールサーバ構築編
第5回:DNS・DHCPサーバ構築編 ←この記事
第6回:NoderedとMQTTでホームサーバ構築編
番外編:KVM上でのWindows11のインストール編
番外編:KVM上でのUbuntu Serverのインストール編

第5回:DHCP・DNSサーバ構築編

第3回と第4回では、インターネット向けに公開するWeb系やMail系サーバの設定を行いました。第5回では、家内のPC・スマホ・タブレットの利用に欠かせないDHCPやDNSの設定を行なっていきます。なお、IPv4だけでなくIPv6に関しても設定していきます。さらに、端末が追加になった時のDHCPやDNSへの追加は手間がかかる運用作業ですので、これを効率化するためのCockpitの拡張機能を開発していきます。

DHCPサーバの設定

Ubuntsu24.4にはデフォルトではDHCPサーバはインストールされていないので、DHCPサーバをインストールし、設定していきます。

①DHCPサーバのインストール

Ubuntsu24.4に簡単にインストールできるDHCPサーバは「isc-dhcp-server」です。早速「apt-get install」コマンドでインストールしていきます。

②dhcpd.confの修正

DHCPサーバのメインの設定である「dhcpd.conf」の設定を行なっていきます。

まずは、オリジナルのファイルをバックアップしてテキストエディタで開きます。

「dhcpd.conf」の修正内容は以下の通りです。

3行目と5行目の「option domain-name」と「option domain-name-servers」は、ドメイン名とDNSサーバのIPアドレスの設定です。私の場合にはドメインを「home-net」、DNSサーバを「192.168.1.2」に設定しています。また、9行目はSyslogで利用するログファシリティの設定で、ここを「local7」に設定し、Syslog側の設定で「local7」に対応するログファイル名を設定することで、DHCPに関するログを「/var/log/syslog」とは別のファイルに出力する事ができます。DHCPのログは端末が接続される度に大量に出力されるので、別ファイルにすることをお勧めします。

次に「dhcpd.conf」の一番下に、以下のサブレットの設定を追記します。

1行目で192.168.1.0(ネットマスク255.255.255.0)のサブネットに関する設定であることを宣言し、2行目でDHCPが自動的に割り当てるIPアドレスの範囲として192.168.1.200〜192.168.1.250を設定します。なお、後でMACアドレスに紐づく固定IPアドレスの割り当てを設定するので、ここでの設定はMACアドレスが登録されていない端末に自動的に割り当てる範囲となります。3行目は、このDHCPサーバが信頼できるものであることを宣言。5行目と5行目は、上でも設定したDNSサーバとドメイン名の設定、8行目はサブネットマスクの設定。9行目はデフォルトゲートウェイの設定。12行目と13行目は、IPアドレスのデオフォルトと最大のリリースタイムの設定です。また、通常であれば15行目以降に固定IPアドレスの設定を記載しますが、この部分は端末の追加に応じて随時更新する必要があるので、別ファイル「dhcpd.hosts」に定義することにします。このため、15行目では「dhcpd.hosts」ファイルをインクルードすることを記載します。

③dhcpd.hostsの設定

dhcpd.hostsには、端末のMACアドレスに紐づく固定IPアドレスの設定を記載します。ここに家内の端末のMACアドレスを登録しておくことで、端末がネットワークに接続された時に毎回同じIPアドレスがDHCPにより設定されます。これにより、DNSによる名前解決やIPTablesによる端末ごとのネットワーク通信制限などが可能になります。

④DHCPサービスの提供元インタフェースの設定

Homeサーバは、2つのネットワークインタフェースを持つので、何も設定しないとLAN側だけでなくDMZ側にもDHCPサービスを提供してしまいます。これを防止するためにDHCPサービスを提供するネットワークインタフェースの設定を「/etc/default/isc-dhcp-server」に記載します。

「isc-dhcp-server」の修正内容は以下の通りです。

「INTERFACESv4」と「INTERFACESv6」の値にDHCPサービスを提供するネットワークインタフェース名を記載します。ネットワークインタフェース名は「ip a」コマンドで調べられるので、分からない人は「ip a」コマンドでLAN側のネットワークインタフェース名を調べましょう。また、この後IPv6の設定も行うので「INTERFACESv6」もついでに設定しておきます。

⑤ログ出力先の設定

DHCPに関するログの出力先を変更するためにSyslogの設定ファイルである「/etc/rsyslog.d/50-default.conf」を編集します。

「50-default.conf」を以下のように変更します。

まず、9行目の設定によりDHCPサーバが「local7」のログファシリティを用いて記載したログが、Syslogにより「/var/log/dhcpd.log」に記載されるようになります。次に2行目を「*.*;auth,authpriv,local7.none」に変更することで、「auth,authpriv,local7.none」を除く全ログを/var/log/syslogに記入するというが意味になります。これで、DHCP関係のログが「/var/log/syslog」からは除外され「/var/log/dhcpd.log」に記載されるようになります。

⑥Systemdへの登録と起動

最後にDHCPサーバをSystemdへ登録して、DHCPサーバを起動します。

3行目の「systemctl status isc-dhcp-server」コマンドを実行して「Active」欄が「active」になっていれば起動成功です。

⑦テスト

それでは、LANにPCなどの端末を接続してみましょう。上で設定したネットワークのIPアドレスが割り当てられていれば設定成功です‼️

DHCPサーバ(IPv6)の設定

ここからはIPv6のDHCPサーバの設定を行なっていきます。IPv6のIPアドレスの配布の仕組みはIPv4とは大きく異なっており、RA(ルータ)を使ってアドレスの割り当てを行う方法とDHCPサーバを利用する方法があります。

ここではIPv6でも固定のIPアドレスを割り当てたいのと、DNSを利用したいのでDHCPを用いる方法で設定していきます。いくらFWがあるからといって、全機器のIPアドレスをインターネットに晒すのは怖いなとIPv4時代からの慣れが邪魔するので、IPv6についてもプライベートアドレス+NAPTという構成にしています。ただし、IPv6のDHCP仕様にはデフォルトゲートウェイのIPアドレスを配布する仕様がないので、デフォルトゲートウェイはRAから配布する必要があります。この辺り、どうにかしてほしいものだと思います。

なお、IPv6用のDHCPサーバパッケージはIPv4用と同時にインストールされているのでパッケージのインストールは不要です。

①dhcpd6.confの修正

IPv6用のDHCPサーバの設定ファイルである「dhcpd6.conf」の設定を行なっていきます。

「dhcpd6.conf」の修正内容は以下の通りです。

3行目と5行目の「option dhcp6.name-servers」と「option dhcp6.domain-search」は、IPv4の場合と同様にDNSサーバのIPアドレスとドメイン名の設定です。私の場合にはDNSサーバを「fc00:cafe::2」、ドメインを「home-net」に設定しています。7行目は、オリジナルのdhcpd6.confには記載がないのですが「log-facility local7;」を設定し、IPv4と同様に「/var/log/dhcpd.log」にログが出力されるようにします。ちなみに、これを記載しないと「/var/log/syslog」にもIPv6に関するDHCPのログは出力されません💦

次に「dhcpd6.conf」の一番下に、以下のサブレットの設定を追記します。

家内のサブネットは「fc00:cafe::」のアドレス体系を使います。「cafe」にしているのは、なんかオシャレな気がするからです😊そして、3行目の「dhcp6.name-servers」で、DNSサーバのIPアドレスを「fc00:cafe::2」に設定し、4行目の「range6」でDHCPがIPアドレスを割り当てる範囲を「fc00:cafe::100」から「fc00:cafe::200」の間に設定します。IPv6は16進数なので、100や200と書くと10進数で記入するIPv4のアドレス範囲と一致しませんが、分かりやすさを優先しました。そして6行目で固定IPアドレスを割り当てるための別ファイル「dhcpd6.hosts」をインクルードします。

②dhcpd6.hostsの修正

IPv4と同様にMACアドレスに基づき固定IPアドレスを割り当てる「dhcpd6.hosts」を設定していきます。

③Systemdへの登録と起動

最後にSystemdへ登録して、DHCPサーバを起動します。ここで、DHCPサーバのデーモンはIPv4とIPv6で分かれているのでIPv6用の「isc-dhcp-server6」を追加で登録する必要があります。

3行目の「systemctl status isc-dhcp-server6」コマンドを実行して「Active」欄が「active」になっていれば起動成功です。

(参考)「dhcpd6.pid」の書き込みエラー

私の環境では「Can’t create PID file /run/dhcp-server6/dhcpd6.pid」と「dhcpd6.pid」の書き込みに失敗する事象が発生しました。実害はありませんが、気になる方は以下で解決できます。

④テスト

それでは、LANにPCなどの端末を接続してみましょう。ちなみにWindows11でIPv6のIPアドレスを取得しなおす時は「ipconfig /renew6」と最後に「6」をつけないといけないので注意してください。上で設定したIPv6のネットワークのIPアドレスが割り当てられていれば設定成功です‼️

DNSサーバの設定

ここからは家内で利用するDNSサーバの設定を行なっていきます。DHCPと同様にIPv4だけでなくIPv6の両方に対応します。

①DNSサーバのインストール

Ubuntsu24.4に簡単にインストールできるDNSサーバは「bind9」ですので「apt-get install」コマンドでインストールしていきます。

②named.confの修正

まずはbind9のメインの設定ファイルである「named.conf」の設定を行なっていきます。

named.confへの修正は、最終行の追加です。

named.confでは、各種設定を行うファイルをIncludeしているので、家の中のゾーンを設定するためのファイルとして「include “/etc/bind/named.conf.my-zones”;」を追加します。

③named.conf.optionsの修正

次にbind9の基本設定を行う「named.conf.options」を修正していきます。

「named.conf.options」の修正箇所は以下の通りです。

まず、1行目で、今回は家の中のDNSサーバなのでDNS SECは不要なので、無効化します。次に2行目でNXDOMAINに関する権威設定を「No」にします。

4行目で、このDNSサーバがサービスを提供するポート番号を53とIPアドレスを「127.0.0.1; 192.168.1.2;」に設定し、インターネット側からの問い合わせを制限します。同様に5行目は、IPv6に関するサービス提供するポート番号とIPアドレスの制限です。6行目は、このDNSサーバが応答を返す依頼元ホストのネットワークアドレスを制限し、家の中からの応答にのみ答えるように設定します。

7行目は、このDNSサーバが回答を持っていない時に依頼を転送するDNSサーバのIPアドレスを設定しています。ここではIPv4とIPv6共にGoogleのDNSサーバを指定しています。最後の8行目はforwardersに問い合わせても回答が得られないときに反復的な問い合わせをするかどうかの指定で「only」を指定して反復的問い合わせをしないように設定します。

9行目の「allow-transfer」はこのDNSサーバの情報を転送できるセカンダリDNSサーバの設定ですが、今回はセカンダリDNSサーバは用意しないので「none」を指定します。

④named.conf.my-zonesの作成

次にこのDNSサーバで名前解決を行うゾーンの設定を行う「named.conf.my-zones」を作成します。

「named.conf.my-zones」の中には3つのゾーン(実際には4つ)を記載します。

まず、1〜5行目で、家の中のプライベートドメインである「home-net」の正引き(ホスト名からIPアドレスを調べる)の設定を行います。このDNSサーバがマスターサーバであることを示す「type master;」と設定ファイルのパス名、そして他のDNSサーバにゾーン転送を行わないようにするための「allow-transfer { none; };」を設定します。また、7〜11行目は、IPv4用の「192.186.1.0」の逆引き(IPアドレスからホスト名を調べる)の設定となります。

13〜22行目でIPv6用の「fc00:cafe::/64」の設定を行います。まず、13〜17行目と18〜22行目の二つがあるのは、IPv6の仕様が「ip6.int」から「ip6.arpa」に変更されたことを受けた互換性の確保のためです。DNSサーバを利用するホストのOSやバージョンによっては、片方だとうまく引けないことがあるようなので2つを設定しています。次に「0.0.0.0.0.0.0.0.e.f.a.c.0.0.c.f」の部分が、少し厄介です。IPアドレス「fc00:cafe::」の省略されている「0(ゼロ)」を全て展開し、ネットワーク部分の64ビット部分を切り取り、通常16ビットごとに区切る「:(コロン)」の代わりに1ビットづつ「.(ドット)」で区切り、さらにそれを左右逆転させます。つまり以下となります。

1.省略されている0を全て展開
 →fc00:cafe:0000:0000:0000:0000:0000:0000
2.ネットワーク部分の先頭64ビットを切り取る
 →fc00:cafe:0000:0000
3.コロン区切りをドット区切りへ
 →f.c.0.0.c.a.f.e.0.0.0.0.0.0.0.0
4.左右を入れ替える
 →0.0.0.0.0.0.0.0.e.f.a.c.0.0.c.f

⑤正引き用ゾーンファイルの作成

「named.conf.my-zones」で指定したゾーンファイルのうち正引き用の「db.home-net」を作成します。

ゾーンファイルの書き方は、多くの情報がネットにあるので詳しく書きませんが、10行目と12行目のIPv6アドレスの部分だけ触れてたいと思います。正引きのゾーンファイルでは、IPv4とIPv6のアドレスを一つのファイルに書く事ができ、IPv4のホストはAレコードで、IPv6のホストはAAAAレコードで記載します。

⑥逆引き用ゾーンファイル(IPv4)の作成

次に「named.conf.my-zones」で指定したゾーンファイルのうちIPv4用の逆き用の「db.192.168.1」を作成します。

このファイルはIPv4用の設定なので、特筆すべきことはありません。他のネットの情報を参考にしながら設定してください。

⑦逆引き用ゾーンファイル(IPv6)の作成

最後に「named.conf.my-zones」で指定したゾーンファイルのうちIPv6用の逆き用の「db.fc00:cafe」を作成します。

ここでもホスト部分のIPアドレスは、左右を逆にして設定する必要があることが必要です。

⑧namedの起動

上記の設定ファイルを作成し終えたら、DNSサーバであるnamedを起動させます。

⑨テスト

それでは、DNSで名前解決ができるかテストしてみましょう。テストにはnslookupコマンドを利用します。

まず、1行目でnslookupコマンドを引数なしで実行し対話モードに入ります。次に2行目で「server 127.0.0.1」と入力し、問い合わせ先DNSサーバを自ホスト(ホームサーバ)に設定します。5行目で「router.home-net」と入力し、正引きのテストを行います。この例では10行目と12行目でIPv4とIPv6のIPアドレスが引けていることが分かります。次に13行目で「192.168.1.1」と入力し、IPv4アドレスの逆引きのテストを行います。この例では14行目で「router.home-net」が引けていることがわかります。さらに15行目で「fc00:cafe::1」と入力し、IPv6アドレスの逆引きのテストを行います。この例では16行目で「router.home-net」が引けていることがわかります。

Cockpit拡張機能の構築

ここまででDHCPサーバとDNSさーばの設定は完了ですが、新規に機器が増えた際には「dhcpd.hosts」「dhcpd6.hosts」「db.home-net」「db.192.168.1」「db.fc00:cafe」の5つのファイルにホスト名・MACアドレス・IPアドレスをそれぞれ追記する必要があり運用が大変です。このためCockpitを用いて家内の機器の登録・変更・削除ができるようにしていきます。

同じような悩みを持っている人も多いのでは?とCokpitのアドオンを探したのですが、DNSやDHCPに関するアドオンはなかったのでオリジナルで構築することにしました。今回構築した仕組みは以下の通りです。
 ①Cokcpitの画面から新しい機器のMACアドレス、ホスト名、IPアドレスを入力
 ②Cockpitからサーバ上の機器一覧情報を記載した「hostlist.txt」ファイルを更新する
 ③Cockpitからサーバ上のdhcp_dns.shを実行する
 ④dhcp_dns.shでhostlist.txtを読み込みDHCPやDNSに必要な5つのファイルを作成する

構築するCockpitの入力画面は以下の通りです。

なおCockpitアドオンの使い方についても日本語の情報はほとんどない状態なので、別途記事にしたいと考えています。

①Cockpitのインストール

まずはCockpitをインストールが必要です。Cockpitのインストールは何度もやっているのでもう日常作業化しています。

②Systemdへの登録

CockpitをインストールしたらSystemdに登録して起動します。

③Cockpitの起動確認

Webブラウザで「http://<IPアドレス>:9090」にアクセスしてCockpitの画面が表示されるか確認します。

④Cockpitアドオンフォルダの作成

Cockpitのアドオンは「/usr/share/cockpit/」にフォルダを作成することで作れます。今回は「DHCPandDNS」というフォルダを作成します。

⑤manifest.jsonの作成

Cockpitにアドオンとして認識させるために、以下の「manifest.json」を作成します。

「manifest.json」の内容は以下の通りです。

内容は非常にシンプルですね。labelの部分でCockpitの画面に表示するメニュー名を、pathの部分で画面表示するためのhtmlファイル名を指定しています。

⑥dhcp_dns.htmlの作成

次にCockpitの画面に表示するための「dhcp_dns.html」を作成していきます。

内容は、他画面に合わせるCSS設定が面倒ですが基本的にはHTMLなので特筆すべきところはないと思います。あえて上げるなら8行目で「cockpit.js」を122行目で後述の「dhcp_dns.js」のJavaScriptを読み込んでいるところぐらいでしょうか。

⑦dhcp_dns.cssの作成

この画面のCSSは基本的にはNetworkManagerのCSSを利用していますが、一部オリジナルのCSSを利用するために「dhcp_dns.css」を作成します。

⑧dhcp_dns.jsの作成

Cockpitを用いたDHCP&DNS登録機能の肝である「dhcp_dns.js」を作成していきます。

1〜7行目はサーバ上のファイルパスの記載であり、8〜24行目は上で作成したHTML上の各要素の取得部分です。26〜31行目で、グローバル変数を宣言します。ここのisDebugをtrueにすると、各種ログを出力するようにできます。

次に33〜70行目は、サーバ上の「hostlist.txt」の読み込み処理となります。38行目で「cockpit.file()」のメソッドを用いることでCockpitの機能を用いてサーバ上のファイルを読み込むことができます。読み込んだCSV形式のファイルは、63〜66行目でカンマ区切りで処理され、hostsArray配列に読み込まれます。

次の72〜100行目は、hostsArray配列の内容をHTMLに出力する処理となります。103〜113行目は、画面上の「編集」ボタンが押された時の処理であり、画面の一番上の登録・編集欄に対象ホストのIPアドレスやMACアドレスなどを転記します。115〜127行目は、「削除」ボタンが押された時の処理であり、確認ダイアログを出した後に、hostsArray配列から対象の一行を削除し、後述する「upload_hostlist()」を呼び出してサーバ上の「hostlist.txt」を更新します。

次の130〜191行目は、画面上の「登録・更新」ボタンが押された時の処理であり、未入力チェック、正規表現によるIPアドレスやMACアドレスのチェック、重複確認チェックを行った上でhostsArray配列を更新します。また、174〜183行目でIPv4アドレスの第4オクテットの昇順で並べ替えを行なっています。

次の193〜247行目が、サーバ上のファイル処理になります。まず、197〜205行目で、「cockpit.spawn()」メソッドを用いて、サーバ上で「CP」コマンドを実行し「hostliext.txt」のバックアップを作成します。212〜217行目で、hostsAarry配列の内容をCSVファイル形式に変換し、222行目で「cockpit.file()」メソッドを用いて、サーバ上の「hostlist.txt」ファイルを上書きします。そして、ファイル書き込みに成功した場合には、後述の「dhcp_dns.sh」シェルスクリプトをroot権限で実行(「superuser: “try”」を指定)します。

最後に252〜264行目は、サーバ上の「/var/log/dhcp.log」を読み込んで画面に表示する処理となります。上の設定でDHCP用のログを別ファイルに分けておいたのもこの理由です。

以上のように「cockpit.spawn()」メソッドを用いてコマンドを叩けたり、「cockpit.file()」を用いてファイルアクセスが簡単にできるところがCockpitを用いて開発するメリットとなると思います。

⑧dhcp_dns.shの作成

ここからはCockpitから実行され「hostlist.txt」を読み込んで「dhcp.hosts」や「db.home-net」などのファイルを作成するシェルスクリプトである「dhcp_dns.sh」を作成します。

まず、3〜11行目でサーバ上のファイルパスの設定を行い、14〜19行目でファイルのバックアップを作成し、22〜27行目でDHCP系の2ファイルは初期化、DNS系の3ファイルはテンプレートファイルのコピーを行います。

次の30行目以降の部分でhostlist.txt(第1引数に指定のファイル)の1行づつを読み取って処理を行なっていきます。まず、32〜37行目でカンマで分割し各変数に値を格納します。次に、42行目でIPv4アドレスをドットで区切って、最終オクテット部分(ホスト部)を求めます。

48〜69行目は、IPv6アドレスのホスト部を求める処理ですが、こちらは少々大変です。50〜55行目でコロンを削除(「sed -e “s/://g”」の部分)したIPv6アドレスの一文字づつを「list」配列に読み込みます。次に60〜68行目でlist配列の大きい方から逆順に一文字つづを読み取って「ipa6dder」に追記していきます。この処理により、IPv6アドレスのホスト部分の逆順のドット区切りの文字列が得られます。

ここまできたら71〜100行目で、それぞれの形式に従ってIPアドレスやMACアドレスの情報を各ファイルに書き込んでいきます。最後に109〜122行目で1、DHCP4サーバ、DHCP6サーバ、DNSサーバの再起動を行なって完了です。

⑨テンプレートファイルの作成

ここまで来たらあと一息です。「dhcp_dns.sh」に読み込ませるテンプレートファイルを作成していきます。

ファイルの内容は見ていただくと分かる通り、各ゾーンファイルの冒頭の定義部分となります。同様にして「/etc/bind/db.192.168.1.temp」「db.fc00:cafe.temp」も作成します。

⑩テスト

ここまでファイルを作成したら「http://<IPアドレス>:9090」にアクセスしてCockpitの画面を表示させましょう。すると左側のメニューに「DHCP・DNS投獄」が追加されている事が確認できると思います。ホストの追加や更新削除など、正しく動作するか確認してみましょう。

(参考)ファイル一式のダウンロード

上記の実際のファイルはここに置いておきますので、参考までにダンロードして使ってください。

おわりに

今回は、家内のPC・スマホ・タブレットの利用に欠かせないDHCPやDNSの設定を行いました。さらに、端末が追加になった時の運用作業を効率化するためのCockpitの拡張機能を開発していきました。全ての端末がMACアドレスに基づき固定のIPアドレスとなることから、ファイヤウォールでの帯域制限、ログ監視などが可能になります。

次回は、6回目として「NoderedとMQTTでホームサーバ構築編」を書いていきたいと思います。

第1回:Ubuntuインストール編
第2回:KVMとCockpitで仮想サーバ構築編
第3回:ApacheとWordpressでWebサーバ構築編
第4回:PostfixとRainloopでメールサーバ構築編
第5回:DNS・DHCPサーバ構築編
第6回:NoderedとMQTTでホームサーバ構築編 ←次回
番外編:KVM上でのWindows11のインストール編
番外編:KVM上でのUbuntu Serverのインストール編

関連記事

記事が参考になったら、ブログランキングに協力(クリック)して貰えると嬉しいです。

昼間はIT企業に勤めてますが、プライベートでは「育児×家事×IoT」をテーマに家のスマートホーム化に取り組んでいます。Androidアプリも作っているので使って下さい。質問・コメントは、↓のコメント蘭でもFacebookメッセンジャーでもどちらでも大丈夫です。
E-mail:naka.kazz.d@gmail.com

naka-kazzをフォローする
スマートホーム
スポンサーリンク
naka-kazzをフォローする
スマートホーム×DIY
タイトルとURLをコピーしました