iPXE без лишних слов, но с большим количеством пояснений

от автора

Для начала определимся, что такое ipxe:

iPXE (open-source network boot firmware) — это загрузчик с открытым исходным кодом, предназначенный для сетевой загрузки операционных систем и других файлов. Он расширяет возможности стандартного PXE (Preboot Execution Environment), добавляя расширенные функции и гибкость в процесс загрузки по сети.

Статей на тему pxe, pxelinux, ipxe-загрузчиков, как и готовых решений в сети много, но:

  1. Готовые решения зачастую платные

  2. pxeboot, pxelinux.0 и оные не умеют в UEFI (или я не смог их подружить), а на дворе 2026 год и новых Legacy компьютеров на полках магазинов вы вряд ли найдёте

  3. Те статьи, что находил я, чаще всего заточены под Legacy загрузку с использованием ipxe через загрузку memdisk (о нём ниже), а загрузчики UEFI не работают с memdisk, поэтому в статье и проекте чаще всего будет использован http и sanboot (хоть и у него есть свои нюансы) и в отличии от прямой загрузки .iso в ОЗУ, он гибче (об этом тоже по ходу статьи)

Оглавление:

  1. Начало

  2. Настройка DHCP

  3. Первичная настройка и TFTP

  4. HTTP-сервер

  5. iPXE

  6. Veeam

  7. Strelec WinPE UEFI

  8. TGT и SAMBA

  9. Модификация wim

  10. Strelec WinPE LEGACY

  11. Kaspersky Remote Disk

  12. WDS

  13. Linux Ubuntu 24.04.4 autoinstall

  14. Итоги

Начало

Грузить по сети мы будем установщик Windows через WDS (отдельным пунктом загрузчика ipxe), Veeam, для бекапов и прочего, WinPE, Memtest, Kaspersky (KRD), установку Linux Ubuntu 24.04 (как ручную, так и автоматическую через autoinstaller), ручную установку Linux Ubuntu Server, также установку Linux Debian-а, остальные пункты меню можно добавлять по аналогии на ваш вкус и под ваши потребности

Небольшой спойлер конечной стадии проекта:

iPXE

iPXE

Как и в любом проекте, всё начинается с установки ОС, так как мне привычнее ubuntu, я поставил Linux Ubuntu 24.04.4 без графической оболочки (она нам не нужна), вы в праве поставить любой другой дистрибутив Linux

Что понадобится в проекте?

  1. ipxe

  2. TFTP-сервер

  3. HTTP-сервер

  4. TAG (iSCSI таргет)

  5. NFS

  6. SAMBA

Настройка DHCP

DHCP ставить не нужно, если он у вас на контроллере домена или на роутере, нужно будет настроить правила 66, 67, 60 и политики, сразу же с политик и правил и начнём:

Когда вы включаете компьютер, тот отправляет широковещательный запрос на DHCP сервер и ждёт от него таблицу параметров загрузки, поэтому на DHCP сервере создадим две политики для Legacy и UEFI соответственно:

политики

политики

В свойствах политики Legacy добавляем классы поставщика, именно они определяют, каким компьютерам какой файл 67-ым правилом отдавать:

классы поставщика

классы поставщика

Отдельная благодарность статье за представленное решение, классы поставщиков вы можете посмотреть по ссылке, смысл в том, что цифрами 14, 04, 05, 00 и т.д. мы объясняем клиенту, какой файл ему брать в момент загрузки по сети

КРАЙНЕ ВАЖНО: При создании класса поставщика обязательно ставить галочку «Добавить подстановочный знак в конце (*)», поскольку перечислить всевозможные классы почти невозможно, каждый производитель может добавлять свой класс, который вероятнее всего есть в статье

Добавляем во вкладке «Параметры» 66, 67 и 60-ые правила:

Правило 66

Правило 66
правило 67

правило 67
правило 60

правило 60

Правило 60 пустое, поскольку, мы его укажем в политике класса поставщика, а именно «PXEClient:BIOS(14)» (например), но включить его обязательно

В UEFI политике всё тоже самое, за исключением номеров классов поставщиков:

классы поставщиков UEFI

классы поставщиков UEFI

КРАЙНЕ ВАЖНО: При создании класса поставщика обязательно ставить галочку «Добавить подстановочный знак в конце (*)», поскольку перечислить всевозможные классы почти невозможно, каждый производитель может добавлять свой класс, который вероятнее всего есть в статье

Сами классы поставщика настраиваются, если нажать правой кнопкой мыши по ipv4 и нажать «Определить классы поставщиков…»:

классы поставщиков

классы поставщиков

Внутри данной области буфер обмена не работает, а заполняется только поле ASCII руками:

пример готового класса поставщиков

пример готового класса поставщиков

После чего, DHCP сервер в работе больше не участвует, передавая всю работу ipxe-серверу

Первичная настройка и TFTP

После первичной загрузки Linux обязательно сделать стандартные команды по обновлению библиотек в Linux:

sudo apt install -y && sudo apt upgrade -y

Начнём с настройки и установки TFTP, суть в том, что он будет отдавать .ipxe файл и передавать управление загрузчиком самому ipxe, больше через него ничего кроме .ipxe передаваться не будет, поскольку протокол очень медленный
Вводим команду для установки tftp:

sudo apt install tftpd-hpa -y

Настройка у tftp минимальная, поэтому сразу же и сделаем её:

sudo nano /etc/default/tftpd-hpa

И вносим туда 4 строчки:

TFTP_USERNAME="tftp" #пользователь для авторизацииTFTP_DIRECTORY="/srv/tftp" # папка, где будут лежать передаваемые с помощью tftp файлыTFTP_ADDRESS=":69" #слушать все сетевые интерфейсы по порту 69 (порт по умолчанию)TFTP_OPTIONS="--secure" #режим безопасности

HTTP-сервер

Так как tftp будет передавать только .ipxe файлы (из-за скорости протокола), то для передачи больших файлов таких как установщик Linux или WinPE будем использовать http-сервер, в моём случае это Apache2 (вы можете использовать любой другой, к примеру nginx), установим http-сервер:

sudo apt install apache2

Убедимся в наличии строк в конфиг файле откуда разрешать скачивание файлов по 80 порту, открываем файл:

sudo nano /etc/apache2/apache2.conf

Ищем эти строки: (если нету, добавьте)

<Directory /var/www/>        Options Indexes FollowSymLinks        AllowOverride None        Require all granted</Directory>

Остальные строчки можно оставить по умолчанию, либо настроить под себя используя документацию вашего http сервера

iPXE

Для сборки ipxe используется официальный дистрибутив с гитхаба, поэтому сразу скачаем и подготовим как для Legacy файл undionly.kkpxe так и для UEFI файл ipxe.efi, именно эти два файла будут отдаваться 67-ым правилом DHCP сервера, выполним поочерёдно ряд команд:

sudo apt install git -y #доустановим, если нетуsudo git clone https://github.com/ipxe/ipxe.gitcd ipxe/src #переходим в директорию ipxesudo nano start.ipxe #создадим файл с расширением .ipxe, назвать файл можете как хотите

в файл start.ipxe добавить строчки:

#!ipxedhcpchain tftp://ip-адрес вашего ipxe-сервера/boot.ipxe

Обратите внимание, что все скрипты для ipxe начинаются с #!ipxe, данный файл отдаёт загрузчик boot.ipxe, в котором можно настроить параметры под себя, указать переменные в ip адреса (об этом ниже), добавить цвет текста, обводки, выделения, а также возможность добавить фоновую картинку и т.д. С полным списком возможностей можете ознакомиться здесь
p.s: мы у себя оставили всё по умолчанию, поскольку добавление фонового изображения полностью ломало графику загрузчика из-за разного разрешения экрана на мониторах и поправить эту проблемы мы не смогли

Прежде чем перейдём к созданию меню загрузчика ipxe, сначала скомпилируем два файла ipxe.efi и undionly.kkpxe
У меня .kpxe ни на одной BIOS машине не завёлся, поэтому .kkpxe, в чём отличие каждого файла загрузчика вы можете посмотреть здесь
Вводим команды:

sudo make bin-x86_64-efi/ipxe.efi EMBED=start.ipxe #Для UEFIsudo make bin-i386-pcbios/undionly.kkpxe EMBED=start.ipxe #Для BIOS

Сами загрузчики boot.ipxe, menu.ipxe будут отдаваться с помощью tftp сервера, поэтому, после завершения компиляции переносим файлы ipxe.efi и undionly.kkpxe в директорию tftp созданную ранее:

cp bin-x86_64-efi/ipxe.efi /srv/tftp/cp bin-i386-pcbios/undionly.kkpxe /srv/tftp/

С помощью программы mc или с помощью команды cd переходим в директорию

cd /srv/tftp/

ВАЖНО! При создании файлов ipxe.efi и undionly.kkpxe они компилируются, поэтому если у вас поменяется ip-адрес ipxe сервера или название файла, нужно будет перекомпилировать файлы командами выше повторно!

После компилирования и переноса файлов, создаём в директории /srv/tftp два файла, первый с названием boot.ipxe:

sudo nano boot.ipxe

Моё содержимое boot.ipxe (ваше может сильно отличаться):

#!ipxe# Глобальные параметрыset httpServer http://10.50.50.50:80 # Задание адреса HTTP сервераset ${next-server} 10.50.50.50:80 # Задание адреса# Переход к файлу с основным меню:nextchain --replace --autofree menu.ipxe

Второй файл menu.ipxe, заметьте, что на него направляет boot.ipxe в 8 строчке выше, файл menu.ipxe и будет тем меню, в котором можно выбирать пункты меню для загрузки, общий вид файла menu.ipxe:

