четверг, 2 апреля 2015 г.

Установка Windows 7 с помощью PXE и LINUX сервера

[взято отсюда]

Дано: некий офис с компьютерами типа PC, сервер с Linux.
Задача: Сделать сервис установки системы по сети без использования платных Windows Server и др.

Решение:
Решение базируется на статье "PXE Win Install: установка Windows 7 по сети" Автор: Игорь Осколков от 22.03.2012.
Привожу рабочее решение, с исправленными ошибками в упомянутой статье и для Linux серверов с сервисами DHCP, TFTP и Samba.


План работ
1. Настройка служб DHCP, TFTP и Samba на Linux сервере.
2. В первую очередь необходимо создать образ WINPE, интегрирования в него сетевых драйверов и настройку скрипта сетевой загрузки.
3. Создание и настройка загрузчика BCD.
4. Размещение файлов на сервере и проверка сетевой загрузки.

Что понадобиться:
1. Компьютер с установленной Windows 7.
2. Windows Automated Installation Kit (WAIK).
3. Linux сервер, можно два :)

Приступим.


1. DHCP

У меня DHCP установлен на маршрутизаторе 192.168.1.1, с Debian GNU/Linux.
Все что необходимо нам от DHCP сервера - это указать адрес сервера загрузки и имя файла для загрузки по сети.

Я поместил эти параметры в блок описания подсети:
  
subnet 192.168.1.0 netmask 255.255.255.0
{
option netbios-name-servers 192.168.1.1;
option routers 192.168.1.1;
...
next-server 192.168.1.200;
filename "pxelinux.0";

...
}


2. TFTP сервер

Находится вместе с Samba сервером на отдельном комьютере, с адресом 192.168.1.200. Здесь установлен дистрибутив Gentoo.

Как установить tftpd в gentoo - читать здесь.

Настройки TFTP:
Файл /etc/conf.d/in.tftpd

INTFTPD_PATH="/opt/pxe/"
INTFTPD_OPTS="-R 4096:32767 -s ${INTFTPD_PATH} -m /etc/tftpd.rules -v"

Первый параметр - корень папки TFTP сервера.
Второй - параметры запуска.

Файл /etc/tftpd.rules

rg \\ /

Для автозамены слешей в стиле windows на linux-like.

В папку /opt/pxe/ копируем файлы из пакета syslinux:

cp /usr/share/syslinux/pxelinux.0 /opt/pxe/
cp /usr/share/syslinux/pxechain.com /opt/pxe/
cp /usr/share/syslinux/memdisk /opt/pxe/

Создаем папку pxelinux.cfg

mkdir -p /opt/pxe/pxelinux.cfg

Копируем туда файлы из пакета syslinux:

cp /usr/share/syslinux/menu.c32 /opt/pxe/pxelinux.cfg/
cp /usr/share/syslinux/poweroff.com /opt/pxe/pxelinux.cfg/
cp /usr/share/syslinux/reboot.c32 /opt/pxe/pxelinux.cfg/

 Создаем файл default

nano /opt/pxe/pxelinux.cfg/default

такого содержания:
DEFAULT pxelinux.cfg/menu.c32
TIMEOUT 600
MENU TITLE PXE BOOT MENU
ALLOWOPTIONS 0
PROMPT 0

LABEL 001
MENU LABEL Local ^Boot
MENU DEFAULT
LOCALBOOT 0
TIMEOUT 80
TOTALTIMEOUT 9000

LABEL 002
MENU LABEL ^Install Windows 7 x64
KERNEL pxechain.com
APPEND ../Boot/pxeboot.com

LABEL 003
MENU LABEL ^Memtest86+
KERNEL images/memtest

LABEL Reboot
MANU LABEL ^Reboot
KERNEL pxelinux.cfg/reboot.c32



3. Samba

Приведу секцию, которая отвечает за созданную шару с дистрибутивом windows7:

[Win7Install$]
comment = Windows7x64 install folder
path = /opt/sambashare/win7x64
read only = No
create mask = 0666
directory mask = 0777
guest only = Yes
guest ok = Yes

Проверить можно с любой windows в командной строке:

net use z: \\192.168.1.200\Win7Install$

