Грузим ВСЁ по сети в DualBoot. Часть 2: Первые грабли в процессе загрузки MemTest86+
После теории нужно проверить ее на практике. В предыдущей статье я описывал варианты сетевой загрузки и остановился на iPXE, попробуем его запустить на чистой системе.
Часть 1: Теория и анализ предложений
Часть 2: Первые грабли в процессе загрузки MemTest86+
Часть 3: Добавляем поддержку UEFI
Часть 4: Загружаем Strelec WinPE
Часть 5: Загружаем полноценный дистрибутив Linux Ubuntu
Часть 6: Загружаем Windows Installer и ставим ОС
Часть 7: Устанавливаем Windows на iSCSI диск по сети
Часть 8: Жонглируем пунктами iPXE меню
Часть 9: Обслуживание сервера и обновление образов
Подготовка среды
Мои действия будут проводиться в виртуальной среде, где будут 3 виртуальные машины:
- PXE Server: минимальная конфигурация Ubuntu Server 20.10, 4vCPU, 4Gb RAM, 50Gb HDD (если нужно, можно увеличить), с двумя сетевыми интерфейсами: сетевой интерфейс в настоящую сеть, там же где находится хост (LAN) и второй в частный виртуальный коммутатор, на 3 виртуальные машины (PXELAN)
- Client Legacy: без дисков, 2-4Gb RAM, 4vCPU, устаревший* сетевой адаптер, подключенный в PXELAN
- Client UEFI: без дисков, 2-4Gb RAM, 4vCPU, сетевой адаптер, подключенный в PXELAN
*В Hyper-V поколении 1 (legacy) только устаревшие сетевые адаптеры умеют загружаться по сети, его нужно будет добавить вручную в настройках виртуальной машины.
Итак, цепляемся к PXE Server по SSH и донастраиваем систему:
apt update && apt upgrade
apt remove netplan.io -y
apt install ifupdown dnsmasq htop -y
systemctl disable systemd-resolved.service
cat > /etc/network/interfaces << EOF
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address 192.168.9.1
netmask 255.255.255.0
EOF
reboot
Для управления сетью верну обратно ifupdown и пропишу нужный конфиг. В качестве DHCP сервера будет использоваться пакет dnsmasq. Данный продукт сочетает в себе DNS (нам не потребуется), DHCP и TFTP сервер в одном флаконе и с простой настройкой. Пока что этого будет достаточно.
Настройка DNSMASQ
Как мы помним из первой части, у нас первые участники в процессе загрузки это DHCP и TFTP сервера, поэтому идем настраивать, заодно выделим папку для файлов сетевой загрузки:
mkdir -p /pxe/ipxe
cat > /etc/dnsmasq.conf << EOF
# настройки DNS сервера (по желанию)
no-resolv
expand-hosts
server=8.8.8.8
server=8.8.4.4
# настройки DHCP сервера
interface=eth1
dhcp-range=192.168.9.10,192.168.9.250,255.255.255.0,10m
dhcp-authoritative
dhcp-leasefile=/var/log/dnsmasq.leases
# настройка опций 67 и 66 для сетевой загрузки
dhcp-boot=/ipxe/ipxe.legacy,,192.168.9.1
# настройки TFTP сервера
enable-tftp
tftp-root=/pxe
tftp-mtu=1350
tftp-no-blocksize
# логирование
log-dhcp
EOF
service dnsmasq restart
Теперь нужно раздобыть файл undionly.kpxe – бинарный файл загрузки режима Legacy. Но тут нас поджидает первая грабля. Так как iPXE изначально разрабатывался как альтернативное решение для прошивки сетевых карт, то если возьмем стандартный файл undionly.kpxe, при загрузке iPXE будет заново инициализировать сеть и загружать новый бинарный файл, указанный в 66 и 67 опциях, то есть сам себя. В итоге возникнет бутлуп.
Компилируем свой iPXE
Согласно странице chainloading (“цепная загрузка”) официального сайта выхода из ситуации всего два:
- Скомпилировать свой iPXE, задав на этапе компиляции нужные действия при запуске бинарного файла (заменив загрузку самого себя)
- Объяснить DHCP-серверу, чтобы при ответе прошивке контроллера выдавал сам бинарный файл iPXE, а при ответе самому iPXE уже выдавал другой параметр в той же 67 опции, основываясь на vendor class (опция 60).
Второй вариант кажется немного легче, однако на DNSMasq его не реализовать, даже несмотря на то, что в DNSMasq есть фильтры “network-id”, поэтому придется скачивать и компилировать iPXE из исходников. Если вам не хочется компилировать, то можете взять готовый бинарный файл здесь.
# скачиваем утилиты для сборки и клонируем к себе репозиторий
apt install build-essential liblzma-dev git wget -y
git clone http://git.ipxe.org/ipxe.git
cd ipxe/src
# записываем скрипт, который будет выполняться при запуске iPXE
# в данном случае, он получает настройки по dhcp, а затем
# загружается по tftp в меню по пути ipxe/menu.ipxe
# с pxe сервера
cat > starter.script.ipxe << EOF
#!ipxe
dhcp || reboot
chain tftp://\${net0/next-server}/ipxe/menu.ipxe
EOF
# собираем, бинарный файл вместе со скриптом
make -j4 bin/undionly.kpxe EMBED=starter.script.ipxe
# заменяем старый на новый
mv /pxe/ipxe/ipxe.legacy /pxe/ipxe/ipxe.legacy.original
cp bin/undionly.kpxe /pxe/ipxe/ipxe.legacy
Так как файла /pxe/ipxe/menu.ipxe у нас еще не создано, то при попытке загрузки iPXE теперь не будет падать в bootloop, а выйдет ошибка “no such file or directory”.
Создаем свое меню
Давайте же создадим простое меню, с единственным пока что пунктом:
cat > /pxe/ipxe/menu.ipxe << EOF
#!ipxe
set menu-timeout 0
# находим ip адрес сервера загрузки
set srvip \${net0/next-server}
# создаем меню
# item - вариант выбора,
# в переменную selected падает то что выбрано,
# а мы потом можем сделать на эту метку goto
:start
menu Simple iPXE boot menu
item memtest Run Memtest86+-5.31b
choose --default memtest selected
goto \${selected}
# теперь загружаем сам MemTest86 с помощью memdisk
:memtest
initrd tftp://\${srvip}/utilites/mt531b.iso
chain tftp://\${srvip}/utilites/memdisk iso raw
EOF
Итак, memdisk – это маленькая утилита, которая загружает iso в ОЗУ, запускает эмуляцию диска и пытается с него загрузиться. Главный ее недостаток это то, что она загружает образ в ОЗУ, следственно мы не можем просто взять и загрузить любой ISO, а можем только маленькие утилиты.
Скачать бинарный файл memdisk и последний MemTest86+ можно тут, для работы переместите их в папку /pxe/utilites.
В результате у нас успешно запускается меню и при нажатии Enter – MemTest86+
Грузим ВСЁ по сети в DualBoot. Часть 2: Первые грабли в процессе загрузки MemTest86+: 5 комментариев
херь нерабочая
переменная ${net0/next-server} получается ПУСТАЯ
если не заменить на конкретный ip то ничего не работает
в какой момент? в скрипте скомпилированного ipxe или в меню загрузки?
по идее, если dhcp сервер отдает опцию, должна падать
По первому варианту выхода из бутлупа – в виртуалках уже встроен ipxe, по всей видимости, эмулируется прошитая сетевая карта. Поэтому первый запуск не отличить от второго.
:memtest
initrd tftp://\${srvip}/utilites/mt531b.iso
chain tftp://\${srvip}/utilites/memdisk iso raw
Не отрабатывает.
Прописывал явный ip адрес вместо переменной. Получаю:
Could not boot: No such file or directory
No more network devices
Со стороны tftp работает – файлы закачиваются и скачиваются.
Где копать?
Нигде не копать УМВР.