menu.ipxe
#!ipxe######## Главное меню ########set url    http://${next-server}/set srvip  ${net0/next-server}set netX/next-server 10.50.50.51set root_path /pxebootset server_ip 10.50.50.50menuitem exit                 Exit iPXE and continue BIOS bootitem --gap -- ----------- iPXE Install Menu ---------------item veeam                   Veeam Recovery Media (UEFI)item strelec_uefi            WinPE Strelec (UEFI)item strelec_legacy          WinPE Strelec (LEGACY)item memtest                 Memtestitem --gap -- ----------- Antivirus -----------------------item krd                     Kaspersky Remote Diskitem --gap -- ------------Windows Installer ------------------item win10                   Windows 10 installeritem --gap -- ----------- Linux Installer ------------------item ubuntu     Ubuntu Installer 24item ubuntua                 Ubuntu Installer 24 (AUTOINSTALL)item ubuntuserver            Ubuntu Server Installer 24item debian     Debian Netinstallitem --gap -- -------------------------------------------------choose target && goto ${target}item --gap -- -------- iPXE Utilites --------item -k c config Start interactive (c)onfiguration toolitem -k s shell Start (S)hell iPXEchoose -d exit -t ${menu-timeout} selectedgoto ${selected}:veeamsanboot ${httpServer}/images/veem/Veeam.iso || goto error:strelec_uefisanboot --drive 0xe0  ${httpServer}/images/strelecuefi/strelec.iso || goto error:strelec_legacyimgfreekernel ${httpServer}/images/strelec/wimboot guiinitrd -n BCD       ${httpServer}/images/strelec/boot/BCD       BCDinitrd -n boot.sdi  ${httpServer}/images/strelec/boot/boot.sdi  boot.sdiinitrd -n BOOTMGR ${httpServer}/images/strelec/BOOTMGR BOOTMGRinitrd -n strelec10x64.wim  ${httpServer}/images/strelec/sources/strelec10x64.wim strelec10x64.wimimgstatboot || goto error:memtestsanboot ${httpServer}/images/memtest/memtest.iso || goto failed:krdkernel ${httpServer}/images/krd/live/vmlinuz || goto errorinitrd ${httpServer}/images/krd/live/initrd.img || goto errorimgargs vmlinuz initrd=initrd boot=live components locales=ru_RU.UTF-8 netboot=nfs nfsroot=${server_ip}:${root_path}/krd || goto errorboot:ubuntuset os_root ubuntu24kernel   ${httpServer}/images/ubuntu24/vmlinuz initrd   ${httpServer}/images/ubuntu24/initrd || goto errorimgargs vmlinuz initrd=initrd ip=dhcp boot=casper netboot=nfs nfsroot=${server_ip}:${root_path}/${os_root} || goto errorboot:ubuntuaset os_root ubuntu24kernel ${httpServer}/images/ubuntu24/vmlinuz || goto errorinitrd ${httpServer}/images/ubuntu24/initrd || goto errorimgargs vmlinuz initrd=initrd netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/${os_root} systemd.mask=systemd-networkd-wait-online.service \    systemd.mask=NetworkManager-wait-online.service \    network-config=disabled \ autoinstall ds=nocloud-net;s=http://10.50.50.50/images/ubuntu24/autoinstall/ || goto errorboot:ubuntuserverset os_root ubuntuserver24kernel   ${httpServer}/images/ubuntuserver24/vmlinuz  || goto errorinitrd   ${httpServer}/images/ubuntuserver24/initrd || goto errorimgargs vmlinuz initrd=initrd root=/dev/nfs netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/${os_root} || goto errorboot:debianos_root debian13kernel ${httpServer}/images/debian13/install.amd/vmlinuz || goto errorinitrd ${httpServer}/images/debian13/install.amd/initrd.gz || goto errorboot:win10imgexec tftp://${netX/next-server}/boot/x64/wdsmgfw.efi || goto errorboot || goto failed:exitecho Boot from disk...sleep 2exit# При ошибках выход на командную строку:errorecho Failed - have errorsleep 1goto shell

Как видно по содержимому файла, в каждом пункте кроме Windows 10 installer используется http протокол, так как он работает быстрее и стабильнее tftp, а sanboot работает только в UEFI

Структура и смысл файла крайне прост, в самом верху, после #!ipxe задаются переменные, вы можете задать их в boot.ipxe, но так как menu.ipxe вы будете редактировать чаще, удобнее задать переменные здесь
Дальше настраивается структура меню, через item, принцип создания меню идёт как
item — название — выводимый текст:

menuitem exit                 Exit iPXE and continue BIOS bootitem --gap -- ----------- iPXE Install Menu ---------------item veeam                   Veeam Recovery Media (UEFI)

А уже под структурой меню выдаётся что и как грузить:

:veeamsanboot ${httpServer}/images/veem/Veeam.iso || goto error

Veeam

На примере загрузки veeam-а, через sanboot грузится Veeam.iso из директории http сервера — ${httpServer}/images/veem/ физически на сервере все директории лежат по пути: /var/www/html/images/
ВАЖНО! Директории images в /var/www/html/images/ у вас может не быть, поэтому командой mkdir вы можете её создать
как видим, если выбрать veeam и загрузиться, то всё работает корректно:

veeam.iso

veeam.iso

Так как мы подключили его через sanboot, то загрузился не весь Veeam, а только самое необходимое, поэтому в пункте Bare Metal Recovery нам доступен только Network Stage

С Veeam всё, идём дальше

Strelec WinPE UEFI

Как не трудно догадаться, через: item —gap – ———— iPXE Install Menu —————
выводится текстовое поле без права его выбрать, для визуального отделения от остальных пунктов меню по их логике, антивирусы в антивирусы, Linux в Linux и т.д.

Следующим пунктом добавим Strelec WinPE для UEFI с помощью загрузки .iso образа напрямую как и с Veeam, но из-за принципа работы sanboot, он не грузит по сети все 5гб, а только самое необходимое для загрузки, из-за чего диск и Minst папка со всем необходимым софтом strelec не будут загружены, даже если мы явно через аргумент —filename укажем, что грузить, частично это можно обойти если указать аргумент —drive 0xA0, тогда он будет работать как CD-ROM, но данный метод нас не устраивает, поскольку это долго и это 5гб по сети в ОЗУ, поэтому грузить будем командой:

:strelec_uefisanboot --drive 0xe0  ${httpServer}/images/strelecuefi/strelec.iso || goto error

А уже после загрузки через WinPE, модифицировав .wim файл добавим в автозагрузку скрипт, который загрузит и примонтирует необходимые нам диски, но прежде чем модифицировать .wim скриптом, создадим то, что нужно примонтировать и запустить, для этого установим и настроим samba-сервер и TAG

TGT и SAMBA

Сделаем две последовательных команды:

sudo apt install tgt -y #iscsi таргетsudo apt install samba -y #samba сервер

По порядку, что и зачем нужно:
Отмечу, что TGT выбран из-за простоты и удобства настройки
TGT будет выступать в роли iscsi таргета, который будет подключать «физический» диск strelec по сети, из удобств такого метода это возможность в любой момент модифицировать данный iscsi диск, подключив его к windows с помощью инициатора iscsi поэтому перейдём к его настройке:

sudo nano /etc/tgt/targets.conf

Данный файл можете полностью очистить, нам нужно добавить лишь 5 строк:

include /etc/tgt/conf.d/*.conf #где искать конфиг<target iqn.2026-02.local.dom.ipxe:strelec> #название iscsi диска (КРИТИЧНО!)    backing-store /disk2/strelec.img #где физически лежит диск на сервере    incominguser iscsi iscsi #логин и пароль (задайте любой) для подключения iscsi (не обязательно)</target>

Почему название iscsi диска именно iqn.2026-02.local.dom.ipxe:strelec и почему это так критично:
iscsi диск имеет свою логику в названии, которое идёт так: iqn.год-месяц.домен компьютера:название, часть после двоеточия можете уже называть свободно
Как мы видим, в директории disk2/ лежит strelec.img, создадим его с помощью нескольких команд:

mkdir /disk2/strelec #создаём каталог strelec в директории /disk2touch /disk2/strelec/strelec.img #создаём пустой файл образа с расширением .imgtruncate -s 6G /disk2/strelec/strelec.img #выдаём размер файла strelec.img 6 Гбsudo systemctl restart tgt #перезапускаем службу tgt

На самом деле strelec.img вы можете создавать где угодно, просто затем нацельте на него tgt в третьей строчке файла targets.conf и после любых изменений перезапускайте службу

После перезапуска службы tgt проще всего будет настроить образ на windows, поэтому запускаем инициатор iscsi в ОС Windows и подключаем наш диск по ip адресу Linux ipxe сервера в поле «Объект» вводите ip адрес и нажав «Быстрое подключение» находите там ваш iscsi диск:

iscsi

iscsi

ВАЖНО! Если вы поставили пароль в 4 строчке файла targets.conf, не забудьте ввести его в «Разрешить вход CHAP» во вкладке «дополнительно»
После подключения iscsi в управлении дисками появится новый неинициализированный диск в статусе «не в сети». ОС Windows автоматически предложит создать новый том и задать диску букву, на этом моменте заострять внимание не буду, поскольку можно оставить настройки по умолчанию.
Дальше скачиваете любой готовый WinPE .iso образ, я же буду проводить дальнейшую работу на примере strelec 2021 (можно новее, не принципиально, методика одна)
После скачивания WinPE образа лучше отключить антивирус, поскольку strelec как и любая другая готовая WinPE сборка с софтом всеми антивирусами считается вредоносной из-за различного ПО по типу сброса паролей администраторов или killprocess и т.д. и просто переносим содержимое образа в корень нового диска, получится нечто подобное:

содержимое iscsi-диска

содержимое iscsi-диска

На этом с iscsi и tgt всё

Переходим к SAMBA-серверу:

Если вы планируете через WinPE разворачивать бекапы или делать их, то в данном случае лучше воспользоваться протоколом samba, который также как и iscsi диск будет подключаться в момент загрузки, установим samba-сервер:

sudo apt install samba -y #установка samba

Сразу же настроим:

sudo nano /etc/samba/smb.conf

В данном файле закомментируйте всё (или очистите его), и в самый низ списка добавьте строчки:

[global]workgroup = WORKGROUPserver string = Samba Server %vserver role = standalone serverserver min protocol = SMB2_10client max protocol = SMB3client min protocol = SMB2_10encrypt passwords = truerestrict anonymous = 2netbios name = vud-serversecurity = usermap to guest = nevermax log size = 1000usershare allow guests = Yesdos charset = 866unix charset = utf8lanman auth = yesntlm auth = yes[obraz_ro]comment = ropath = /disk2/obraz_ropublic = yeswritable = yesread only = noguest ok = yescreate mask = 0775directory mask = 0775force create mode = 0775force directory mode = 0775[obraz_rw]comment = rwpath = /disk2/obraz_rwpublic = nowritable = yesread only = yesguest ok = novalid users = pxe, samba #имя пользователя кому можно подключаться по smbwrite list = sambacreate mask = 0775directory mask = 0775force create mode = 0775force directory mode = 0775inherit owner = yes

В данном конфиге мы отдаём по протоколу samba две папки, obraz_rw и obraz_ro, как не сложно догадаться, одна на чтение, вторая на запись, идея в том, что образы и бекап-файлы будут лежать в ro (поскольку акронису чтения достаточно), а в rw будем заливать бекап клиентской машины, которая загрузилась по ipxe

С SAMBA всё, идём дальше

Модификация wim

Дальше нам необходимо вшить в образ свой скрипт для монтирования iscsi и samba в момент загрузки образа по ipxe, поскольку sanboot его сам не загрузит
Открываем .iso образ с помощью UltraISO или просто распаковываем его в папку (можно даже на сам iscsi диск), и в папке SSTR лежат .wim образы, которые и являются ОС WinPE при загрузке. Находим там strelec10x64.wim и открываем его с помощью того же UltraISO или 7zip, по структуре папок вы заметите, что это обычная ОС, идём по пути: Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\ (если в вашем образе нет Programs\Startup — просто создайте эти две папки) и создаём в ней обычный .bat скрипт, я назвал его start ISCSI.bat, его содержимое:

#пинг является "паузой" для ожиданияping 127.0.0.1 -n 2 #стартуем службу iscsi (по умолчанию она выключена)sc start MSiSCSI #снова ждёмping 127.0.0.1 -n 5#нацеливаем "таргетируем" iscsiiscsicli QAddTarget iqn.2026-02.local.dom.ipxe:strelec 10.50.50.50ping 127.0.0.1 -n 5#подключаем "монтируем" диск в системеiscsicli QLoginTarget iqn.2026-02.local.dom.ipxe:strelec iscsi iscsi#последняя паузаping 127.0.0.1 -n 5#так как нам неизвестно какой буквой будет диск, #стартуем ПО MInstlink, у strelec она по умолчанию лежит в system32 #%windir% - является "поиском windows директории"cmd.exe /c "%windir%\system32\MInstLink.exe#перед подключением SAMBA попингуем машину, на которой она настроенаping 10.50.50.50 -n 3 #подключаем папку как сетевой диск Knet use K: \\10.50.50.50\obraz_ro /user:Логин и пароль пользователя у которого есть доступ к папке# паузаping 10.50.50.50 -n 3#подключаем папку как сетевой диск Nnet use N: \\10.50.50.50\obraz_rw /user:Логин и пароль пользователя у которого есть доступ к папке

Пауза между действиями нужна, поскольку запуск службы или таргет на iscsi могут не успеть отработать, а мы уже пытаемся авторизоваться.
Последнее, что можно сделать, это в месте где вы распаковали iso образ запустить ПО MInst.exe, которое находится в SSTR\MInst и добавить VNC в автозапуск (нужно, если планируете управлять WinPE удалённо через DameWare или VNC на Windows. На официальном сайте strelec есть инструкция как туда добавлять свой софт

В данном этапе от iso образа больше ничего не нужно, сохраняем новый .wim с таким же названием и через UltraISO копируем .wim в SSTR с заменой, после чего копируем ваш .iso образ в директорию Linux, проще всего это сделать через команду sc в cmd или WinSCPPortable и добавляем его на http-сервер Linux по пути /var/www/html/images, чтобы не плодить здесь неразбериху, создаём директорию для каждого софта отдельно, поэтому в /var/www/html/images я создал директорию strelecuefi и перенёс в неё .iso образ menu.ipxe добавим строчки:

:strelec_uefisanboot --drive 0xe0  ${httpServer}/images/strelecuefi/strelec.iso || goto error

Если всё правильно, то при загрузке ipxe в меню будет пункт WinPE Strelec (UEFI), выбрав его загрузится WinPE образ и в shell:startup мы увидим наш скрипт, который автоматически отработает
Ниже я покажу два скриншота, без скрипта и после скрипта:

загрузка sanboot без скрипта

загрузка sanboot без скрипта
загрузка sanboot со скриптом

загрузка sanboot со скриптом

Как видно по скриншотам, запустился и определился весь софт и даже VNC (справа снизу в трее)

Strelec WinPE LEGACY

И если с UEFI WinPE на этом всё, то с Legacy так просто не выйдет
memdisk нас не устраивает, потому что WinPE образ может весить 5-6 гб, и столько ОЗУ в Legacy компьютерах может не быть
а sanboot не умеет грузиться в Legacy, поэтому воспользуемся wimboot-ом, стандартным загрузчиком windows, скачиваем его с гитхаба:

wget https://github.com/ipxe/wimboot/releases/download/v2.9.0/wimboot

И переносим его в директорию http-сервера по пути /var/www/images/strelec

в menu.ipxe добавляем:

:strelec_legacyimgfreekernel ${httpServer}/images/strelec/wimboot guiinitrd -n BCD       ${httpServer}/images/strelec/boot/BCD       BCDinitrd -n boot.sdi  ${httpServer}/images/strelec/boot/boot.sdi  boot.sdiinitrd -n BOOTMGR ${httpServer}/images/strelec/BOOTMGR BOOTMGRinitrd -n strelec10x64.wim  ${httpServer}/images/strelec/sources/strelec10x64.wim strelec10x64.wimimgstatboot || goto error

Возвращаемся в папку, где мы распаковали iso образ и модифицировали .wim образ и приводим её к следующему виду:

содержимое образа для legacy

содержимое образа для legacy

Использовать стандартные пути SSTR мы не можем, поскольку в wimboot нет SSTR и там используются стандартные boot и sources пути
Как видно в menu.ipxe, BCD и boot.sdi запускаются из папки boot, можете их перенести из SSTR в boot, а strelec10x64.wim запускается из sources, поэтому переименовываем SSTR в sources

!КРИТИЧНО ВАЖНО! регистр для Linux и wimboot важен, поэтому если вы назвали файл BOOTMGR, а в menu.ipxe написали bootmgr ipxe выдаст ошибку «File not found» регистр директорий также критично важен!

Теперь нам необходимо модифицировать BCD, запускаем cmd от имени администратора и последовательно вводим команды:

set BCDSTORE=C:\1\pxe\Strelec\boot\BCD (у вас свой путь к папке boot в корне куда распаковали iso)#Исправляем путь к boot.sdibcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdidevice bootbcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdipath \boot\boot.sdi#Исправляем пути к wimbcdedit /store %BCDSTORE% /set {default} device   ramdisk=[boot]\sources\strelec10x64.wim,{ramdiskoptions}bcdedit /store %BCDSTORE% /set {default} osdevice ramdisk=[boot]\sources\strelec10x64.wim,{ramdiskoptions}

p.s одной модификации может не хватить, поскольку загрузчик может ссылаться или искать файлы шрифтов или другие .wim образы, их желательно очистить по аналогии:

Дополнительная очистка BCD, если способ выше всё равно падает в ошибку \SSTR\BCD
set BCDSTORE=C:\1\pxe\Strelec\boot\BCD (у вас свой путь к папке boot в корне куда распаковали iso)#Узнаём GUID вашего образаbcdedit /store %BCDSTORE% /create /d "Strelec Win10 x64" /application osloader#копируем GUID и заменяем его вместо {GUID}, с фигурными скобками#Вычищаем BCDbcdedit /store %BCDSTORE% /set {GUID} device   ramdisk=[boot]\SSTR\strelec10x64.wim,{ramdiskoptions}bcdedit /store %BCDSTORE% /set {GUID} osdevice ramdisk=[boot]\SSTR\strelec10x64.wim,{ramdiskoptions}bcdedit /store %BCDSTORE% /set {GUID} path     \windows\system32\boot\winload.exebcdedit /store %BCDSTORE% /set {GUID} systemroot \windowsbcdedit /store %BCDSTORE% /set {GUID} detecthal Yesbcdedit /store %BCDSTORE% /set {GUID} winpe Yesbcdedit /store %BCDSTORE% /set {GUID} nointegritychecks Yesbcdedit /store %BCDSTORE% /set {GUID} testsigning Yesbcdedit /store %BCDSTORE% /set {GUID} nx AlwaysOff#Удаляем strelec10 x86bcdedit /store %BCDSTORE% /delete {GUID} /f#Удаляем strelec8 x86bcdedit /store %BCDSTORE% /delete {GUID} /f#Удаляем strelec8NE x86bcdedit /store %BCDSTORE% /delete {GUID} /f#Обновляем displayorder - только x64bcdedit /store %BCDSTORE% /displayorder {default}#Меню смысла нет показывать если запись однаbcdedit /store %BCDSTORE% /set {bootmgr} displaybootmenu No#Удаляем шрифтыbcdedit /store %BCDSTORE% /deletevalue {globalsettings} fontpath

Останется только в корне образа заменить bootmgr, взять его можете из любого iso образа установщика windows 10

Снова через UltraISO создаём iso образ и копируем его на Linux ipxe-сервер, по пути /var/www/images/strelec и распаковываем его там:

sudo 7z x strelec.iso -y #распаковать iso

После чего iso образ нам не нужен, удаляем его. В итоге получится следующий вид:

содержимое каталога strelec для загрузки по legacy

содержимое каталога strelec для загрузки по legacy

На этом настройка Legacy завершена, при загрузке через ipxe и выборе пункта меню WinPE Strelec (LEGACY) вы получите ту же картину, что и при UEFI с автоматическим запуском скрипта, VNC и монтировании iscsi диска

Kaspersky Remote Disk

Перейдём к Kaspersky Remote Disk и скрипт с автоматическим обновлением/актуализацией дистрибутива раз в неделю

Так как касперский часто обновляет свои базы вирусов, нужно как можно чаще держать его в актуальном состоянии, руками делать подобное нам не подходит, поэтому к нам на помощь приходит планировщик задач Linux — crontab, в Ubuntu 24.04.4 он уже установлен и готов к работе, так как у crontab своя логика и своё понимание когда и что отрабатывать, в сети есть калькулятор crontab, но обо всём по порядку

Внесём в menu.ipxe следующие строки:

:krdkernel ${httpServer}/images/krd/live/vmlinuz || goto errorinitrd ${httpServer}/images/krd/live/initrd.img || goto errorimgargs vmlinuz initrd=initrd boot=live components locales=ru_RU.UTF-8 netboot=nfs nfsroot=${server_ip}:${root_path}/krd || goto errorboot

iso образ касперского это Linux, а ipxe изначально создавался под загрузку Linux по сети, поэтому добавлять Linux системы в ipxe довольно просто, нужен лишь NFS и объяснить что откуда и как грузить

Скачиваем с официального сайта Kaspersky Remote Disk и распаковываем образ в /var/www/html/images/krd и оставляем только 2 файла в каталоге live, vmlinuz и initrd.img, остальное можно удалить, поскольку после выдачи ядра и системы остальное (диск и базы данных) мы будем отдавать через nfs, поэтому его и установим и настроим:

sudo apt install nfs-kernel-server #установить nfs-серверsudo nano /etc/exports #переходим к настройке nfs

В файле /etc/exports можно закомментировать или очистить всё и добавляем строчку:

/pxeboot *(ro,sync,no_wdelay,insecure_locks,no_root_squash,insecure,no_subtree_check)

Что делает строчка:

/pxeboot — Папка на которую нацелен nfs (создаётся в корне каталога /, название какое хотите)
* — Разрешить подключение с любого IP-адреса (лучше завернуть в ip адрес вашей сети с маской)
ro — Read-only — только чтение, запись запрещена
sync — Запись на диск синхронно — данные сбрасываются сразу
no_wdelay — Не задерживать запись в ожидании групповых операций
insecure_locks — Не требовать аутентификацию для блокировок файлов
no_root_squash — root на клиенте = root на сервере — не понижать права root
insecure — Разрешить подключения с портов выше 1024 (не только привилегированных)
no_subtree_check — Не проверять что запрашиваемый файл находится внутри экспортируемого дерева

Это вся настройка nfs которая необходима, теперь переходим в корень /pxeboot и создав директорию krd переносим в неё наш iso образ Kaspersky Remote Disk и распаковываем:

sudo 7z x krd.iso 

После чего сам iso образ удаляем, а структуру оставляем как есть, получится нечто такое:

содержимое каталога krd

содержимое каталога krd

На этом настройка Kaspersky Remote Disk завершена, и при выборе в ipxe Kaspersky Remote Disk автоматически загрузится и дойдёт до рабочего стола, работает как в Legacy так и в UEFI:

krd через ipxe

krd через ipxe

Как видите диск касперского подключён и никаких дополнительных скриптов для подключения диска или монтирования iscsi как было с sanboot в strelec нам не нужно, всё работает благодаря nfs

Поэтому, перейдём к настройке скрипта, который будет автоматически скачивать iso образ с официального сайта раз в неделю, копировать образ в определённую папку, распаковывать его, удалять iso образ из папки после завершения и писать лог в /var/log, для этого создадим где вам удобно папку script и сам скрипт, я это сделаю в /pxeboot/script:

sudo nano /pxeboot/script/install.krd.sh 

Содержимое файла install.krd.sh:

#!/bin/bashISO_URL="https://rescuedisk.s.kaspersky-labs.com/latest/krd.iso"ISO_FILE="krd.iso"EXTRACT_DIR="/pxeboot/krd"# Загрузкаecho "Загружаю ISO..."wget -O "$ISO_FILE" "$ISO_URL"if [ $? -ne 0 ]; then    echo "Ошибка загрузки"    exit 1fi# Распаковка с помощью 7zecho "Распаковываю ISO..."7z x -y "$ISO_FILE" -o"$EXTRACT_DIR/"# Удаление ISOrm -f "$ISO_FILE"echo "Готово! Содержимое в: $EXTRACT_DIR"

Не забудьте сделать скрипт активным:

sudo chmod +x /pxeboot/scripts/install.krd.sh 

Последним пунктом останется добавить его в планировщик, вводим:

sudo crontab -e #редактировать crontab

И в самый низ списка добавляем строчки:

# Обновлять KRD каждый понедельник в 15 часов дня00 15 * * 1 /pxeboot/script/install_krd.sh > /var/log/install_krd.log 2>&1 

Теперь 1 раз в неделю в 15 часов дня будет срабатывать скрипт и записывать лог в /var/log/install_krd.log, своё время и свою дату вы можете взять из калькулятора crontab

WDS

На этом с Kaspersky Remote Disk закончено, перейдём к WDS

Если у вас есть сервер WDS, то подружить его с ipxe крайне просто, добавим в menu.ipxe строчки:

:win10imgexec tftp://${netX/next-server}/boot/x64/wdsmgfw.efi || goto errorboot || goto failed

Простота использования WDS в том, что при выборе пункта Windows 10 installer в ipxe, он просто передаёт управление к вашему WDS серверу и дальше всю работу на себя берёт WDS

Linux Ubuntu 24.04.4 autoinstall

Последнее, на чём хотелось бы акцентировать внимание в проекте, это автоматическую установку Linux Ubuntu 24.04.4 (с 25 версией тоже работает)
Добавим в menu.ipxe блок:

:ubuntuaset os_root ubuntu24kernel ${httpServer}/images/ubuntu24/vmlinuz || goto errorinitrd ${httpServer}/images/ubuntu24/initrd || goto errorimgargs vmlinuz initrd=initrd netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/${os_root} systemd.mask=systemd-networkd-wait-online.service \    systemd.mask=NetworkManager-wait-online.service \    network-config=disabled \ autoinstall ds=nocloud-net;s=http://10.50.50.50/images/ubuntu24/autoinstall/ || goto errorboot

В блоке остановлю своё внимание на пояснении только четырёх важнейших аспектах, поскольку остальные никак не отличаются от krd:

  1. systemd.mask=systemd-networkd-wait-online.service — отключить ожидание сети при старте

  2. systemd systemd.mask=NetworkManager-wait-online.service — отключить ожидание NetworkManager при старте

  3. systemd network-config=disabled — отключить cloud-init настройку сети

  4. autoinstall ds=nocloud-net;s=http://10.50.50.50/images/ubuntu24/autoinstall/ — путь, откуда Linux Ubuntu брать файл автоматической установки

Прежде чем углубиться в объяснение зачем мы отключаем NetworkManager и cloud-init, объясню структуру, файла автоматической установки, по пути /var/www//images/ubuntu24/autoinstall/ должны находиться два файла, первый meta-data, второй user-data
meta-data обязателен и может быть пустой, а вот user-data имеет язык YAML и должен соответствовать его синтаксису, посмотреть как создать файл автоответа можно на официальном сайте ubuntu
Вот моё содержимое файла автоматических ответов:

#cloud-config# =======================================================================# Ubuntu 24.04  :  полностью бездиалоговая установка# =======================================================================autoinstall:  version: 1                         # версия схемы cloud-init autoinstall  # -------------------------------------------------------------------  # Локализация: раскладка, часовой пояс  # -------------------------------------------------------------------  locale: ru_RU.UTF-8  keyboard: {layout: us}  timezone: Europe/Moscow  # -------------------------------------------------------------------  # Идентификация и сеть в интерактивном режиме  # -------------------------------------------------------------------  interactive-sections:    - network    - identity  # -------------------------------------------------------------------  # Подключаемся к репризиторию Ubuntu   # -------------------------------------------------------------------  apt:    preserve_sources_list: false    mirror-selection:      primary:        - country-mirror        - uri: "http://ru.archive.ubuntu.com"          arches: [i386, amd64]    fallback: abort    geoip: true  # -------------------------------------------------------------------  # РАЗМЕТКА ДИСКА: берём всё под корневой раздел (direct layout)  # -------------------------------------------------------------------  storage:    layout:      name: direct      sizing-policy: all             # весь диск без ручных диалогов  # -------------------------------------------------------------------  # ИДЕНТИФИКАЦИЯ: имя ПК, пользователь, пароль  # -------------------------------------------------------------------  identity:    hostname: test9    username: user    realname: user          # (по умолчанию = username)    password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'    # Пароль: "321" (ОБЯЗАТЕЛЬНО СМЕНИТЕ ПОСЛЕ УСТАНОВКИ (можно puppet-ом)      # -------------------------------------------------------------------  user-data:    runcmd:      # Ждём реального DHCP-ответа (спейсер)      - |        until ping -c1 -W1 8.8.8.8 >/dev/null 2>&1; do          echo "Waiting for DHCP…" && sleep 2        done  # -------------------------------------------------------------------  # Команды после окончания установки, но до перезагрузки ОС  # -------------------------------------------------------------------            late-commands:    - curtin in-target -- apt-get update && apt-get upgrade -y    - curtin in-target -- apt-get install -y puppet    - curtin in-target -- apt-get install -y puppet-agent    - curtin in-target -- apt-get install -y mc    - curtin in-target -- apt-get install -y gparted    - curtin in-target -- apt-get install -y ssh    - curtin in-target -- apt-get install -y python3    - curtin in-target -- apt-get install -y winpr-utils    - sudo bash -c 'printf "server = puppet.dom.local\nshow_diff = true\n" > /target/etc/puppet/puppet.conf'    - curtin in-target -- systemctl enable puppet    - sudo reboot

Как видно по коду файла, интерактивными мы оставили network и identity, остальное полностью автоматизировано, зачем это сделано?
Так как в нашей инфраструктуре есть развёрнутый сервер puppet, который имеет агентское приложение, то ссылается он на название ПК, поэтому лучше указывать его имя уникально для каждого клиента, если у вас нет необходимости в puppet, то identity можно удалить из интерактивного режима
Однако, network удалить из интерактивного режима не выйдет, поскольку в момент автоматической установки, система доходит до настроек network, даже если вы там впишите ipv4: dhcp, то в моменте система уронит все сетевые интерфейсы и намертво зависнет установка ОС, победить эту проблему без интерактивного режима не получилось, возможно это баг самой ОС Ubuntu
Остальные шаги прокомментированы в файле, поэтому на них подробно останавливаться не буду

На данном этапе, если выбрать пункт меню Ubuntu Installer 24 (AUTOINSTALL) в ipxe, то после загрузки ОС нужно будет лишь трижды нажать «Next», скриншоты ниже:

network в интерактивном режиме

network в интерактивном режиме
identity в интерактивном режиме

identity в интерактивном режиме

Как видите, в user-data прописано:

  identity:    hostname: test9    username: user    realname: user          # (по умолчанию = username)    password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'    # Пароль: "321" (ОБЯЗАТЕЛЬНО СМЕНИТЕ ПОСЛЕ УСТАНОВКИ (можно puppet-ом)

Всё, кроме пароля система заполнила

Подтверждение установки

Подтверждение установки

После чего система сама установит весь софт с помощью после-установочных скриптов:

  late-commands:    - curtin in-target -- apt-get update && apt-get upgrade -y    - curtin in-target -- apt-get install -y puppet    - curtin in-target -- apt-get install -y puppet-agent    - curtin in-target -- apt-get install -y mc    - curtin in-target -- apt-get install -y gparted    - curtin in-target -- apt-get install -y ssh    - curtin in-target -- apt-get install -y python3    - curtin in-target -- apt-get install -y winpr-utils    - sudo bash -c 'printf "server = puppet.dom.local\nshow_diff = true\n" > /target/etc/puppet/puppet.conf'    - curtin in-target -- systemctl enable puppet    - sudo reboot

Можно добавить любой софт или скрипт/текст-в-файл по аналогии, в конце команда sudo reboot, для перезагрузки, поскольку мне известно о существовании shutdown: reboot в user-data синтаксисе, но он по неизвестной мне причине не сработал
КРАЙНЕ ВАЖНО, у YAML имеется свой синтаксис и он зависит от пробелов с первого символа

Что будет, если в menu.ipxe не добавить строчки:

systemd.mask=systemd-networkd-wait-online.service
systemd systemd.mask=NetworkManager-wait-online.service systemd
network-config=disabled

Данными командами мы насильно отключаем NetworkManager и cloud-init, если их оставить, то при загрузке ОС, nfs соединение будет разрываться и ОС будет уходить в Kernel Panic и попросту зависать, поскольку будет бесконечно ожидать поднятие одного из демонов, NetworkManager или cloud-init, но никогда их не поднимет, ведь nfs соединение разорвано и остались лишь файлы в ОЗУ установки

результат установки

результат установки

На данном этапе полная настройка ipxe сервера завершена, остальные ОС можно добавлять по аналогии с krd или по аналогии с ubuntu

Итоги

Настроенный и поднятый сервер предназначен для ускорения и упрощения работы с установкой, диагностикой и обслуживанием ОС, в том числе автоматической установкой Ubuntu и возможностью снимать и развёртывать бекапы различных систем по сети, данный сервер работает быстрее обычной флешки, поскольку ограничен лишь скоростью накопителей и сетевой пропускной способностью

ссылка на оригинал статьи https://habr.com/ru/articles/1037416/