Если ресурс под паролем, то

net use z: \\192.168.1.200\Win7Install$ password /user:username

В эту папку копируем содержимое диска дистрибутива Windows 7.


4. WinPE

Частично действия похожи на те, что делались в статье "Собираем свой дистрибутив Windows 7 с программами".

Установим WAIK, который мы скачали по ссылке выше.

Запускаем "Командная строка средств развертывания" (если у вас английская версия - Deployment Tools Command Prompt). Запускаем от имени Администратора.

В консоли выполняем команду:

copype.cmd amd64 C:\WinPE

Эта команда копирует в каталог C:\WinPE файлы, необходимые для создания образа с предустановочным окружением 64-разрядной Windows 7. Для 32-битной версии надо указать параметр x86 вместо amd64.

copype.cmd x86 C:\WinPE

Далее буду приводить две команды, с обеими архитектурами, для удобства copy-paste.

Сразу же создайте папку C:\TFTP\, в которой будут файлы для TFTP-сервера, а в ней сделайте директорию Boot. В последней будут храниться загрузочные файлы.

Копируем файлы из стандартного winpe образа в папку C:\TFTP\Boot

imagex /mountrw winpe.wim 1 mount

Эта комнада монтирует winpe.wim в папку C:\WinPE\ mount (осле первой команды мы автоматически попадаем в папку C:\WinPE)

copy mount\Windows\Boot\PXE\*.* C:\TFTP\Boot

Я еще скопировал папку ru-RU и папку fonts. Если их в образе не окажется - их можно взять с любого установочного диска Windows7.


Копируем еще один нужный файл

copy "C:\Program Files\Windows AIK\Tools\PETools\amd64\boot\boot.sdi" C:\TFTP\Boot

или в случае 32-битной Windows 7

copy "C:\Program Files\Windows AIK\Tools\PETools\x86\boot\boot.sdi" C:\TFTP\Boot

Интегрируем драйвера. Для этого, скачиваем пакет дрйверов для сетевых карт, отсюда. Распаковываем, я для удобства перенес папку L из распакованного дерева в корень диска С.

dism /image:C:\winpe\mount /add-driver /driver:C:\L /recurse /forceunsigned

Где:
/image:C:\winpe\mount примонтированый образ

/add-driver - добавить драйвера.
/driver:C:\L - папка с драйверами.
/recurse - позволяет брать драйвера еще и из подпапок.
/forceunsigned - если есть неподписанные драйверы.

После этого, пока образ еще примонтирован, необходимо подправить файл startnet.cmd. Но для этого уже необходимо знать IP адрес Samba сервера и путь к ресурсу, который будет отдавать дистрибудтив Windows 7.
Выполняем команду:

notepad C:\WinPE\mount\windows\system32\startnet.cmd

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

wpeinit
net use Z: \\192.168.1.200\Win7Install$
Z:\setup.exe

Если ресурс под паролем, то строка имеет другой вид:

net use Z: \\192.168.1.200\Win7Install$ password /user:username

Закрываем блокнот, с сохранением изменений, проверяем, чтобы в проводнике не было открыто содержимое папки mount и выполняем команду для отмонтирования:
 
imagex /unmount C:\winpe\mount /commit

И копируем файл образа в C:\TFTP\Boot\

copy C:\winpe\winpe.wim C:\TFTP\Boot\boot.wim


5. Загрузчик BCD

Здесь в оригинальной статье скрылись несколько ошибок, из-за которых не загружался загрузчик и в Linux вылезли мелкие ошибки, такие как соответствие регистра.
Ниже представлен вариант, который работает, следите за регистром в пути к файлам, так как в Windows все будет работать и так, а в Linux приведет к ошибке.

Создаем загрузчик:

bcdedit -createstore C:\BCD
bcdedit -store C:\BCD -create {ramdiskoptions} /d "Ramdisk options" 
bcdedit -store C:\BCD -set {ramdiskoptions} ramdisksdidevice  boot
bcdedit -store C:\BCD -set {ramdiskoptions} ramdisksdipath  \Boot\boot.sdi
bcdedit -store C:\BCD -create /d "PE Boot Image" /application osloader

