iPXEでセキュアブートした TCP iSCSI root は前回の方法で一息ついたのですが、ConnectX VPI は rdma が使えるのに使わないのは勿体ないと思いました。なので一旦 iPXE で iBFT を登録・ iscsiでboot してから、initramfs 上で SRP root に切替た所、上手くいったのですが、SRPで複数ターゲット・複数イニシエータがある場合、ターゲットの探索を行うと、複数のターゲットが検出される上、/dev/disk/by-pathがローカルのデバイスと判別がつきにくく、さらに srptoolsには含まれるイニシエータプログラムが2つあり、それぞれ異なるaclを投げてくる為、管理が非常に面倒だということが分かったので、こちらはボツネタにしました。
そこで今度は iSER でテストし、/dev/disk/by-path での管理も特に問題はなさそうでしたので、initramfs 上で iBFT の情報( iscsistart -f )を元に tcp ISCSI root から ISER rootに切替したところ、上手くいきましたので本稿を挙げてみることにしました。
基本的には、前回の方法と同じなのですが、おさらいの意味も兼ねて今回は全体の詳細を挙げます。なお、今回はターゲット・tftp/httpサーバは同一の 10.1.40.51 ( i51 ) で、イニシエータは 10.1.40.114 ( sv114 ) で共にDebian 12 としています。また、dhcp server だけは Debian 12 の isc-dhcp-server が ipoib での bootps に対応していないので、別のサーバ ( 10.1.40.50, i50 Ubuntu24.04 ) としています。また、イニシエータは今回 2 ポートの Connectx-3 VPI で試したのですが、uefi ロムが見つかったので、セキュアブートもOKでした。
今回は以上です。それでは。
そこで今度は iSER でテストし、/dev/disk/by-path での管理も特に問題はなさそうでしたので、initramfs 上で iBFT の情報( iscsistart -f )を元に tcp ISCSI root から ISER rootに切替したところ、上手くいきましたので本稿を挙げてみることにしました。
基本的には、前回の方法と同じなのですが、おさらいの意味も兼ねて今回は全体の詳細を挙げます。なお、今回はターゲット・tftp/httpサーバは同一の 10.1.40.51 ( i51 ) で、イニシエータは 10.1.40.114 ( sv114 ) で共にDebian 12 としています。また、dhcp server だけは Debian 12 の isc-dhcp-server が ipoib での bootps に対応していないので、別のサーバ ( 10.1.40.50, i50 Ubuntu24.04 ) としています。また、イニシエータは今回 2 ポートの Connectx-3 VPI で試したのですが、uefi ロムが見つかったので、セキュアブートもOKでした。
# ターゲットイメージの作成等 ( on target 10.1.40.51 i51 ) apt-get install targetcli-fb qemu-utils tftpd-hpa apache2 REL=bookworm IMG=deb12.amd64.04.img tNAME=deb12-amd64-04 tHOSTNAME=i51 tADDR=10.1.40.51 tBASE=iqn.1868-01.com.example iHOSTNAME=sv114 NBD=nbd1 MP=/media/${tNAME} SRV=/srv/deb03 mkdir -p ${SRV} cd ${SRV} dd if=/dev/zero of=${IMG} bs=1024k count=32768 modprobe -av nbd qemu-nbd -f raw -c /dev/${NBD} /$SRV/${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 P2_UUID=`xfs_admin -u /dev/${NBD}p2 | cut -d' ' -f 3` mkdir -p ${MP} mount /dev/${NBD}p2 ${MP} mkdir -p ${MP}/boot/efi mount /dev/${NBD}p1 ${MP}/boot/efi cd ${MP}/boot/efi mkdir -p ${MP}/boot/efi/EFI/debian cd ${SRV} mkdir -p netboot cd netboot wget https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz tar xzpf netboot.tar.gz cp -a debian-installer/amd64/bootnetx64.efi ${MP}/boot/efi/EFI/debian/ cat > ${MP}/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=${MP}/boot/efi --boot-directory=${MP}/boot --uefi-secure-boot /dev/${NBD} cd ${MP} debootstrap ${REL} . # debootstrap では足りないパッケージ等を半自動でインストール・設定 cat > root/and-so-on.sh <<EOF apt-get install -y --no-install-recommends linux-image-amd64 busybox xfsprogs openssh-server open-iscsi dbus zstd apt-get install -y --no-install-recommends locales console-setup fbterm fonts-vlgothic fonts-courier-prime # set root password passwd # add user adduser YourUserName # change hostname echo ${tNAME} > /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 console dpkg-reconfigure console-setup # 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 $MP/boot KVER=`ls vmlinuz-*-amd64 | sed 's/vmlinuz-//g' | sed 's/-amd64//g'` cat > ${MP}/boot/grub/grub.cfg <<EOF serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1 terminal_input --append console serial terminal_output --append console serial set default="0" set timeout=20 menuentry 'Debian iSER root ( ${KVER} )'{ linux /boot/vmlinuz-${KVER}-amd64 root=UUID=$P2_UUID rw ip=:::::ib0:dhcp iscsi_auto net.ifnames=0 rootfstype=xfs rootwait console=tty0 console=ttyS0,115200n8 initrd /boot/initrd.img-${KVER}-amd64.iser } EOF mkdir -p /srv/tftp/boot cp -a ${MP}/boot/*${KVER}* /srv/tftp/boot/ ################################################################*/ # targetcli を使ってターゲットを作成 ( on target 10.1.40.51 i51 ) # create target for ibft targetcli /backstores/fileio create ${tNAME} ${SRV}/${IMG} targetcli /iscsi create ${tBASE}:${tHOSTNAME}.${tNAME} targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}/tpg1/luns create /backstores/fileio/${tNAME} targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}/tpg1/acls create ${tBASE}:${iHOSTNAME} # create itarget for iser targetcli /iscsi/ create ${tBASE}:${tHOSTNAME}.${tNAME}.iser targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}.iser/tpg1/luns create /backstores/fileio/${tNAME} targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}.iser/tpg1/portals/0.0.0.0:3260 enable_iser true targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}.iser/tpg1/acls create ${tBASE}:sv112 targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}.iser/tpg1/acls create ${tBASE}:sv113 targetcli /iscsi/${tBASE}:${tHOSTNAME}.${tNAME}.iser/tpg1/acls create ${tBASE}:${iHOSTNAME} targetcli / saveconfig ################################################################ # apache2 の設定 ( on target 10.1.40.51 i51 ) apt-get install apache2 cat > /etc/apache2/sites-available/ipxe-40.conf <<EOF <VirtualHost ${tAddr}:80> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. #ServerName www.example.com ServerAdmin webmaster@localhost DocumentRoot /srv/tftp # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # For most configuration files from conf-available/, which are # enabled or disabled at a global level, it is possible to # include a line for only one particular virtual host. For example the # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf <Directory /> Options +FollowSymLinks +Indexes Require all granted </Directory> </VirtualHost> EOF cat > /etc/apache2/sites-available/ipxe-40-4433.conf <<EOF <VirtualHost 10.1.40.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 a2dissite 000-default a2ensite ipxe* 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 systemctl restart apache2 ################################################### # isc dhcp server ( 別サーバ; on 10.1.1.50/10.1.40.50 i50 ubuntu24.04 ) # /etc/dhcp allow booting; allow bootp; option user-class code 77 = string; 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 exists user-class and option user-class = "iPXE" { filename "menu.ipxe"; } else { if pxetype=00:06 or pxetype=00:07 { filename "ipxe-signed/ipxe.efi"; # filename "ipxe-signed/snponly.efi"; # filename "ipxe-unsigned/snponly.efi"; # filename "ipxe-unsigned/ipxe.efi"; } elsif pxetype=00:00 { filename "ipxe.pxe"; } } pool { range 10.1.1.180 10.1.1.250; } } group ind40 { host sv114ind { option host-name "sv114"; next-server 10.1.1.51; hardware ethernet aa:bb:cc:dd:01:14; } } subnet 10.1.40.0 netmask 255.255.255.0 { option domain-name-servers 10.1.1.64; option domain-name "example.com"; option routers 10.1.40.50; option broadcast-address 10.1.40.255; next-server 10.1.40.50; if exists user-class and option user-class = "iPXE" { filename "menu.ipxe"; } else { if pxetype=00:06 or pxetype=00:07 { filename "ipxe-signed/ipxe.efi"; # filename "ipxe-signed/snponly.efi"; # filename "ipxe-unsigned/snponly.efi"; # filename "ipxe-unsigned/ipxe.efi"; } elsif pxetype=00:00 { filename "ipxe.pxe"; } } pool { range 10.1.40.200 10.1.40.250; } } group ib40 { option domain-name "ind40.example.com"; host sv114-cx354a-fcbt { option host-name "sv114"; hardware ethernet 00:11:22:33:01:14; filename "ipxe-signed/ipxe.efi"; fixed-address 10.1.40.114; next-server 10.1.40.51; } } # check config and restart dhcp server dhcpd -t systemctl restart isc-dhcp-server ################################################### # tftp server ( on 10.1.40.51 i51 ) apt-get install unzip cd /srv/tftp # download and copy 64bit_ipxe_efi.zip to here then unzip mkdir ipxe-signed cd ipxe-signed unzip ../64bit_ipxe_efi.zip ## edit menu.ipxe ( on i51) mkdir -p /srv/tftp/Altiris/iPXE cat > /srv/tftp/Altiris/iPXE/GetPxeScript.aspx <<EOF #!ipxe :start menu MENU item --gap -- -------------- item iSER-${tHOSTNAME}.${tNAME} iSER root ( ${tHOSTNAME}.${tNAME}.iser ) item --gap -- -------------- item shell Drop to iPXE shell item --gap -- -------------- choose selected goto \${selected} :iSER-${tHOSTNAME}.${tNAME} set initiator-iqn ${tBASE}:\${hostname} set root-path iscsi:${tAddr}::::${tBASE}:${tHOSTNAME}.${tNAME} sanboot --drive 0x80 --filename \EFI\debian\bootnetx64.efi \${root-path} || goto shell goto start :shell echo Type 'exit' to get back to the menu shell set menu-timeout 0 goto start EOF cd /srv/tftp ln -sf Altiris/iPXE/GetPxeScript.aspx menu.ipxe ################################################ # initramfs-tools の設定その1 ( on target 10.1.40.51 i51, chroot) cd ${MP} mount -t proc proc proc/ mount -t sysfs sysfs sys/ chroot . cat >> /etc/initramfs-tools/modules <<EOF ib_core ib_cm ib_uverbs ib_umad iw_cm rdma_cm rdma_ucm mlx4_core mlx4_ib mlx5_core mlx5_ib ib_mthca ib_ipoib iscsi_ibft ib_iser ib_srp EOF ################################################ # initramfs-tools の設定その2 ( on target 10.1.40.51 i51, chroot) cat > /etc/initramfs-tools/hooks/iscsiadm <<EOF #!/bin/sh PREREQ="" prereqs() { echo "\$PREREQ" } case \$1 in prereqs) prereqs exit 0 ;; esac . /usr/share/initramfs-tools/hook-functions copy_exec /bin/grep copy_exec /bin/sleep copy_exec /sbin/iscsiadm copy_exec /sbin/iscsid copy_exec /usr/bin/expr copy_file config /etc/iscsi/iscsid.conf copy_file config /etc/iscsi/initiatorname.iscsi copy_exec /usr/lib/*/libnss_files.so.* copy_exec /sbin/iscsi-iname copy_exec /sbin/iscsi_discovery copy_exec /lib/open-iscsi/startup-checks.sh /sbin EOF chmod +x /etc/initramfs-tools/hooks/iscsiadm #############################################################################*/ # initramfs-tools の設定その3 ( on target 10.1.40.51 i51, chroot) # /usr/share/initramfs-tools/scripts/local-top/iscsi の変更 mkdir -p /root/initrd_iser cd /root/initrd_iser cp -a /usr/share/initramfs-tools/scripts/local-top/iscsi iscsi.org cp -a /usr/share/initramfs-tools/scripts/local-top/iscsi iscsi # save as iscsi.patch --------------------------------------------------------------------- --- iscsi.orig 2022-10-20 00:59:32.000000000 +0900 +++ iscsi 2025-04-04 15:19:07.649734655 +0900 @@ -330,7 +330,70 @@ exit 0 fi -do_iscsi_login +iscsistart -f | grep -v \# > /run/iscsi-vars +i=`echo $ip | cut -d: -f 6` + +if [ -e /sys/class/net/$i/carrier ]; then + ip link set dev $i up && interface_up=`cat /sys/class/net/$i/carrier` +else + interface_up="" +fi +echo awainting for interface $i up +count=0 +while [ "$interface_up" == "0" -o ! -n "$interface_up" ] && [ $count -lt 30 ] +do + echo interface_up: $interface_up + if [ -e /sys/class/net/$i/carrier ]; then + ip link set dev $i up && interface_up=`cat /sys/class/net/$i/carrier` + else + interface_up="" + fi + if [ "$interface_up" == "1" ];then + echo $i is up + fi + count=$((count + 1)) + sleep 5 +done + +iface=`cat /run/iscsi-vars | grep iface.net_ifacename | cut -d' ' -f3` +i=`echo $ip | cut -d: -f 6` + +if [ "$iface" == "$i" ]; then + iscsistart -N || echo Failed to bring up the network as specified by iBFT. +else + address=`cat /run/iscsi-vars | grep iface.ipaddress | cut -d' ' -f3` + netmask=`cat /run/iscsi-vars | grep iface.subnet_mask | cut -d' ' -f3` + i=`echo $ip | cut -d: -f 6` + ip addr add ${address}/${netmask} dev $i +fi + +# workaround for iscsistart -N not adding default gateway +gw=`cat /run/iscsi-vars | grep iface.gateway | cut -d' ' -f3` +ip route add default via ${gw} dev $i + +mkdir -p /run/lock +mkdir -p /etc/iscsi +touch /etc/iscsi/iscsid.conf + +initiatorname=`cat /run/iscsi-vars | grep iface.initiatorname | cut -d' ' -f3` + +echo InitiatorName=${initiatorname} > /etc/initiatorname.iscsi +echo InitiatorName=${initiatorname} > /etc/iscsi/initiatorname.iscsi + +if startup-checks.sh; then + if [ ! -e /etc/passwd ] ; then + echo "root:x:0:0:root:/:/bin/sh" > /etc/passwd + fi + iscsid -c /etc/iscsi/iscsi.conf -i /etc/iscsi/initiatorname.iscsi -p /run/iscsid.pid + targetaddr=`cat /run/iscsi-vars | grep node | grep address | grep 0 | cut -d' ' -f3` + iscsiadm -m discovery -t sendtargets -p ${targetaddr} -I iser + targetname=`cat /run/iscsi-vars | grep node.name | cut -d' ' -f3` + iscsiadm -m node --login -p ${targetaddr} -T ${targetname}.iser -I iser && kill `cat /run/iscsid.pid` +else + echo startup-checks failed +fi + +#do_iscsi_login udevadm settle --------------------------------------------------------------------- apt-get install patch patch < iscsi.patch cp -a iscsi /usr/share/initramfs-tools/scripts/local-top/iscsi ################################################### # initramfs-tools の設定その4 ( on target 10.1.40.51 i51, chroot) cd ~ mkdir -p initrd_iser mkdir -p /srv/tftp/boot cd initrd_iser KVER=`cd /boot && ls vmlinuz-*-amd64 | sed 's/vmlinuz-//g' | sed 's/-amd64//g'` cat > updt-${KVER}.sh <<EOF update-initramfs -k ${KVER}-amd64 -c -b . mv initrd.img-${KVER}-amd64 initrd.img-${KVER}-amd64.iser cp initrd.img-${KVER}-amd64.iser ${MP}/boot EOF chmod +x updt-${KVER}.sh ./updt-${KVER}.sh ############################################## # 後片付け ( on target 10.1.40.51 i51 ) exit cd ${MP} umount proc/ umount sys/ cd umount ${MP}/boot/efi umount ${MP} qemu-nbd -d /dev/${NBD}以下ブート後のディスク情報です。
# df ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 udev 16140064 0 16140064 0% /dev tmpfs 3233152 1596 3231556 1% /run /dev/sdd2 32962560 2193632 30768928 7% / tmpfs 16165740 0 16165740 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock # ls -la /dev/disk/by-path | grep sdd$ lrwxrwxrwx 1 root root 9 4月 4 08:06 pci-0000:18:00.0-ip-10.1.40.51:3260-iscsi-iqn.1868-01.com.example:i51.deb12-amd64-03.iser-lun-0 -> ../../sdd # iscsiadm -m session iser: [2] 10.1.40.51:3260,1 iqn.1868-01.com.example:i51.deb12-amd64-03.iser (non-flash)なお スイッチを経由してイニシエータとターゲットを接続しているのですが、環境によるとは思いますが、grubから起動して ipoib インターフェスが initramf 上で up するのに時間がかかりましたので注意が必要かもしれません。
今回は以上です。それでは。
コメント
コメントを投稿