Грузим ВСЁ по сети в DualBoot. Часть 2: Первые грабли в процессе загрузки MemTest86+

Грузим ВСЁ по сети в 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 виртуальные машины:

  1. PXE Server: минимальная конфигурация Ubuntu Server 20.10, 4vCPU, 4Gb RAM, 50Gb HDD (если нужно, можно увеличить), с двумя сетевыми интерфейсами: сетевой интерфейс в настоящую сеть, там же где находится хост (LAN) и второй в частный виртуальный коммутатор, на 3 виртуальные машины (PXELAN)
  2. Client Legacy: без дисков, 2-4Gb RAM, 4vCPU, устаревший* сетевой адаптер, подключенный в PXELAN
  3. Client UEFI: без дисков, 2-4Gb RAM, 4vCPU, сетевой адаптер, подключенный в PXELAN
VM PXE Server
VM PXE Server
VM Client Legacy
VM Client Legacy
VM Client UEFI
VM Client UEFI
External LAN Virtual Switch
External LAN Virtual Switch
PXE LAN Virtual Switch
PXE LAN Virtual Switch
Host machine
Host machine
10.0.0.0/24
10.0.0.0/24
192.168.9.0/24
192.168.9.0/24
9.1
9.1
Viewer does not support full SVG 1.1

*В 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 Bootloop

Компилируем свой 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+

MemTest86+ загруженный по сети

Грузим ВСЁ по сети в DualBoot. Часть 2: Первые грабли в процессе загрузки MemTest86+: 5 комментариев

  1. херь нерабочая
    переменная ${net0/next-server} получается ПУСТАЯ
    если не заменить на конкретный ip то ничего не работает

    1. в какой момент? в скрипте скомпилированного ipxe или в меню загрузки?
      по идее, если dhcp сервер отдает опцию, должна падать

      1. По первому варианту выхода из бутлупа — в виртуалках уже встроен ipxe, по всей видимости, эмулируется прошитая сетевая карта. Поэтому первый запуск не отличить от второго.

  2. :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 работает — файлы закачиваются и скачиваются.
    Где копать?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *