OS自動インストールを行うためのPXEブート環境を作る

# はじめに
最近はクラウド環境が増えてきて、1からOSインストールを実施する機会は減っているかもしれませんが、VirtualBox等でちょっとテストマシンを作ったり、クラウド利用料などのお金の心配せずにマシンを使いたいといった場合にISOファイルやDVDからインストールするような場合も多々あるかと思います。

私はVirtualBoxでテスト用仮想マシンを作ることが多いですが、毎回OSインストール→セットアップするのも面倒なので、あらかじめ`PXEブート`構成を作っておき、`Kickstart`でテストマシンを作成することをよくやっています。

今まではCentOS7系OSでPXEブート環境を作っていましたが、今回CentOS8系OSでブート環境を作ったので内容を残しておこうと思います。

# PXEブートとは
[Wikipedia](https://ja.wikipedia.org/wiki/Preboot_Execution_Environment)より
> *Preboot eXecution Environment（PXE、ピー・エックス・イー、ピクシー）は、コンピュータのブート環境のひとつ。インテルの策定したネットワークブートの規格である。*
> *ネットワークブートを利用することにより、ストレージをもたないクライアントコンピュータや、ストレージに別のOSが導入されているクライアントコンピュータがサーバ上のOSイメージを使用して起動できる。*

PXEブートは基本的に、OSがインストールされていない状態からのブートを前提としているため、ネットワーク経由でブートイメージを取得する必要があります。

そのため、[Wikipedia](https://ja.wikipedia.org/wiki/Preboot_Execution_Environment)にも記載されている通り、ブートイメージを配布するための`TFTPサーバ`とTFTPサーバと通信するためのアドレスを払い出す`DHCPサーバ`が必須となります。

## PXEブートの起動シーケンス
PXEブート時は起動直後のDHCP要求で、IPアドレスとともに**起動用ブートイメージが格納されているTFTPサーバの場所**と**ブートイメージファイル名**を要求します。

DHCPサーバから応答を受け取ると、受け取った情報に従ってTFTPサーバに**ブートイメージ**と**ブート構成ファイル**を要求することで、OSの起動に必要となる**OSイメージファイル**や**OS構成ファイルの場所**を把握し、ブート構成ファイルに記載されている内容に従って、指定されたプロトコルでOSイメージ等をダウンロードします。（下図参照）

![pxeboot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/fa9ce1b9-6c86-03db-3a7b-4c031e72fafa.png)

今回の記事ではPXEの起動で必要となるDHCPサーバ、TFTPサーバの構築まで行います。


# DHCP構成を考える
DHCPサービスはブロードキャストで通知される`DHCPリクエスト`を受け付けるため、基本的に構築するマシンと同一ネットワーク上に設置設置する必要があります。
※途中の機器で`DHCPリレー`の設定が行えるようであれば、別のネットワーク上に設置することもできます。

また、同一ネットワーク上に複数のDHCPサーバが存在した場合の動作は早い者勝ちで意図しない動作となってしまうので、間違ってもVirtualBox等で作成した**DHCPサービスが動いている仮想マシンをブリッジで社内ネットワークに繋ぐことはやめましょう！！**

ただ、テスト環境でPXEブートを行いたいけど、DHCPサーバが簡易的なものでPXEブートの設定ができなかったり、テストのためだけにDHCPサーバを集約したりするのは面倒なので、今回は`Proxy DHCP`機能を使うことで既存のDHCPサーバと同居できる構成とします。

## Proxy DHCPとは
DHCPサーバが複数存在した場合の動作は早い者勝ちで、先に受け取ったDHCPサーバのアドレスを使用しますが、Proxy DHCP機能を使用すると、`PXEブート`する際に使用する`next-server`や`boot-filename`等のパラメータのみ`DHCP Offer`で送信して、それ以外は他DHCPサーバのパラメータを使用することになります。

大雑把に言うと、PXEブート用のパラメータのみ上書きするイメージです。

そのため、他DHCPサーバが動作していても、ネットワークに影響を及ぼすことなく同居することが可能です。
※他DHCPサーバがPXEブート機能も提供している場合はその限りではないのでご注意を。

# 構築環境
今回はVirtualBoxで以下構成の仮想マシンに`PXEブート`環境をセットアップします。

`ネットワーク1`はゲートウェイは設定せずホストオンリーのセグメントのアドレス（192.168.56.105）を固定で適当に割り当てて、`ネットワーク2`はDHCPでアドレスをもらうようにしておきます。

また、`Proxy DHCP`を使用するため、VirtualBoxのDHCP機能は有効のままとしておきます。

|構成|種別|
|:--|:--|
|OS|CentOS 8.2.2004|
|ソフトウェアの選択|最小限のインストール|
|ネットワーク1|ホストオンリーアダプター|
|ネットワーク2|NAT（パッケージインストール用）|

# 構築方法
本構築では以下手順で`PXEサーバ`構築まで進めます。
PXEサーバを使った`Kickstart`などはまた別途。

1. SELinuxの停止
2. パッケージインストール
3. DHCPサービスセットアップ
4. TFTP用設定
5. dnsmasqサービス有効化
6. Apache設定
7. Apacheサービス有効化
8. firewalld許可設定

## SELinuxの停止
作業に都合が悪いので`SELinux`を停止しておきます。

```shell:SELinuxの無効化
sudo setenforce permissive
sudo sed -i -e "/^SELINUX=/s/=.*/=disabled/g" /etc/selinux/config
```

## パッケージインストール
以下パッケージをインストールします。

尚、`dnsmasq`サービスは**DHCP機能**、**Proxy DHCP機能**だけではなく、**TFTP機能**も含まれるため、個別にTFTPサービスをインストールことはせず、今回は`dnsmasq`パッケージのみインストールすることとします。

|インストールパッケージ|用途|
|:--|:--|
|dnsmasq|DHCP、TFTP用|
|syslinux|ブート用ファイル取得用|
|httpd|Kickstart等でのOSイメージ転送等|

```shell:必要パッケージインストール
sudo dnf -y install dnsmasq syslinux httpd
```

## DHCPサービスセットアップ
今回PXEブートで使用するネットワークは`VirtualBox`の`ホストオンリーネットワーク`を使用します。
アドレス等は各環境に合わせて適宜修正して下さい。

```shell:/etc/dnsmasq.d/pxeboot.conf
sudo cat << _EOF_ | sudo tee /etc/dnsmasq.d/pxeboot.conf
# DHCPサービス設定
dhcp-range=192.168.56.0,proxy
log-dhcp
dhcp-boot=pxelinux.0,192.168.56.105
pxe-service=x86PC,"Network Boot",pxelinux,192.168.56.105
# TFTPサービス設定
enable-tftp
tftp-root=/tftpboot
_EOF_

※単純なヒアドキュメントの書き方だと権限がなく書き込めなかったためteeにパイプして書き込み。
```

## TFTP用設定
PXEブート用ファイル格納ディレクトリ作成と必要モジュールをTFTPディレクトリに格納します。

```shell:TFTPディレクトリ作成と必要モジュールの格納
sudo mkdir -p /tftpboot/pxelinux.cfg
sudo cp -p /usr/share/syslinux/{pxelinux.0,ldlinux.c32,libcom32.c32,libutil.c32} /tftpboot/
```

## dnsmasqサービス有効化
DHCP、TFTPの設定ができたら`dnsmasq`サービスを有効化します。

```shell:dnsmasq有効化
sudo systemctl enable --now dnsmasq
```

## Apache設定
PXEブートを使用して、実際に各OSをネットワーク経由でインストールするには`HTTP/HTTPS`や`NFS`等でOSイメージやOS設定ファイルを転送する必要があります。

今回はHTTPでOSイメージを転送することを想定して`Apache`のセットアップを行っておきます。

```shell:PXEブート用ディレクトリ作成
sudo mkdir /pxeboot
```

```shell:/etc/httpd/conf.d/pxeboot.conf
sudo cat << _EOF_ | sudo tee /etc/httpd/conf.d/pxeboot.conf
Alias /pxeboot/ "/pxeboot/"
<Directory "/pxeboot">
Options Indexes MultiViews FollowSymlinks
AllowOverride None
Require all granted
</Directory>
_EOF_
```

## Apacheサービス有効化
`httpd`サービスを有効化します。

```shell:httpd有効化
sudo systemctl enable --now httpd
```

## firewalld許可設定
`firewalld`を有効にしている場合は、以下サービスに対して`fIrewalld`の許可設定も行います。

|許可サービス名|ポート番号|
|:--|:--|
|dhcp|67/udp|
|proxy-dhcp|4011/udp|
|tftp|69/udp|
|http|80/tcp|
|https|443/tcp|

```shell:firewalld許可設定
sudo firewall-cmd --add-service=dhcp --zone=public --permanent
sudo firewall-cmd --add-service=proxy-dhcp --zone=public --permanent
sudo firewall-cmd --add-service=tftp --zone=public --permanent
sudo firewall-cmd --add-service=http --zone=public --permanent
sudo firewall-cmd --add-service=https --zone=public --permanent
```

```shell:firewalld有効化
sudo firewall-cmd --reload
```

# まとめ
ここまでの構築でPXEブートする環境が整いました。
実際にPXEサーバを使用したOSインストールについては次回紹介します。

- 【次】[Ubuntu Server 20.04の自動インストール機能でネットワークインストールする。](https://qiita.com/sakai00kou/items/7ce4a8a410251b98b2ac)
- 【次】[CentOS8をKickstartでネットワークインストールする。](https://qiita.com/sakai00kou/items/16b22a64e239170e774a)