Последнее изменение файла: 2020.03.16
Скопировано с www.bog.pp.ru: 2023.09.23
Bog BOS: PXE: протокол, настройка ISC DHCP сервера, pxelinux, сервер установки Linux
PXE (Preboot Execution Environment) - стандарт, предложенный Intel и Systemsoft (последняя версия 2.1 от 20 сентября 1999),
для обеспечения возможности сетевой загрузки ОС.
Является частью набора спецификаций Wired for Management (WfM 2.0).
Используется для установки ОС по сети, восстановительных работ или для работы бездисковых компьютеров.
Используются протоколы DHCP (с расширениями) и TFTP (с широковещательным расширением MTFTP).
Сетевая карта должна иметь активированный PCI Option ROM (firmware, прошивка, физически м.б. в другом месте), содержащий загрузчик (хотя см. Etherboot),
а BIOS должна позволять загружаться по сети.
В стандарте PXE ничего не говорится про UEFI, IPv6, архитектуры отличные от IA-32.
требования к BIOS со стороны PXE прошивки и программы сетевой загрузки (NBP - Network Bootstrap Program):
PnP BIOS 1.0a или выше
SMBIOS 2.2 или выше
BIOS Boot Specification (BBS) 1.01 в части глав 3 (поиск устройств IPL - Initial Program Load - и составление таблицы IPL) и 4 (приоритет IPL)
механизм инициализации PXE прошивки (IPL, bootstrap) - запуск PXE клиента
проводится процедура IPL;
BIOS перебирает по очереди загрузочные устройства из таблицы IPL (PXE ROM является BEV устройством) и пытается с них загрузиться,
в т.ч. в свою очередь управление передаётся на сегментный адрес PXE загрузчика;
менеджер загрузки UEFI имеет явный список потенциальных источников загрузки,
дойдя до ? начинает ?
механизм (расширение DHCP) определения сетевого адреса NBP (IP адрес сервера и имя файла)
и протокол её загрузки (TFTP/MTFTP) и проверки (BIS);
реализован в PXE Base Code (может находиться в PXE Option ROM, в основной прошивке BIOS/UEFI или внешнем модуле/расширении);
упрощённая последовательность взаимодействия PXE клиента и сервера (серверов) такова:
клиент посылает DHCPDISCOVER с расширением PXE
разбирающийся в PXE сервер DHCP посылает список серверов загрузки (т.е. нужен настроенный DHCP сервер,
возможно использование DHCP Relay или вспомогательного DHCP Proxy)
клиент выбирает сервер загрузки подходящего типа и загружает NBP с помощью TFTP сервера (т.е. нужен настроенный TFTP сервер)
клиент запускает NBP (определены требования к состоянию клиента на этот момент, NBP может использовать PXE API)
набор требований к состоянию клиента на момент запуска NBP
набор PXE API (реализованы в PXE прошивке), которые могут использоваться BIOS или загруженной NBP;
в частности, содержит Pre-boot API, UDP API, API TFTP клиента и UNDI (Universal Network Device Interface) API
Стандарт предусматривает использование MTFTP (multicast TFTP) для загрузки файлов (не описываю, т.к. не использую).
Для проверки правильности NBP PXE загрузчик может запросить дополнительный файл, содержащий
цифровую подпись NBP (сертификаты в формате X.509v3), и использовать API работы с цифровой подписью (BIS - Boot Integrity Services API).
Адреса подпрограмм данного API должны содержаться в BIOS, их адреса и параметры задаются
в SMBIOS (адрес блока описания подпрограмм: "dmidecode -t 31 -u"; нет этого блока - нет BIS).
В частности, имеется подпрограмма, возвращающая список поддерживаемых алгоритмов шифрования и хеширования, а также длин ключей шифрования
(обязательны DSA-1024/SHA-1 и RSA-512/MD5). Имеется также подпрограмма, сообщающая о необходимости аутентификации.
Подробности не описываю, т.к. не использую.
PXE специфическим образом использует следующие опции DHCP:
информация в формате изготовителя оборудования, подопции:
сервер указывает клиенту способ обнаружения загрузочного сервера:
установка бита 0 запрещает широковещательный запрос
установка бита 1 запрещает групповой запрос
установка бита 2 запрещает принимать ответы от серверов, не указанных
в списке явно
установка бита 3 одновременно с предоставлением имени NBP в пакете DHCPOFFER
требует от клиента загрузки и выполнения NBP безо всякой выдачи меню,
поиска сервера загрузки и т.д.
список серверов загрузки:
тип (2 байта; 0 - PXE bootstrap (локальная загрузка),
1 - MS Windows NT Boot Server, 32768 и больше - для личного использования)
число IP-адресов (1 байт; если 0, то клиент
может принимать предложения любого сервера загрузки указанного типа)
IP-адреса (по 4 байта каждый)
тип ...
меню, выдаваемое оператору для выбора сервера загрузки:
тип (2 байта)
длина строки (1 байт)
строка
тип ...
текст приглашения оператору для выбора из меню (без этой подопции меню выдаётся
без вмешательства оператора, автоматического выбора не происходит):
число секунд до автоматического выбора первого пункта меню (1 байт,
255 или отсутствие подопции - выдать меню сразу и ждать бесконечно долго,
0 - немедленно выбирать первый пункт меню)
строка приглашения
номер доверяемого публичного ключа и тип цифровой подписи (4 байта)
клиент указывает тип сервера загрузки (2 байта) и уровень (2 байта;
0 - первый файл NBT и т.д., 0x8000 - цифровая подпись первого файла и т.д.)
список требуемых клиенту от сервера параметров должен содержать как минимум
subnet(1), router(3), vendor(43), class(60)
тип клиента (class identifier),
PXE клиент посылает с помощью этой опции PXE Client Class Identifier
в формате "PXEClient:Arch:00000:UNDI:002001", сервер подтверждает готовность обслуживать
PXE клиента повторением той же строки или просто "PXEClient":
строка "PXEClient" указывает DHCP серверу
на необходимость особенного обслуживания PXE клиента; "Arch:00000" означает архитектуру x86;
"UNDI:002001" указывает версию UNDI (2.1 для текущей версии стандарта PXE)
в качестве идентификатора клиента вместа MAC адреса указывается его UUID
(хранится в SMBIOS, структура типа 1; Microsoft называет его GUID);
длина 16 байт и 1 байт для указания типа (254),
текстовое представление - C4F42D50-4FB2-11D9-8D84-000EA68F7252
имя сервера загрузки (можно задавать также в поле sname/next-server)
имя файла NBT (можно задавать также в поле bootfile)
Последовательность событий при загрузке PXE IPL, если сервер не знает про PXE:
BIOS после POST определяет потенциальные загрузочные устройства и запускает PXE IPL
(Initial Programm Load)
клиент выдаёт широковещательный запрос DHCPDISCOVER с расширенными PXE опциями
DHCP сервер выдаёт обычный ответ DHCPOFFER без расширенных опций
с указанием клиентского IP адреса
или перенаправляет клиента на специализированный Proxy DHCP сервер
(в этом случае в качестве IP адреса клиента возвращается 0.0.0.0, а клиент
должен обращаться на порт 4011/UDP указанного прокси сервера с запросом DHCPDISCOVER,
дальше см. ниже)
клиент делает широковещательный запрос DHCPREQUEST/DHCPINFORM на порт 67/UDP
DHCP сервер выдаёт обычный ответ DHCPACK с указанием IP адреса TFTP сервера
и именем файла NBP
клиент загружает указанную NBP с указанного сервера (TFTP, до 32 КБ)
выполнение NBP; так как размер её ограничен, то обычно она
используется для выдачи на экран меню для возможности дать пользователю выбор
и загрузить "настоящую" ОС
Последовательность действий при использовании DHCP сервера, понимающего PXE
и совмещённого с Proxy DHCP:
клиент выдаёт широковещательный запрос DHCPDISCOVER с опциями,
указывающими, что клиент поддерживает PXE на порт 67/UDP
(UUID, тип клиента ("PXEClient", архитектура,
версия UNDI), системная архитектура клиента, версия UNDI)
DHCP сервер выдаёт ответ DHCPOFFER с дополнительными опциями:
идентификатор класса клиента (60): "PXEClient:Arch:00000:UNDI:002001"
(берётся из запроса)
UUID клиента (97)
[если используется Proxy DHCP, то не выдаёт!] опция 43: использовать ли широковещательную,
групповую или unicast адресацию при общении с сервером загрузки,
список IP адресов PXE серверов с указанием типа и строк меню,
текст приглашения для нажатия F8
для вывода меню, время ожидания перед выполнением первой строки меню при
отсутствии выбора пользователя
Proxy DHCP сервер выдаёт клиенту адрес 0.0.0.0 и адрес настоящего DHCP сервера,
с которым клиент обменивается стандартными DHCP запросами для получения и резервирования IP адреса
если клиент решил использовать полученный IP адрес, то он завершает стандартный DHCP обмен
с DHCP сервером для резервирования IP адреса, PXE опции из DHCPOFFER замещают полученные на
предыдущем этапе!
если в ответе было меню с ненулевым временем ожидания,
то на экран выдаётся текст приглашения нажать F8 для вывода меню
если пользователь успел нажать F8 до истечения времени ожидания, то на экран выводится
меню, дающее пользователю возможность выбрать загрузочный сервер
клиент ищет сервер загрузки на основании автоматического или ручного
выбора: расширенный запрос DHCPREQUEST (в зависимости от ответа DHCPOFFER в указанном порядке:
групповой, широковещательный на порт 67, unicast на порт 4011/UDP)
с указанием тех же параметров, что в запросе DHCPDISCOVER, дополнительно указывая
тип загрузочного сервера и уровень (PXE Boot Layer, BIS или не BIS)
если сервер загрузки настроен на поддержку указанного типа и архитектуры клиента,
то он отвечает расширенным DHCPACK
(имя файла NBP для загрузки по TFTP, тип и уровень сервера)
загрузка NBP в ОП (для архитектуры x86 по адресу 0:7C00h) с помощью TFTP (рекомендуется до 32KB,
зарезервировано места в памяти - 577536 байт, ограничение TFTP - 32MB),
возможна проверка контрольной суммы (стандарт BIS)
с помощью дополнительного файла (credentials) с того же самого сервера (к номеру уровня добавляется
0x8000, клиент посылает ещё один запрос на определение имени загружаемого файла
(unicast запрос на тот же сервер загрузки с указанием списка возможных типов аутентификации),
загружает его и проверяет подпись с помощью BIS)
выполнение NBP (при удачной проверке или отсутствии оной); так как размер NBP ограничен, то обычно она
используется для выдачи на экран меню для возможности дать пользователю выбор
и загрузить "настоящую" ОС
Если используется отдельный Proxy DHCP сервер на том же компьютере, то он использует
порт 4011/UDP, если на другом, то - порт 67/UDP. Клиент понимает необходимость обращения к отдельному
Proxy DHCP серверу по наличию в ответе опции 60 ("PXEClient") и отсутствию опции 43 или имени
файла NBP.
В начале объявления (сеть, группа и т.д.) сделать условное задание параметров:
shared-network имя {
authoritative;
# MS Windows BINLSVC не умеет возвращать тип сервера загрузки,
# поэтому клиент PXE не воспринимает его как свой
# RIS сервер с включённой защитой не отдаёт TFTP файл, если не отработал BINLSVC
# такие случаи необходимо обслуживать "по-простому"
# if hardware = 01:xx:xx:xx:xx:xx:xx {
# next-server адрес-RIS-сервера;
# filename "RemoteInstall\\OSChooser\\I386\\startrom.com";
# } elsif ...
# делаем из ISC DHCP сервера два разных BOOT сервера
if substring (option vendor-class-identifier, 0, 9) = "PXEClient" {
vendor-option-space PXE;
option vendor-class-identifier "PXEClient:Arch:00000:UNDI:002001";
# предлагаем оператору выбрать BOOT сервер и ждём 10 секунд
option PXE.prompt 10 "Select Boot Server";
# для сервера типа 0000 приглашение "Local"
# для сервера типа 804c (0x8000+'L') приглашение "LIS (Linux Install Server)"
# для сервера типа 8057 (0x8000+'W') приглашение "RIS (MS Windows Install)"
option PXE.menu 00:00:05:4c:6f:63:61:6c:80:4c:1a:4c:49:53:20:28:4c:69:6e:75:78:20:49:6e:73:74:61:6c:6c:20:53:65:72:76:65:72:29:80:57:18:52:49:53:20:28:4d:53:20:57:69:6e:64:6f:77:73:20:49:6e:73:74:61:6c:6c:29;
# запретить multicast
option PXE.discovery-control 2;
# для сервера типа 804c (0x8000+'L') один BOOT сервер x.y.z.v (адрес нашего DHCP сервера)
# для сервера типа 8057 (0x8000+'W') один BOOT сервер x.y.z.v (адрес нашего DHCP сервера)
option PXE.boot-server-list 80:4c:01:xx:yy:zz:vv:80:57:01:xx:yy:zz:vv;
# ветвление в зависимости от выбора типа BOOT сервера, сделанного оператором
if substring (option vendor-encapsulated-options, 3, 1) = "W" {
next-server адрес-RIS-сервера;
filename "RemoteInstall\\OSChooser\\I386\\startrom.com";
option PXE.boot-server-type 32855 0;
} else {
next-server адрес-TFTP-сервера-с-pxelinux;
if option architecture-type = 00:07 {
# rfc4578#section-2.1: 0 - Intel x86PC, 7 - UEFI ByteCode, 9 - UEFI x86-64
# /boot/efi/EFI/centos/shim.efi из пакета shim в CentOS 7
# /boot/efi/EFI/centos/grubx64.efi из пакета grub2-efi в CentOS 7
filename = "uefi/shim.efi";
} else {
# из system-config-netboot-cmd в CentOS 5 или syslinux-tftpboot в CentOS 6/7
filename "linux-install/pxelinux.0";
}
option PXE.boot-server-type 32844 0;
}
}
}
Дешифровка "загадочной" строки из руководства pxelinux:
09: меню
0f: размер меню
80:00: нестандартный сервер загрузки
0c:4e:65:74:77:6f:72:6b:20:62:6f:6f:74: Network boot
0a: текст приглашения оператору
07: размер приглашения
00: секунд ожидания (немедленно выбрать первый пункт)
50:72:6f:6d:70:74: Prompt
06: способ обнаружения загрузочного сервера
01: размер
02: не принимать ответы от серверов не в списке
08: список серверов загрузки
03: размер списка
80:00: нестандартный сервер загрузки
00: число серверов (принимать любой адрес)
47: тип сервера загрузки и уровень
04: размер
80:00: нестандартный сервер загрузки
00:00: уровень 0
ff конец списка
В Linux в качестве NBP обычно используется pxelinux (часть проекта syslinux),
который загружает образы ядра и initrd и передаёт управление ядру.
Вместо ядра Linux может быть загружена любая совместимая с используемым форматом
программа (например, memdisk, которая в свою очередь позволяет загрузить DOS).
Имеется вариант pxelinux, умеющий загружать образы в формате NBI (Network Bootable Image) -
образы дискеты с DOS или ядро Linux вместе с корневой файловой системой
(для изготовления .nbi используется пакет NetBoot).
Сервер TFTP должен поддерживать tsize.
Имя файла (включая относительную часть) не может иметь длину более 127 символов.
Структура каталога /tftpboot/linux-install (можно изменить опцией 210 DHCP):
сам загрузчик (NBP) находится в файле pxelinux.0
тексты сообщений в каталоге msgs/: достаточно сложный формат (^L - очистка экрана, ^G - звонок,
есть возможность выводить графические файлы, управлять цветами, условный вывод и т.д.),
первоначально выдаётся boot.msg,
другие файлы выдаются на экран при нажатии кнопок F2 и т.д.;
набор файлов сообщений один на все варианты
конфигурационные файлы в каталоге pxelinux.cfg/ (имя файла из каталога
выбирается исходя из UUID клиента, его MAC-адреса ("01-MAC-адрес", например "01-88-99-aa-bb-cc-dd"),
IP адреса (16-ричная нотация с прописными буквами, "C0A8025B"), урезанного справа IP-адреса или берётся файл default)
Конфигурационный файл является текстовым (UNIX или DOS), пустые строки и строки, начинающиеся с "#" игнорируются,
первое слово - ключ (регистронезависим), длина строки не более 512 байт:
implicit 1 # 0 - не загружать образ, если он не указан явно в разделе команд
timeout десятых-секунды # максимальное ожидание до первого нажатия, 0 - бесконечность
totaltimeout десятых-секунды # максимальное ожидание до начала загрузки, 0 - бесконечность
ontimeout имя-файла-образа параметры # что загружать при отсутствии ответа оператора
onerror имя-файла-образа параметры # что загружать при ошибках загрузки выбранного оператором образа
nohalt 0 # не останавливать ЦП в ожидании ввода
serial порт скорость флажки
console 1 # позволяет отключить видеовывод на консоль
font имя-файла-psf
kbdmap имя-файла
label команда # начинает новый командный раздел (до следующей label), команды должны быть уникальными
kernel имя-файла # загрузить образ для выполнения с автоматическим распознаванием типа
linux имя-файла # загрузить образ как ядро Linux
PXE имя-файла # загрузить образ (суффикс ".0") как PXE NBP, нет командной строки и initrd
append строка # ровно 1 строка 1 раз, может быть глобальной или внутри командного раздела,
строка добавляется к командной строке ядра в самом начале как текст параметров,
например, параметры программы установки anaconda ("initrd=имя-файла ramdisk_size=размер method=URL ip=dhcp")
Последовательность подготовки обратна последовательности загрузки:
подготовить дерево файлов на сервере HTTP, FTP или NFS
(просто скопировать дерево файлов из каталога Redhat с DVD-ROM (образа) на сервер, где они будут доступны с помощью
соответствующего протокола)
создать файл kickstart (при необходимости), разместить его на сервере HTTP, FTP или NFS
проверка и размещение образов ядра и ramdisk на сервере TFTP
(пакет system-config-netboot содержит графически интерфейс, пакет system-config-netboot-cmd - командный интерфейс (утилита pxeos))
pxeos управляет списком вариантов загрузки (хранится в /tftpboot/linux-install/pxelinux.cfg/pxeos.xml),
варианты нумеруются с 0 (0 - всегда локальный загрузчик),
не более 10 вариантов (?), предъявляются оператору в виде меню из boot.msg), ключи:
действие:
-a (добавить конфигурацию; создаётся каталог /tftpboot/linux-install/идентификатор-ОС/,
в который записываются файлы ядра (vmlinuz) и ramdisk (initrd.img), которые берутся из подготовленного дерева файлов на сервере;
определяется размер ramdisk ("ramdisk_size="), редактируется pxelinux.cfg/default (label, kernel, append);
также генерируется файл ks.cfg с URL для доступа к этому дереву - см. ключи -p, -s и -L)
-m (изменить)
-d (удалить - не работает в CentOS4.6, пришлось вручную редактировать pxelinux.cfg/default и msgs/boot.msg)
-l (выдать список)
-i описание (выдаётся оператору в виде строки меню)
-p {NFS | FTP | HTTP}
--anonymous {1|0}
--user имя-пользователя
--password пароль
-D 0 (это установка, а не запуск бездисковой станции)
-s имя-сервера-NFS-FTP-HTTP
-L путь-к-дереву-файлов (часть URL после имени сервера)
-K местонахождение-файла-kickstart
идентификатор-ОС (используется как имя каталога в /tftpboot/linux-install; д.б. последним в строке)
В комплект system-config-netboot-cmd также входят файлы /etc/pam.d/system-config-netboot
(запрашивает пароль root, кеширует на время),
/etc/security/console.apps/system-config-netboot, /etc/sysconfig/system-config-netboot (задаётся PXEBOOTDIR).
При описанных выше настройках PXE загрузчик 10 секунд ждёт нажатия клавиши F8, затем ждёт 10 секунд выбора
сервера загрузки, затем выводит на экран меню загрузки (msgs/boot.msg) и 10 секунд ждёт выбора команды (реальный список команд можно
посмотреть нажав Tab, он не обязательно совпадает с текстом msgs/boot.msg). При отсутствии выбора оператора происходит загрузка
с локального диска.
В RHEL6/CentOS6 утилита pxeos отсутствует, но никто не мешает разложить файлы вручную,
а pxelinux.0 взять из пакета syslinux-tftpboot (также оттуда можно взять набор модулей - menu.c32 и др.).
UEFI на x86_64: рекомендуется использовать grub2 вместо SYSLINUX,
shim.efi взять из пакета shim в CentOS 7 (/boot/efi/EFI/centos/shim.efi),
grubx64.efi взять из пакета grub2-efi в CentOS 7 (/boot/efi/EFI/centos/grubx64.efi).
Скопировать initrd.img и vmlinuz из images/pxeboot установочного DVD-ROM в uefi сервера tftboot.
Настройки grub.cfg (в тот же каталог, что и shim.efi):
не работает: после выбора Linux и получения "uefi/shim.efi" клиент выдаёт повторный DHCP запрос по адресу шлюза