Windows 10をインストールするにあたり、
USBメモリを作るのもCDドライブを用意するのも面倒だったので、PXEを使ってインストールしました。
利用する技術
はじめに今回利用する技術要素を簡単に紹介します。
PXE
**PXE(Preboot eXecution Environment)**はクライアントがネットワークからソフトウェアを取得して実行する仕組みです。
よくあるNICにはこのPXEクライアント機能が実装されており、OSのインストールなどに利用することができます。Wikipedia
iPXE
iPXEはオープンソースのネットワークブートファームウェアです。
PXEクライアント機能に加え、いくつかの機能が追加されています。
詳しくはこちらのページに記載があります。
今回利用するにあたって重要なのは、HTTPでソフトウェアを取得して起動できることです。
WinPE
**WinPE(Windows PE)**はWindows OSのデプロイ等に利用できる、小さなOSです。
通常のWindowsと比べると機能が制限されています。
インストール概要
今回は、これらの技術を組み合わせてWindows OSをインストールします。
最終的にはこんな感じにします。
インストールするために、Linuxサーバをひとつ用意します。
今回は、新しいパソコンとLinuxサーバをL2で接続することとし、他のホストは接続されていないこととします。
まずはLinuxサーバを作っていきます。
Linuxサーバ構築
今回はFedora 33 WorkStationのVMを用意しました。
[testing@localhost ~]$ cat /etc/fedora-release
Fedora release 33 (Thirty Three)
インターフェイスには固定IPアドレス192.168.0.1/24を設定します。
(各種ソフトウェアインストールにはインターネット接続が必要ですので、環境によっては適宜DHCPに戻すなどする必要があるかもしれません。)
[testing@localhost ~]$ ip a sh ens3
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:28:c1:a9 brd ff:ff:ff:ff:ff:ff
altname enp0s3
inet 192.168.0.1/24 brd 192.168.0.255 scope global noprefixroute ens3
valid_lft forever preferred_lft forever
inet6 fe80::da34:251a:af7d:962d/64 scope link noprefixroute
valid_lft forever preferred_lft forever
1. DHCPサーバ、TFTPサーバ設定
はじめに、DHCPサーバとTFTPサーバを設定します。
今回利用するdnsmasqはTFTPサーバ機能を持っていますが利用しません。
別途tftpdをインストールします。
# Fedoraインストールした時点でdnsmasq入っていました。
$ rpm -q dnsmasq
dnsmasq-2.82-3.fc33.x86_64
$ sudo vi /etc/dnsmasq.conf
<下に記載>
$ sudo firewall-cmd --add-service dhcp
$ sudo systemctl start dnsmasq
# interfaceを必要なインターフェイスに変更する。
interface=ens3
# 適当なdhcp-rangeをコメントアウトする。
dhcp-range=192.168.0.50,192.168.0.150,12h
# iPXEに関わる設定をコメントアウト。
# 3行目、iPXEに返すdhcp-bootをスクリプトのURLに変更する。スクリプトは後で作成。
dhcp-boot=undionly.kpxe
dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
dhcp-boot=tag:ipxe,http://192.168.0.1/boot.ipxe
# 今回はiPXEをFedora Repositoryから取得する。
$ sudo dnf install ipxe-bootimgs
$ rpm -ql ipxe-bootimgs
/usr/share/doc/ipxe-bootimgs
/usr/share/doc/ipxe-bootimgs/COPYING
/usr/share/doc/ipxe-bootimgs/COPYING.GPLv2
/usr/share/doc/ipxe-bootimgs/COPYING.UBDL
/usr/share/ipxe
/usr/share/ipxe/ipxe-i386.efi
/usr/share/ipxe/ipxe-x86_64.efi
/usr/share/ipxe/ipxe.dsk
/usr/share/ipxe/ipxe.iso
/usr/share/ipxe/ipxe.lkrn
/usr/share/ipxe/ipxe.usb
/usr/share/ipxe/undionly.kpxe # <- これを使う。
$ sudo dnf install tftp-server
$ sudo firewall-cmd --add-service tftp
$ sudo systemctl start tftp
$ sudo cp /usr/share/ipxe/undionly.kpxe /var/lib/tftpboot/
ここまでやれば、iPXEの起動までは確認できるはずです。
2. WinPE準備
ここでWinPEを作成します。
Windowsで作成する方法もあるのですが、今回は**wimlib**を使ってLinuxで作成してみます。
この時点でWindowsのインストール用ディスクイメージ(ISOファイル)が必要ですので、Microsoft公式からダウンロードしてLinuxサーバに配置しておきます。
# 英語版の場合。
$ ls Win10_20H2_v2_English_x64.iso
Win10_20H2_v2_English_x64.iso
# wimlib-utilsとsyslinuxをインストール。
$ sudo dnf install wimlib-utils
$ sudo dnf install syslinux
# WinPE起動時のコマンドを指定。
$ vi boot.cmd
<下に記載>
# 適当にインストーラをマウント。
$ sudo mount Win10_20H2_v2_English_x64.iso /mnt
$ mkwinpeimg -W /mnt -a amd64 -s boot.cmd winpe.img
# アンマウントしておく。
$ sudo umount /mnt
上で作成するboot.cmd
ファイルです。
ユーザ名(例ではtesting)はLinuxのユーザ名に、
パスワード(例ではpassword)は後ほど指定するSambaのパスワードにします。
wpeinit
ping -n 10 localhost
net use n: \\192.168.0.1\testing password /user:testing
n:\installer\setup.exe
これでWinPEのイメージが作成できました。
ちなみに
ping -n 10 localhost
があるのは不可解かもしれませんが、sleep 10
を目的としています。
net use
を実行する際にネットワーク設定が終わっていないとエラーになるためで、苦肉の策なのです…
3. HTTPサーバ設定
今回はNginxを利用します。
$ sudo dnf install nginx
$ sudo firewall-cmd --add-service http
$ sudo systemctl start nginx
WinPEの起動に必要なファイルを配置します。
唐突ですが、wimbootというソフトウェアを利用します。
$ wget http://git.ipxe.org/releases/wimboot/wimboot-latest.zip
$ unzip wimboot-latest.zip
$ sudo cp <展開されたディレクトリ>/wimboot /usr/share/nginx/html/
WinPEイメージから必要なファイルを取り出して配置します。
$ sudo mount winpe.img /mnt/
$ sudo cp -r /mnt/boot /mnt/sources /usr/share/nginx/html
最後に、iPXEのスクリプトファイルを作成します。
(wimbootページを参考にしました。)
# DHCPで返すファイル名と一致させること。
$ sudo vi /usr/share/nginx/html/boot.ipxe
#!ipxe
kernel wimboot
initrd boot/bcd BCD
initrd boot/boot.sdi boot.sdi
initrd sources/boot.wim boot.wim
boot
うまくいけば、この時点でWinPEの起動が確認できます。
4. Samba設定
続いてSambaの設定を行います。
$ sudo dnf install samba
# パスワードを設定する。WinPE作成時に記載したユーザ名、パスワードと同じにする。
$ sudo smbpasswd -a -U testing
New SMB password:
Retype new SMB password:
Added user testing.
$ sudo firewall-cmd --add-service samba
$ sudo systemctl start smb
windowsのインストーラを参照できるようにします。
今回はhomeディレクトリを使います。
$ sudo setsebool -P samba_enable_home_dirs=on
$ cd
# WinPE作成時に記載したパスに合わせる。
$ mkdir installer
$ sudo mount -o context=user_u:object_r:user_home_t:s0 Win10_20H2_v2_English_x64.iso installer/
$ ls installer/
autorun.inf boot bootmgr bootmgr.efi efi setup.exe sources
これでLinuxサーバの設定はおわりです。
インストール実行
インストールしてみます。
正しく接続できたら、新しいパソコンを起動して、インストーラが起動するのを待ちます。
インストーラが起動した後は通常と同様でだいたい大丈夫です。
(必要なら起動時にBoot Orderを変更します。)
例を示すため、試しに仮想マシンでやってみます。
- 初めにPXEからiPXEが起動します。
(今回の仮想マシンでは最初からiPXEが起動するため、ここはありません。) - 次にiPXEがHTTPでスクリプトを取得し、実行します。
- WinPEが起動します。
- WinPEがSambaに接続し、インストーラを起動します。
- あとは通常と同様です。(一部選べないオプションなどあるようです。)
このようにインストールができました。
補足・追記
上記手順ではfirewalldやsystemdサービスの設定を永続化していないため、Linuxサーバを再起動すると設定が消えてしまいます。
感想
すごくつまったので安いUSBメモリ買ってきたほうが早かったと思います。
ただ、実際の機械をPXEで起動するのはやはり楽しいですね。
バージョン情報など
今回利用した主なソフトウェアのバージョンを記載しておきます。
$ rpm -q dnsmasq
dnsmasq-2.82-3.fc33.x86_64
$ rpm -q tftp-server
tftp-server-5.2-31.fc33.x86_64
$ rpm -q nginx
nginx-1.18.0-3.fc33.x86_64
$ rpm -q samba
samba-4.13.3-0.fc33.x86_64
$ rpm -q ipxe-bootimgs
ipxe-bootimgs-20200823-1.git4bd064de.fc33.noarch
$ rpm -q wimlib-utils
wimlib-utils-1.13.3-1.fc33.x86_64