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'`
# 2025/05/22:terminal_iput terminal_output の2行を修正:
cat > ${MP}/boot/grub/grub.cfg <<EOF
serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
terminal_input --append console
terminal_output --append"console
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,115200n1
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 するのに時間がかかりましたので注意が必要かもしれません。
今回は以上です。それでは。
コメント
コメントを投稿