Windows 11にHTTP Bootサーバを立てる

# 0. 概要

[前回の記事](https://qiita.com/nkn-khr/items/92ea52a6b0e8a6d617a8 "Windows10にPXEブートサーバをたてる")では[PyPXE](https://github.com/pypxe/PyPXE "PyPXE")でPXEサーバを立てましたが、UEFIモードではブートできないという問題がありました。
今回はWindows 11でHTTP Bootサーバを立てて、UEFIモードでブートできるようにします。
前回と同様、Linux等の仮想環境を使わず、Windowsアプリのみで実現します。

HTTP BootするOSは、[SPP Custom Download](https://spp.hpe.com/custom/)から取得したSPP 2024.04.00.00 + Patch Bunlde 2です。私物の ProLiant ML30 Gen10をブートクライアントとして動作確認しました。

作業は以下の流れです。

1. DHCPDを立てる
1. HTTPDを立てる
1. ブートイメージを準備する
1. ブートクライアントを起動する

## 余談: HTTP Bootとは?
PXE(DHCP+TFTP)と同様にネットワークブートする技術です。ブートイメージの通信にHTTP(S)を用いる点がPXEと異なります。

# 1. DHCPDを立てる
[isc-dhcp-windows](https://github.com/HikaruDY/isc-dhcp-windows)からWindows版isc-dhcp v4.4.3(dhcpd-v4.4.3-Windows-x64.zip)をありがたくダウンロードさせていただいて、任意のディレクトリに展開します。

コマンドプロンプトで作業します。
```
> cd extracted-folder
> mkdir var\db
> type nul > var\db\dhcpd.leases
> mkdir var\run
> notepad etc\dhcpd.conf
> type etc\dhcpd.conf
----
option domain-name "example.com";
option domain-name-servers bootsrv.example.com;
default-lease-time 600;
max-lease-time 7200;

authoritative;
option architecture-type code 93 = unsigned integer 16;

subnet 192.168.0.0 netmask 255.255.255.0 {
    range 192.168.0.110 192.168.0.119;
    option broadcast-address 192.168.0.255;
    option routers 192.168.0.254;
    
    class "httpclients" {
        match if substring (option vendor-class-identifier, 0, 10) = "HTTPClient";
        option vendor-class-identifier "HTTPClient";
        filename "http://192.168.0.31/grubx64.efi";
    }
}
----
※Windows11のIPアドレスは 192.168.0.31/24 とします

> sbin\dhcpd -4 -f -d 
```

実行すると、dhcpdの通信がファイアウォールにブロックされるポップアップ画面がでるため、前回のPythonと同様にアクセス許可します。


# 2. HTTPDを立てる

[nginx: download](https://nginx.org/en/download.html)からWindows版nginxをダウンロードして任意のフォルダに展開します。

コマンドプロンプトで作業します。
```
> cd extracted-folder
> nginx -g "daemon off;"
```
dhcpdと同様にファイアウォールの許可を行います。

PowerShellコンソールを開いて、HTTPアクセスログを監視します。
```
> cd extracted-folder
> Get-Content .\log\access.log -Wait
```

# 3. ブートイメージを準備する

## ISOイメージを準備する

[SPP Custom Download](https://spp.hpe.com/custom/)から取得したSPP 2024.04.00.00 + Patch Bundle 2のISOファイルを準備します。

## カーネルとinitrdを準備する

ISOファイルのpxeフォルダから vmlinuzとinitrd.imgを準備します。
配布されているinitrd.imgはファイルが足りないようなので、[コミュニティ情報(SPP-2023.03.00.00 PXE issue)](https://community.hpe.com/t5/proliant-servers-ml-dl-sl/spp-2023-03-00-00-pxe-issue/td-p/7189049)を参考に修正してください。

## grub2バイナリを準備する

RockyLinuxから[EFI版grub2のRPMファイル](https://dl.rockylinux.org/vault/rocky/9.4/BaseOS/x86_64/os/Packages/g/grub2-efi-x64-2.06-82.el9_4.x86_64.rpm
)を取得します。
7-zip File Manager等で展開して grub2.efiを準備します。

## grub.cfgを準備する
メモ帳などで準備してください。
```grub.cfg
set timeout=5
menuentry 'SPP 2024040002' {
        echo 'Loading kernel ...'
        linuxefi vmlinuz media=net root=/dev/ram0 showopts TYPE=MANUAL AUTOPOWEROFFONUCCESS=no iso1=http://192.168.0.31/SPP-2024.04-00.02.iso iso1mnt=/mnt/bootdevice
        echo 'Loading initrd ...'
        initrdefi fixed_initrd.img
}
```

## ファイルをHTTPコンテンツ用のフォルダに配置する

ISOファイル、vmlinuz、修正したinitrd、grub2.efi、grub.cfgをnginxフォルダのhtmlサブフォルダに置きます。


# 4. ブートクライアントを起動する

ブートクライアント(HPE ProLiant ML30 Gen10)を起動するとHTTP Bootを試みるタイミングで
DHCPdからIPアドレスとブートEFI URLを取得します。

EFI版grub2をHTTPで取得し、grub.cfgも同様にHTTPで取得します。

grub.cfgに書かれたカーネルとinitrdをHTTPで取得し、SPPのブートが開始します。

# 5. まとめ
大容量となりがちな仮想マシンを準備することなく、Windows PCをHTTP Bootサーバとできました。