После этого в консоли появиться сообщение содержащее GUID в виде

{ef40ab64-7ce9-11e2-8487-a0b3ccc2b14c} (пример). Копируем его в следующие команды:

bcdedit -store C:\BCD -set GUID systemroot \Windows 
bcdedit -store C:\BCD -set GUID detecthal Yes 
bcdedit -store C:\BCD -set GUID winpe Yes 
bcdedit -store C:\BCD -set GUID osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions} 
bcdedit -store C:\BCD -set GUID device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit -store C:\BCD -create {bootmgr} /d "Windows BootManager" 
bcdedit -store C:\BCD -set {bootmgr} timeout 30 
bcdedit -store C:\BCD -displayorder {ef40ab64-7ce9-11e2-8487-a0b3ccc2b14c}

Копируем (или переносим, чтобы не мешал) созданный BCD в папку C:\TFTP\Boot\

copy C:\BCD C:\TFTP\Boot\
или
move C:\BCD C:\TFTP\Boot\

Файл pxeboot.com заменяем файлом pxeboot.n12, меняя ему расширение.

Получилась такая картина в этой папке:

 Папки:

fonts
ru-RU

Файлы:

BCD
abortpxe.com
boot.wim
hdlscom1.n12
hdlscom2.n12
wdsnbp.com
WdsConfig.inf
boot.sdi
bootmgr.exe
hdlscom1.com
hdlscom2.com
pxeboot.com
wdsmgfw.efi

 Полученную папку C:\TFTP копируем на Linux сервер, любым удобным для вас способом. Копируем в папку /opt/pxe/ . Так же файл bootmgr.exe копируем из папки Boot в корень папки /opt/pxe/
Получается так:

ls -la /opt/pxe/
total 574
drwxrwxrwx  5 root root    248 Feb 22 18:59 .
drwxr-xr-x 17 root root    808 Feb 18 15:16 ..
drwxrwxrwx  4 root root    520 Feb 25 18:10 Boot
drwxrwxrwx  2 root root     72 Feb 18 14:53 images
drwxrwxrwx  2 root root    160 Feb 22 18:07 pxelinux.cfg
-rwxrwxrwx  1 root root 523328 Jul 14  2009 bootmgr.exe
-rwxrwxrwx  1 root root  26140 Feb 18 14:45 memdisk
-rwxrwxrwx  1 root root    998 Feb 22 18:20 pxechain.com
-rwxrwxrwx  1 root root  26579 Feb 18 14:45 pxelinux.0

ls -la /opt/pxe/Boot/ --group-directories-first
total 282836
drwxrwxrwx 4 root root       520 Feb 25 18:10 .
drwxrwxrwx 5 root root       248 Feb 22 18:59 ..
drwxrwxrwx 2 root root       208 Jan 27  2011 fonts
drwxrwxrwx 2 root root       112 Feb 22 17:36 ru-RU
-rwxrwxrwx 1 root root     12288 Feb 22 16:27 BCD
-rwxrwxrwx 1 root root      1347 Jun 11  2009 WdsConfig.inf
-rwxrwxrwx 1 root root        79 Jun 11  2009 abortpxe.com
-rwxrwxrwx 1 root root   3170304 Jun 10  2009 boot.sdi
-rwxrwxrwx 1 root root 138584642 Feb 22 17:58 boot.wim
-rwxrwxrwx 1 root root    523328 Jul 14  2009 bootmgr.exe
-rwxrwxrwx 1 root root     26076 Jun 11  2009 hdlscom1.com
-rwxrwxrwx 1 root root     26060 Jun 11  2009 hdlscom1.n12
-rwxrwxrwx 1 root root     26076 Jun 11  2009 hdlscom2.com
-rwxrwxrwx 1 root root     26060 Jun 11  2009 hdlscom2.n12
-rwxrwxrwx 1 root root     25772 Jun 11  2009 pxeboot.com
-rwxrwxrwx 1 root root    527360 Jul 14  2009 wdsmgfw.efi
-rwxrwxrwx 1 root root     31124 Feb 22 18:15 wdsnbp.com


6. Проверка работы

