セキュアブートに対応した 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.ixpe 相当) の例です。
長くなりましたが、今回は以上です。それでは。
なので、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 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> EOFDebian/Ubuntuの場合、config の 有効化・無効化は a2ensite/a2dissiteコマンドでできますので、そちらを使ってみてください。なおポートの設定を追加している為、systemctl restart apache2 で apache2 の再起動が必要です。
最後に /srv/tftp/Altiris/iPXE/GetPxeScript.aspx ( 中身は menu.ixpe 相当) の例です。
# 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 バイナリがあるにはあるので、いつかは出てくるかもしれませんね。
長くなりましたが、今回は以上です。それでは。
コメント
コメントを投稿