Raspberry PI シリーズで分散環境構築(その3: dnsmasq のインストールと設定)

# 序
1. [Raspberry PI シリーズで分散環境構築(その1:モデル別、ディスクレスクライアント化の可否まとめ)](https://qiita.com/p_cub/items/e81dd0f49b3f6fb024a5)
2. [Raspberry PI シリーズで分散環境構築(その2: PiServer の解析と代替システムの設計まで)](https://qiita.com/p_cub/items/69fa32a9a62890ca1d04)
3. [Raspberry PI シリーズで分散環境構築(その3: dnsmasq のインストールと設定)](https://qiita.com/p_cub/items/e7c889b0f92a868a6c20)
4. [Raspberry PI シリーズで分散環境構築(その4: NFSサーバの構築とクライアント用OSのインポート)](https://qiita.com/p_cub/items/dd682de7de28276129e6)
5. [Raspberry PI シリーズで分散環境構築(その5: クラスタノード向け Raspberry PI OS のカスタマイズ(1))](https://qiita.com/p_cub/items/ecf4c48b7ecb08d971b1)
6. [Raspberry PI シリーズで分散環境構築(その6: クラスタノード向け Raspberry PI OS のカスタマイズ(2))](https://qiita.com/p_cub/items/73dc833302c3f064dc39)
7. [Raspberry PI シリーズで分散環境構築(その7: 各ラズパイ向けの tftp ルート設定と起動試験)](https://qiita.com/p_cub/items/ecef742e86ab2991c1b0)
8. [Raspberry PI シリーズで分散環境構築(その8: Webクラスタ構築のケース(前半))](https://qiita.com/p_cub/items/10751e2daa2d3b74c5d5)
9. [Raspberry PI シリーズで分散環境構築(その9: Webクラスタ構築のケース(後半))](https://qiita.com/p_cub/items/c4c837a57e6487a076d4)

本稿は[その2](https://qiita.com/p_cub/items/69fa32a9a62890ca1d04)からの続きです。
今回は PiServer 代替システムを構築するに当たり、キモとなる dnsmasq による PXE サーバ構築の部分となります。

# 1. まずは UNIX 系OSをインストールした余剰マシンの用意
勝手な推測となりますが、ラズパイを何枚ももっているような人であれば、自由に使うことが可能な余剰マシンも自宅なり職場/大学なりのどこかに転がっていることと思います。そして、余剰マシンに使い慣れた UNIX 系 OS をインストールすることはお手の物だと思いますので、OS 自体のインストールに関するハウツーは一切記述しません。

## OSインストール時の注意点
+ ラズパイが出す DHCP のブロードキャストを受け取ることができませんので、PC 上の(ブリッジ接続ではなくNAT接続の)仮想マシン/コンテナや Windows 上で Ubuntu などを動かす WSL 機能を使うことは駄目です。[^20200608加筆]
+ tftpサーバにもなるので固定IPにしてください
+ ファイアウォール設定は突き詰め始めると大変なことになりますので、無効化するのが一番手っ取り早い方法で、設定するとしても、サブネット内全許可、icmp,bootps(67/udp),bootpc(68/udp) は全許可、程度にとどめておいたほうが無難です。[^20200608加筆2]
+ dnsmasq が真っ先に参照しますので、/etc/hosts ファイルに自身のホスト名を記載してください。ただし、hosts ファイル内でマシン名を localhost のエイリアスに紐づけてはいけません

以後、PXE サーバのホスト名を"hogeHost", IP は 192.168.172.16/24 であるとして説明することにします。


```
# /etc/hosts(例)
# PXE サーバの固定IPを 192.168.172.16
# ホスト名を hogeHost にする場合

127.0.0.1 localhost
192.168.172.16 hogeHost
```

[^20200608加筆]: @kakinaguru_zo さんからのコメントを受けて加筆(2020/06/08)
[^20200608加筆2]: 2020/06/08加筆


# 2. dnsmasq パッケージのインストール
各ディストリビューションでパッケージのインストール方法は異なりますが、パッケージシステムを採用している UNIX系OSであれば、絶対に公式リポジトリ上でバイナリパッケージを配布しているはずですから、自分でコンパイルする必要はありません[^GENTOO]。
各ディストリビューションでパッケージをインストールする方法も割愛します。apt-get なり pacman なり dnf なり、普段自分が使っているコマンドを使って dnsmasq をインストールしてください。コマンドを忘れた方は下記リンクを参考に。
参考: [ArchLinux Pacman比較表](https://wiki.archlinux.jp/index.php/Pacman_%E6%AF%94%E8%BC%83%E8%A1%A8)

[^GENTOO]: どんなソフトも自分でコンパイルする必要がある Gentoo を除く(苦笑)

# 3. dnsmasq の設定
通常は /etc/dnsmasq.conf ファイルに全ての設定を書き込んで構わないので、私は dnsmasq.conf ファイルに全て書き込むスタイルを取ります。
ディストリビューションによっては /etc/dnsmasq.conf の他に、/etc/dnsmasq.d/ サブディレクトリがあって、このディレクトリ配下のファイルを全てインクルードする、という環境もありますので、この場合は皆さんのお好みで設定ファイルを分割保存してください。[^DIV_EX]

なお、本稿で記載している dnsmasq.conf ファイルは、PiServer が吐き出したものを改造したものとなっています。

[^DIV_EX]: 例: DNS,DHCP,tftp の機能別にファイルを分割しておく、ラズパイの MAC アドレスごとに分割しておく、等

## 3.1. DNS 機能の設定(無効化)
サンプル(デフォルト)の dnsmasq.conf ファイルでは、5353 番ポートで DNS サービスを開くための行が記載された上でコメントアウトされています。ですが、この状態で dnsmasq を実行してしまうと、通常の DNS サービスで用いられる 53番ポートを勝手に開いてしまいますので、意図的にポートを開かないようにします。コメント行はそのままに、port=0 行を追加してください

``` /etc/dnsmasq.conf(一部)
・・・
#port=5353
# DNS の無効化(行追加)
port=0

# 以下の行は port=0 が指定されていれば、本来は必要ない行ですが、
# 設定を誤って DNS サービスが起動してしまったときのために、
# DNS はローカルサービスであると指定しておく
local-service

# DHCP関連の項目を設定する際にtag名として
# 自身のホスト名を利用することになるので、予め自身のホスト名/アドレスを登録しておく
# [書式] host-record=ホスト名,ホストIP
host-record=hogeHost,192.168.172.16
・・・
```

## 3.2. tftp 機能の設定
デフォルトでは tftp サーバ機能は無効化されていますので、最初に有効化します。
また、MAC アドレスによってクライアントを識別させ、ダウンロード先の tftp ルートを変更する機能を有効化します。

``` /etc/dnsmasq.conf(一部)
# tftp サーバ機能の有効化
enable-tftp

# tftp で提供するファイルの基準ディレクトリの場所(お好みで)
# このディレクトリの下に、MAC/IP アドレスごとの tftproot ディレクトリを作成していくことになる
# (実際にはシンボリックリンクだけど)
tftp-root=/srv/tftp

# MAC アドレスで tftproot ディレクトリを自動的に振り分ける機能の有効化。
# ラズパイが tftp サーバにアクセスする段階では既に IP をもらえているはずなので
# 固定 IP を割り振られる環境であれば IP アドレス毎に tftproot ディレクトリを自動的に振り分けることも可能で、
# その場合は、イコールのあとを "ip" にします。
# 今現在構築している環境は　/etc/hosts で管理するために固定IPにする予定ですが
# PiServer の機能と互換性を保つためにあえて mac にしてます。
tftp-unique-root=mac
```

また、tftp-root 行で指定した、各ラズパイに見せる tftp ルートディレクトリを格納するためのベースディレクトリも作成しておきます。

```
# mkdir /srv/tftp
```

## 3.3. DHCP 機能の設定
デフォルトでは DHCP サーバ機能は無効化されていますので、有効化します。
ただし、これから設定する DHCP 機能は、今お使いの環境(サブネット)内に他のDHCPサーバが存在するか否かで記述方法が変わってきますので注意してください。
ちなみに私の例では既存 DHCP サーバがある方、となっています。

``` /etc/dnsmasq.conf(一部)
# dhcp-range 行がないと DHCP 機能が有効化されないので、自分の環境に合わせてどちらかの行を採用してください

# サブネット内に他の DHCP サーバがない場合
# -------------------
# クライアントに与える IP の範囲やネットマスク等を指定する必要がある
# [書式] dhcp-range=tag:ホスト名,開始IP,終了IP(,ネットマスク(,ブロードキャストアドレス(,リースタイム)))

#dhcp-range=tag:hogeHost,192.168.172.32,192.168.63,255.255.255.0

# また、デフォルトゲートウェイも指定したほうが良い
# [書式] dhcp-option=tag:ホスト名,option:router,ゲートウェイアドレス

#dhcp-option=tag:hogeHost,option:router,192.168.172.254

# サブネット内に IP を与えてくれる他の DHCP サーバがある場合
# ------------------
# DHCP Proxy として機能させる。Proxy の場合、与えられる範囲は 自分自身が持つIPだけなので書式が変わる
# [書式] dhcp-range=tag:ホスト名,ホストIP,proxy
dhcp-range=tag:hogeHost,192.168.172.16,proxy

# クライアント側PXEのバグで起動失敗となることを防ぐために、DHCP の応答を1秒遅らせたほうがいいらしい
dhcp-reply-delay=2

# DHCP に関するログを取る
log-dhcp
```

## 3.4. PXE 機能設定
tftp と dhcp 機能を有効化する人、というのは PXE 機能が欲しい人なわけですから、そんな人向けの専用設定項目が存在します。ラズパイ向けの設定では1行で済む「おまじない」状態ですが、ラズパイ以外の一般的なコンピュータでも PXE 機能を利用したい人はサンプルファイルを元に詳細を調べてみてください。
なお、この1行が存在しない dnsmasq による PXE サーバはラズパイのブートローダ(bootcode.bin)から無視されることになるので、必須項目となっています。

```configuration
# /etc/dnsmasq.conf(一部)
# ラズパイの bootcode.bin に tftp サーバと認識させるために必須の1行
# ("Raspberry Pi Boot" の文字列は改変不可)
# pxe-service=tag:PXEサーバ名,0,"Raspberry Pi Boot"
pxe-service=tag:hogeHost,0,"Raspberry Pi Boot"
```

## 3.5. クライアント毎のDHCP設定と暫定的な tftp ルートディレクトリの作成
ここからはラズパイ1枚に付き1つのエントリを追加してくことになります。所有するラズパイの MAC アドレスを調べ、1行ずつエントリを追加していきます。

``` /etc/dnqmasq.conf(一部,MACアドレスは適当な値)

# 他に DHCP サーバがない場合の設定
# (各MACアドレスに固定IPを割り振る)
# --------------
# [書式] dhcp-host=ラズパイのMACアドレス,set:ホスト名,与えるIPアドレス,infinite
# Raspi2
#dhcp-host=b8:27:eb:GG:HH:II,set:hogeHost,192.168.172.32,infinite
# Raspi3
#dhcp-host=b8:27:eb:XX:YY:ZZ,set:hogeHost,192.168.172.33,infinite
# Raspi4
#dhcp-host=dc:a6:32:PP:QQ:RR,set:hogeHost,192.168.172.34,infinite

# Proxy DHCP 設定の場合の設定
#  -----
# [書式] dhcp-host=ラズパイのMACアドレス,set:ホスト名

# Raspi2
dhcp-host=b8:27:eb:GG:HH:II,set:hogeHost
# Raspi3
dhcp-host=b8:27:eb:XX:YY:ZZ,set:hogeHost
# Raspi4
dhcp-host=dc:a6:32:PP:QQ:RR,set:hogeHost
```

エントリ追加が終了した後、dnsmasq をテスト起動した際にエラーが発生しないよう、tftp 関連の項目を設定した際に指定した基準ディレクトリ下に MACアドレスのコロンをハイフンに変えた名前でサブディレクトリを作成します。(本番ではこれはクライアント向けOSの /boot フォルダへのシンボリックリンクになります)

```
# mkdir /srv/tftp/b8-27-eb-GG-HH-II
# mkdir /srv/tftp/b8-27-eb-XX-YY-ZZ
# mkdir /srv/tftp/dc-a6-32-PP-QQ-RR
```

これで dnsmasq の設定は終了です。

# 4. dnsmasq.conf の文法チェック
完成した dnsmasq.conf の文法チェックを実行します

```
# sudo dnsmasq --test      
dnsmasq: syntax check OK.
#
```
今回はここまでとします。[次回](https://qiita.com/p_cub/items/dd682de7de28276129e6)はNFSサーバの構築とクライアント向けOSの手動インポートとなります。