Для начала определимся, что такое 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.git
cd ipxe/src #переходим в директорию ipxe
sudo nano start.ipxe #создадим файл с расширением .ipxe, назвать файл можете как хотите

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

#!ipxe

dhcp
chain 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 #Для UEFI
sudo 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 сервера или название файла, то нужно будет внести новый ip-адрес в файл start.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 # Задание адреса

# Переход к файлу с основным меню
:next
chain --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.51
set root_path /pxeboot
set server_ip 10.50.50.50

menu
item exit                 Exit iPXE and continue BIOS boot
item --gap -- ----------- iPXE Install Menu ---------------
item veeam                   Veeam Recovery Media (UEFI)
item strelec_uefi            WinPE Strelec (UEFI)
item strelec_legacy          WinPE Strelec (LEGACY)
item memtest                 Memtest
item --gap -- ----------- Antivirus -----------------------
item krd                     Kaspersky Remote Disk
item --gap -- ------------Windows Installer ------------------
item win10                   Windows 10 installer
item --gap -- ----------- Linux Installer ------------------
item ubuntu		     Ubuntu Installer 24
item ubuntua                 Ubuntu Installer 24 (AUTOINSTALL)
item ubuntuserver            Ubuntu Server Installer 24
item debian		     Debian Netinstall
item --gap -- -------------------------------------------------
choose target && goto ${target}
item --gap -- -------- iPXE Utilites --------
item -k c config Start interactive (c)onfiguration tool
item -k s shell Start (S)hell iPXE

choose -d exit -t ${menu-timeout} selected
goto ${selected}

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

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

:strelec_legacy
imgfree
kernel ${httpServer}/images/strelec/wimboot gui
initrd -n BCD       ${httpServer}/images/strelec/boot/BCD       BCD
initrd -n boot.sdi  ${httpServer}/images/strelec/boot/boot.sdi  boot.sdi
initrd -n BOOTMGR ${httpServer}/images/strelec/BOOTMGR BOOTMGR
initrd -n strelec10x64.wim  ${httpServer}/images/strelec/sources/strelec10x64.wim strelec10x64.wim
imgstat
boot || goto error

:memtest
sanboot ${httpServer}/images/memtest/memtest.iso || goto failed

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

:ubuntu
set os_root ubuntu24
kernel   ${httpServer}/images/ubuntu24/vmlinuz 
initrd   ${httpServer}/images/ubuntu24/initrd || goto error
imgargs vmlinuz initrd=initrd ip=dhcp boot=casper netboot=nfs nfsroot=${server_ip}:${root_path}/${os_root} || goto error
boot

:ubuntua
set os_root ubuntu24
kernel ${httpServer}/images/ubuntu24/vmlinuz || goto error
initrd ${httpServer}/images/ubuntu24/initrd || goto error
imgargs 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 error
boot

:ubuntuserver
set os_root ubuntuserver24
kernel   ${httpServer}/images/ubuntuserver24/vmlinuz  || goto error
initrd   ${httpServer}/images/ubuntuserver24/initrd || goto error
imgargs vmlinuz initrd=initrd root=/dev/nfs netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/${os_root} || goto error
boot

:debian
os_root debian13
kernel ${httpServer}/images/debian13/install.amd/vmlinuz || goto error
initrd ${httpServer}/images/debian13/install.amd/initrd.gz || goto error
boot

:win10
imgexec tftp://${netX/next-server}/boot/x64/wdsmgfw.efi || goto error
boot || goto failed

:exit
echo Boot from disk...
sleep 2
exit

# При ошибках выход на командную строку
:error
echo Failed - have error
sleep 1
goto shell

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

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

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

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

