セキュアブートに対応した iPXE バイナリは公式サイトにはないのですが、調べていると サイン済みのバイナリが broadcom 社の KB に あると ipxe.org の bbs に記載がありました。該当の kb はこちらです。早速、この kb にリンクのある "64bit_ipxe_efi.zip" をブラウザでダウロードし、tftp/http サーバー上で解凍、dhcp サーバを設定して、tftp で取得・起動させた所、起動はするものの次のステージへは、特定のhttp ポート ( 4433 ) の固定パス ( Altiris/iPXE/GetPxeScript.aspx ) を参照するため、何もしていないと connection がリセットされてしまいます。
なので、apache2を 4433でもリッスンするようにして Altiris/iPXE/GetPxeScript.aspx を配置し、中身を shell が起動するだけの menu.ipxe にしたところ、シェルに入れました。これでOKだと思ったのですが、実はここからが難題でした。
というのも、サイン済みの bootnetx64.efi や linux カーネルをブートしようとしても、exec format error になり起動できません。機種によっては wimboot すら起動しません。それでも CDぐらいはブートできるだろうと思い直し、インストーラの iso ファイルの起動を sanboot コマンドにて試してみたところ、起動はするものの今度はインストーラまで到達できません。ただ、grubとカーネルまでは起動はしているので、iso ファイルを自前で作成し、前回のように nfsroot で立ち上げた所、システムも起動できましたが、isoファイルの作成だと grubのメニュー項目が read only なので、編集したい場合は iso ファイルを再作成しなければならず、実用的ではないなとこれはボツネタにしました。
そこで気を改めて r/w 可能な iSCSI で試してみることにしました。まず、始めは netinst cd イメージを targetcli で エクスポートした所、isoファイルの sanboot とほぼ同じで、grubとカーネルまでは起動できますが、cdromのマウントができない旨でインストール処理を続行することができませんでした。
ここで発想をかえて、grub からカーネルの起動まではできているので、iSCSI ターゲット上で ディスクイメージファイルを作成し、これを nbd デバイスとして割当ててマウントし、必要なものを grub-install や debootstrapで用意してから起動した所、無事 iPXE経由で Debianをセキュアブートできるようになりました。これで disk image file の書込もでき、grub メニューの変更も比較的簡単にできるので、本稿を挙げてみることにしました。
前置きが長くなりましたが、以下設定です。
続いて grubのメニューを設定しておきます。
次は、dhcpサーバを設定します。最初はkea-dhcpで行こうと思ったのですが、クライアントによっては boot file 名を正常に受け渡しできなかったので、isc-dhcp-serverで設定しました。
最後に /srv/tftp/Altiris/iPXE/GetPxeScript.aspx ( 中身は menu.ipxe 相当) の例です。
長くなりましたが、今回は以上です。それでは。
なので、apache2を 4433でもリッスンするようにして Altiris/iPXE/GetPxeScript.aspx を配置し、中身を shell が起動するだけの menu.ipxe にしたところ、シェルに入れました。これでOKだと思ったのですが、実はここからが難題でした。
というのも、サイン済みの bootnetx64.efi や linux カーネルをブートしようとしても、exec format error になり起動できません。機種によっては wimboot すら起動しません。それでも CDぐらいはブートできるだろうと思い直し、インストーラの iso ファイルの起動を sanboot コマンドにて試してみたところ、起動はするものの今度はインストーラまで到達できません。ただ、grubとカーネルまでは起動はしているので、iso ファイルを自前で作成し、前回のように nfsroot で立ち上げた所、システムも起動できましたが、isoファイルの作成だと grubのメニュー項目が read only なので、編集したい場合は iso ファイルを再作成しなければならず、実用的ではないなとこれはボツネタにしました。
そこで気を改めて r/w 可能な iSCSI で試してみることにしました。まず、始めは netinst cd イメージを targetcli で エクスポートした所、isoファイルの sanboot とほぼ同じで、grubとカーネルまでは起動できますが、cdromのマウントができない旨でインストール処理を続行することができませんでした。
ここで発想をかえて、grub からカーネルの起動まではできているので、iSCSI ターゲット上で ディスクイメージファイルを作成し、これを nbd デバイスとして割当ててマウントし、必要なものを grub-install や debootstrapで用意してから起動した所、無事 iPXE経由で Debianをセキュアブートできるようになりました。これで disk image file の書込もでき、grub メニューの変更も比較的簡単にできるので、本稿を挙げてみることにしました。
前置きが長くなりましたが、以下設定です。
# 必要なパッケージのインストールとファイルの準備 ( on tftp/http server 10.1.1.50 i50) apt-get install tftpd-hpa apache2 unzip cd /srv/tftp mkdir ipxe-signed cd ipxe-signed # 上述の kb にある zipファイルをここに解凍。 unzip ~/ダウンロード/64bit_ipxe_efi.zip cd /srv/tftp wget https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz tar xzpf netboot.tar.gz最低限必要なファイルは以上です。続いて必要なパッケージをインストールし disk image file を作成して targetcli を設定し disk image にアクセスできるようにしておきます。
# on iscsi target( on 10.1.1.106 sv106) apt-get install qemu-nbd dosfstools xfsprogs grub-efi-amd64-signed debootstrap modprobe -av nbd mkdir -p /srv/ cd /srv/deb01 dd if=/dev/zero of=deb10.disk.img bs=1024k count=32768 dd if=/dev/zero of=deb11.disk.img bs=1024k count=32768 dd if=/dev/zero of=deb12.disk.img bs=1024k count=32768 ## targetcli start ( deb12.disk.img ) targetcli cd /backstores/fileio create deb12-amd64-01 /srv/deb01/deb12.disk.img cd /iscsi create iqn.1868-01.com.example:sv106.deb12-amd64-01 cd iqn.1868-01.com.example:sv106.deb12-amd64-01/tpg1/luns create /backstores/fileio/deb12-amd64-01 cd ../acls create iqn.1868-01.com.example:ft01 cd / saveconfig exit ## targetcli end続いて disk image のパーティション(p1=ESP:vfat, p2=root:xfs)を設定しフォーマットしておきます。
# on iscsi target( on 10.1.1.106 sv106)
NBD=nbd12
DEB=deb12
HN=${DEB}a
qemu-nbd --format=raw --connect=/dev/${NBD} /srv/deb01/${DEB}.disk.img
fdisk /dev/${NBD}
############################
g
n
enter
enter
1050623
t
uefi
n
enter
enter
enter
w
############################
mkfs.vfat /dev/${NBD}p1
# debian 10 の場合
# mkfs.xfs -m crc=0,finobt=0 -f /dev/${NBD}p2
# debian 12 の場合
mkfs.xfs -f /dev/${NBD}p2
続いて 必要最小限の grub の設定を行います。
# on iscsi target( on 10.1.1.106 sv106)
P1_UUID=`lsblk -f /dev/${NBD}p1 | grep ${NBD}p1 | awk '{print $4}'`
P2_UUID=`xfs_admin -u /dev/${NBD}p2 | cut -d' ' -f 3`
mount /dev/${NBD}p2 /mnt
mkdir -p /mnt/boot/efi
mount /dev/${NBD}p1 /mnt/boot/efi
cd /mnt/boot/efi
mkdir -p /mnt/boot/efi/EFI/debian
scp 10.1.1.50:/srv/tftp/debian-installer/amd64/bootnetx64.efi /mnt/boot/efi/EFI/debian/
cat > /mnt/boot/efi/EFI/debian/grub.cfg <<EOF
search.fs_uuid $P2_UUID root hd0,gpt2
set prefix=(\$root)/boot/grub
configfile \$prefix/grub.cfg
EOF
grub-install --target=x86_64-efi --efi-directory=/mnt/boot/efi --boot-directory=/mnt/boot --uefi-secure-boot /dev/${NBD}
システムがインストールされていなくても、ここまでで grub のシェルが立ち上がるようになります。(一旦ここで iSCSIからブートしてみると良いかもしれません。)続いて grubのメニューを設定しておきます。
# on tftp/http server 10.1.1.50 i50
mkdir -p /mnt/boot/grub
cat > /mnt/boot/grub/grub.cfg <<EOF
menuentry 'Debian 10 iSCSI root'{
linux /vmlinuz root=UUID=$P2_UUID rw ip=::::::dhcp iscsi_auto rootfstype=xfs rootwait
initrd /initrd.img
}
EOF
続いてシステムを populate していきます。
# on iscsi target ( 10.1.1.106 sv106 ) cd /mnt # debian 10 busterの場合 # debootstrap buster . # debian 12 boookworm の場合 debootstrap bookworm .つづいて、debootstrap では足りないパッケージ等を半自動でインストール・設定します。
cat > root/and-so-on.sh <<EOF apt-get install -y --no-install-recommends linux-image-amd64 dbus busybox xfsprogs openssh-server open-iscsi dbus zstd apt-get install -y --no-install-recommends locales console-setup xterm fbterm fonts-vlgothic fonts-courier-prime # set root password passwd # add user adduser YourUserName # change hostname echo deb12a > /etc/hostname # add ipv4 nameservers echo nameserver 10.1.1.64 >> /etc/resolv.conf echo nameserver 10.1.1.65 >> /etc/resolv.conf # setup locales dpkg-reconfigure locales # setup keyboard layout dpkg-reconfigure keyboard-configuration exit EOF mount -t proc proc proc/ mount -t sysfs sysfs sys/ chroot . bash root/and-so-on.sh umount proc/ umount sys/ cd /root umount /mnt/boot/efi umount /mntiSCSIディスクのセットアップは以上です。
次は、dhcpサーバを設定します。最初はkea-dhcpで行こうと思ったのですが、クライアントによっては boot file 名を正常に受け渡しできなかったので、isc-dhcp-serverで設定しました。
# on tftp/http server 10.1.1.50 i50
apt-get install isc-dhcp-server
# /etc/dhcp/dhcpd.conf
allow booting;
allow bootp;
option iscsi-initiator-iqn code 203 = string;
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;
set vendorclass = option vendor-class-identifier;
option pxe-system-type code 93 = unsigned integer 16;
set pxetype = option pxe-system-type;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;
log-facility-local7;
subnet 10.1.1.0 netmask 255.255.255.0 {
option domain-name-servers 10.1.1.64, 10.1.1.65;
option domain-name "example.com";
option routers 10.1.1.23;
option broadcast-address 10.1.1.255;
next-server 10.1.1.50;
if substring(vendorclass, 0, 9)="PXEClient" {
if pxetype=00:06 or pxetype=00:07 {
filename "ipxe-signed/ipxe.efi";
# filename "ipxe-signed/snponly.efi";
} else {
filename "pxelinux/pxelinux.0";
}
}
pool {
range 10.1.1.180 10.1.1.250;
}
}
host ft01 {
hardware Ethernet e4:7f:b2:16:e0:58;
fixed-address 10.1.1.172;
next-server 10.1.1.50;
filename "ipxe-signed/ipxe.efi";
# filename "ipxe-signed/snponly.efi";
option host-name "ft01";
}
つづいて、http server(10.1.1.50 i50)の設定をおこないます。
# on http server (10.1.1.50 i50)
apt-get install apache2
cat > /etc/apache2/sites-available/ipxe-1-4433.conf <<EOF
<VirtualHost 10.1.1.50:4433>
ServerAdmin webmaster@example.com
DocumentRoot /srv/tftp
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory />
Options +FollowSymLinks +Indexes
Require all granted
</Directory>
</VirtualHost>
EOF
cat > /etc/apache2/sites-available/ipxe-1.conf <<EOF
<VirtualHost 10.1.1.50:80>
ServerAdmin webmaster@example.com
DocumentRoot /srv/tftp
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory />
Options +FollowSymLinks +Indexes
Require all granted
</Directory>
</VirtualHost>
EOF
cat > /etc/apache2/ports.conf <<EOF
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
Listen 80
Listen 4433
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
EOF
Debian/Ubuntuの場合、config の 有効化・無効化は a2ensite/a2dissiteコマンドでできますので、そちらを使ってみてください。なおポートの設定を追加している為、systemctl restart apache2 で apache2 の再起動が必要です。最後に /srv/tftp/Altiris/iPXE/GetPxeScript.aspx ( 中身は menu.ipxe 相当) の例です。
# on tftp/http server ( 10.1.1.50 i50 )
#!ipxe
:start
menu MENU
item --gap -- ---------------------------------------------------------------
item deb10-amd64-01-iscsi deb10-amd64-01 iscsi root
item deb11-amd64-01-iscsi deb11-amd64-01 iscsi root
item deb12-amd64-01-iscsi deb12-amd64-01 iscsi root
item --gap -- ---------------------------------------------------------------
item shell iPXE shell
item --gap -- ---------------------------------------------------------------
choose selected
goto ${selected}
:deb10-amd64-01-iscsi
set keep-san 1
set initiator-iqn iqn.1868-01.com.example:${hostname}
set root-path iscsi:10.1.1.106::::iqn.1868-01.com.example:sv106.deb10-amd64-01
sanboot --drive 0x80 --filename \EFI\debian\bootnetx64.efi ${root-path}
goto start
:deb11-amd64-01-iscsi
set keep-san 1
set initiator-iqn iqn.1868-01.com.example:${hostname}
set root-path iscsi:10.1.1.106::::iqn.1868-01.com.example:sv106.deb11-amd64-01
sanboot --drive 0x80 --filename \EFI\debian\bootnetx64.efi ${root-path}
goto start
:deb12-amd64-01-iscsi
set keep-san 1
set initiator-iqn iqn.1868-01.com.example:${hostname}
set root-path iscsi:10.1.1.106::::iqn.1868-01.com.example:sv106.deb12-amd64-01
sanboot --drive 0x80 --filename \EFI\debian\bootnetx64.efi ${root-path}
goto start
:shell
echo Type 'exit' to get back to the menu
shell
set menu-timeout 0
goto start
設定は以上です。以下起動後の dmesg の一部です。
--snip [ 0.000000] Command line: BOOT_IMAGE=/vmlinuz root=UUID=5b540e35-9157-4c61-be1e-xxxxxxxxxxxx rw ip=::::::dhcp iscsi_auto rootfstype=xfs rootwait --snip [ 0.000000] secureboot: Secure boot enabled本来ならiPXE.orgが公式で signed バイナリをだしていればよいのですが、サイン済みの iPXE バイナリがあるにはあるので、いつかは出てくるかもしれませんね。
長くなりましたが、今回は以上です。それでは。
コメント
コメントを投稿