Проверяем работу сервиса. С любого другого компьютера, загружаемся в BIOS, разрешаем возможность загрузки по сети. Загруженное меню:
Выбираем пункт Install, загружается образ winpe:

Лог загрузки:

Feb 25 14:24:49 dev1 in.tftpd[31185]: RRQ from 192.168.1.152 filename pxelinux.cfg/01-00-1c-42-cb-f8-83 
Feb 25 14:24:49 dev1 in.tftpd[31186]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A80198 
Feb 25 14:24:49 dev1 in.tftpd[31187]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A8019 
Feb 25 14:24:49 dev1 in.tftpd[31188]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A801 
Feb 25 14:24:49 dev1 in.tftpd[31189]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A80 
Feb 25 14:24:49 dev1 in.tftpd[31190]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A8 
Feb 25 14:24:49 dev1 in.tftpd[31191]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0A 
Feb 25 14:24:49 dev1 in.tftpd[31192]: RRQ from 192.168.1.152 filename pxelinux.cfg/C0 
Feb 25 14:24:49 dev1 in.tftpd[31193]: RRQ from 192.168.1.152 filename pxelinux.cfg/C 
Feb 25 14:24:49 dev1 in.tftpd[31194]: RRQ from 192.168.1.152 filename pxelinux.cfg/default 
Feb 25 14:24:49 dev1 in.tftpd[31195]: RRQ from 192.168.1.152 filename pxelinux.cfg/menu.c32 
Feb 25 14:24:49 dev1 in.tftpd[31196]: RRQ from 192.168.1.152 filename pxelinux.cfg/default 
Feb 25 14:25:11 dev1 in.tftpd[31203]: RRQ from 192.168.1.152 filename pxechain.com 
Feb 25 14:25:11 dev1 in.tftpd[31204]: RRQ from 192.168.1.152 filename pxelinux.cfg/../Boot/pxeboot.com 
Feb 25 14:25:11 dev1 in.tftpd[31205]: RRQ from 192.168.1.152 filename bootmgr.exe 
Feb 25 14:25:12 dev1 in.tftpd[31207]: RRQ from 192.168.1.152 filename \Boot\Fonts\wgl4_boot.ttf remapped to /Boot/Fonts/wgl4_boot.ttf 
Feb 25 14:25:12 dev1 in.tftpd[31208]: RRQ from 192.168.1.152 filename \boot.ini remapped to /boot.ini 
Feb 25 14:25:27 dev1 in.tftpd[31218]: RRQ from 192.168.1.152 filename \Boot\BCD remapped to /Boot/BCD 
Feb 25 14:25:27 dev1 in.tftpd[31218]: tftp: client does not accept options 
Feb 25 14:25:27 dev1 in.tftpd[31219]: RRQ from 192.168.1.152 filename \Boot\BCD remapped to /Boot/BCD 
Feb 25 14:25:27 dev1 in.tftpd[31220]: RRQ from 192.168.1.152 filename \Boot\Fonts\wgl4_boot.ttf remapped to /Boot/Fonts/wgl4_boot.ttf 
Feb 25 14:25:27 dev1 in.tftpd[31221]: RRQ from 192.168.1.152 filename \hiberfil.sys remapped to /hiberfil.sys 
Feb 25 14:25:27 dev1 in.tftpd[31222]: RRQ from 192.168.1.152 filename \Boot\boot.wim remapped to /Boot/boot.wim 
Feb 25 14:25:27 dev1 in.tftpd[31222]: tftp: client does not accept options 
Feb 25 14:25:27 dev1 in.tftpd[31223]: RRQ from 192.168.1.152 filename \boot\boot.sdi remapped to /Boot/boot.sdi 
Feb 25 14:25:27 dev1 in.tftpd[31223]: tftp: client does not accept options 
Feb 25 14:25:27 dev1 in.tftpd[31224]: RRQ from 192.168.1.152 filename \boot\boot.sdi remapped to /Boot/boot.sdi 
Feb 25 14:25:30 dev1 in.tftpd[31226]: RRQ from 192.168.1.152 filename \Boot\boot.wim remapped to /Boot/boot.wim 