:veeam
sanboot ${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_uefi
sanboot --drive 0xe0  ${httpServer}/images/strelecuefi/strelec.iso || goto error

А уже после загрузки через WinPE, модифицировав .wim файл добавим в автозагрузку скрипт, который загрузит и примонтирует необходимые нам диски
Зачем такой "костыль"? Смысл в том, что если грузить sanboot --drive 0xA0 (то есть как CD-ROM), то загрузка занимает от 4 минут и дольше, в зависимости от скорости интернета, а также накладывает ограничение с требованием использовать больше 5гб ОЗУ (то есть размер .iso образа), с вложенным скриптом в .wim скорость загрузки занимает менее 30-ти секунд и работает даже на 1-2Гб ОЗУ
но прежде чем модифицировать .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 в директории /disk2
touch /disk2/strelec/strelec.img #создаём пустой файл образа с расширением .img
truncate -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 = WORKGROUP
server string = Samba Server %v
server role = standalone server
server min protocol = SMB2_10
client max protocol = SMB3
client min protocol = SMB2_10
encrypt passwords = true
restrict anonymous = 2
netbios name = dom-server
security = user
map to guest = never
max log size = 1000
usershare allow guests = Yes
dos charset = 866
unix charset = utf8
lanman auth = yes
ntlm auth = yes

[obraz_ro]
comment = ro
path = /disk2/obraz_ro
public = yes
writable = yes
read only = no
guest ok = yes
create mask = 0775
directory mask = 0775
force create mode = 0775
force directory mode = 0775

[obraz_rw]
comment = rw
path = /disk2/obraz_rw
public = no
writable = yes
read only = yes
guest ok = no
valid users = pxe, samba #имя пользователя кому можно подключаться по smb
write list = samba
create mask = 0775
directory mask = 0775
force create mode = 0775
force directory mode = 0775
inherit 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
#нацеливаем "таргетируем" iscsi
iscsicli QAddTarget iqn.2026-02.local.dom.ipxe:strelec 10.50.50.50
ping 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 
#подключаем папку как сетевой диск K
net use K: \\10.50.50.50\obraz_ro /user:Логин и пароль пользователя у которого есть доступ к папке
# пауза
ping 10.50.50.50 -n 3
#подключаем папку как сетевой диск N
net 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_uefi
sanboot --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_legacy
imgfree
kernel ${httpServer}/images/strelec/wimboot gui
initrd -n BCD       ${httpServer}/images/strelec/boot/BCD       BCD
initrd -n boot.sdi  ${httpServer}/images/strelec/boot/boot.sdi  boot.sdi
initrd -n BOOTMGR ${httpServer}/images/strelec/BOOTMGR BOOTMGR
initrd -n strelec10x64.wim  ${httpServer}/images/strelec/sources/strelec10x64.wim strelec10x64.wim
imgstat
boot || 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.sdi
bcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdidevice boot
bcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdipath \boot\boot.sdi

#Исправляем пути к wim
bcdedit /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}, с фигурными скобками
#Вычищаем BCD
bcdedit /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.exe
bcdedit /store %BCDSTORE% /set {GUID} systemroot \windows
bcdedit /store %BCDSTORE% /set {GUID} detecthal Yes
bcdedit /store %BCDSTORE% /set {GUID} winpe Yes
bcdedit /store %BCDSTORE% /set {GUID} nointegritychecks Yes
bcdedit /store %BCDSTORE% /set {GUID} testsigning Yes
bcdedit /store %BCDSTORE% /set {GUID} nx AlwaysOff

#Удаляем strelec10 x86
bcdedit /store %BCDSTORE% /delete {GUID} /f

#Удаляем strelec8 x86
bcdedit /store %BCDSTORE% /delete {GUID} /f

#Удаляем strelec8NE x86
bcdedit /store %BCDSTORE% /delete {GUID} /f

#Обновляем displayorder - только x64
bcdedit /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 следующие строки:

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

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/bash

ISO_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 1
fi

# Распаковка с помощью 7z
echo "Распаковываю ISO..."
7z x -y "$ISO_FILE" -o"$EXTRACT_DIR/"

# Удаление ISO
rm -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 строчки:

:win10
imgexec tftp://${netX/next-server}/boot/x64/wdsmgfw.efi || goto error
boot || goto failed

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

Linux Ubuntu 24.04.4 autoinstall

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

:ubuntua
set os_root ubuntu24
kernel ${httpServer}/images/ubuntu24/vmlinuz || goto error
initrd ${httpServer}/images/ubuntu24/initrd || goto error
imgargs 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 error
boot

В блоке остановлю своё внимание на пояснении только четырёх важнейших аспектах, поскольку остальные никак не отличаются от 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 и возможностью снимать и развёртывать бекапы различных систем по сети, данный сервер работает быстрее обычной флешки, поскольку ограничен лишь скоростью накопителей и сетевой пропускной способностью

Комментарии (4)


  1. GrimAnEye
    20.05.2026 15:12

    Помяну чёрта https://habr.com/ru/articles/681142/


    1. AbyssWat4ers Автор
      20.05.2026 15:12

      Основной аспект в моей статье в том, что интегрирован wds, объяснена возможность запускать WinPE с монтированием в систему дисков для возможности восстановить из бекапа любой компьютер или наоборот сделать бекап, лишь бы iPXE был доступен, запуск антивируса с автоматическим обновлением баз раз в неделю, доработан и обновлён Legacy режим, пояснение и нюансы за autoinstall linux с возможностью в лёгкую интегрировать и добавить его в puppet для будущего, а также статья более комплексна и объяснена на случай "сделай сам"


  1. Mailo2600
    20.05.2026 15:12

    iVentoy есть ещё если нет времени, для простых задач вполне


    1. AbyssWat4ers Автор
      20.05.2026 15:12

      у iVentoy насколько помню часть функций платные