На этом все. Про создание своего дистрибутива Windows, с установленными программами, автоматизацией установки и прочее читать здесь - "Собираем свой дистрибутив Windows 7 с программами".
 
и несколько полезных комментариев из этого блога:

 Анонимный

 Суть проблемы: Windows не хочет грузиться при попытке её установить через pxe-меню. Без меню - работает. Т.е. невозможно было сделать меню с выбором установки из нескольких ОС (несколько Windows+Linux+tools). Только прямая загрузка без всякого выбора.

Проблема оказалась в виндовом загрузчике pxeboot.n12, который в этой статье был переименован в pxeboot.com.
Этот злой загрузчик, оказывается, будет работать только из корня tftp-сервера. И конструкцией
kernel pxechain.com
append ../Boot/pxeboot.com
его не обманешь. Кстати, хочу обратить внимание, что в версиях syslinux 4.0.0-4.0.3 этот самый pxechain.com битый (http://www.syslinux.org/wiki/index.php/Common_Problems#pxechain.com.2FPXELINUX-4.00.2B).

Оказалось, что из меню default можно вызвать другой tftp-сервер. Но на каждый инстальник винды плодить по tftp-серверу - это же глупо.
Мне удалось обмануть виндовый загрузчик, вызвав тот же самый tftp-сервер.

Сначала скопировал в корень tftp-сервера файлы pxeboot.n12 и bootmgr.exe
cp /tftpboot/Boot/pxeboot.n12 /tftpboot/
cp /tftpboot/Boot/bootmgr.exe /tftpboot/

Потом поправил файл меню pxelinux.cfg/default :
LABEL 002
MENU LABEL ^Install Windows 7 x64
PXE 192.168.1.3::pxeboot.n12

И всё взлетело.


 Reddik ZiMiN

 все получилось. в некоторых моментах хоетл сумничать (к примеру файл boot.sdi взял не там, ставил загрузку не с файла, который у Вас указан)...
в целом, получилось 3 скрипта.

раз.
imagex /mountrw winpe.wim 1 mount
copy mount\Windows\Boot\PXE\*.* d:\tftp\Boot
rem copy /y d:\winpe\ISO\boot\boot.sdi d:\tftp\Boot
copy "c:\Program Files\Windows AIK\Tools\PETools\x86\boot\boot.sdi" d:\tftp\Boot
dism /image:d:\winpe\mount /add-driver /driver:d:\Inst\drv\L /recurse
echo net use z: \\192.168.1.1\w7$ >> d:\winpe\mount\windows\system32\startnet.cmd
echo z:\setup.exe >> d:\winpe\mount\windows\system32\startnet.cmd
imagex /unmount d:\winpe\mount /commit
copy d:\winpe\winpe.wim d:\tftp\Boot\winpe.wim

два.
set i=d:\tftp\Boot

bcdedit -createstore %i%\BCD
bcdedit -store %i%\BCD -create {ramdiskoptions} /d "Ramdisk options"
bcdedit -store %i%\BCD -set {ramdiskoptions} ramdisksdidevice Boot
bcdedit -store %i%\BCD -set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi
bcdedit -store %i%\BCD -create /d "MyWinPE" /application osloader > guid.txt
notepad guid.txt

и три. т.к. guid выдается строкой с русскими буквами...
set guid={043131e8-0e55-11e4-8280-bb5c29b3e422}
set i=d:\tftp\Boot

bcdedit -store %i%\BCD -set %guid% systemroot \Windows
bcdedit -store %i%\BCD -set %guid% detecthal Yes
bcdedit -store %i%\BCD -set %guid% winpe Yes
bcdedit -store %i%\BCD -set %guid% osdevice ramdisk=[boot]\Boot\winpe.wim,{ramdiskoptions}
bcdedit -store %i%\BCD -set %guid% device ramdisk=[boot]\Boot\winpe.wim,{ramdiskoptions}
bcdedit -store %i%\BCD -create {bootmgr} /d "Windows 7 Boot Manager"
bcdedit -store %i%\BCD -set {bootmgr} timeout 30
bcdedit -store %i%\BCD -displayorder %guid%

отличная статья на эту же тему на хабре, с более сложной конфигурацией.