DHCP+PXE+TFTP — Boot/Netinstall для CentOS 6.6/CentOS 7/Debian Stable/Ubuntu 14.04

Задача: настроить в сети предприятия сетевую установку CentOS 6.6 minimal, CentOS 7 DVD + minimal, Debian Stable (Wheezy), Ubuntu 14.04 LTS
Для этого нам понадобится DHCP сервер (в моей сети уже был настроен isc-dhcp-server), TFTP сервер и:
— HTTP/FTP сервер (на выбор, кому что больше нравится) для локальной установки по сети CentOS;
— NFS сервер для локальной установки по сети Debian/Ubuntu
Почему так? Да потому что Debian based & RHEL based дистры они хоть и линукс … но между ними пропасть всяческих различий, в частности это одно из них 🙂 Сразу скажу, в моем случае приоритет был именно на RHEL, поэтому инсталяхи CentOS я выложил в локальную сеть по HTTP с помощью nginx. С Debian/Ubuntu особо заморачиваться указания не было так как инстал данных дистрибутивов будет выполняться намного реже. Их в меню добавил, но настроил на сетевую установку через Интернет.
Поехали …

Сначала нужно немного подправить настройки DHCP сервера. А точнее в конфиге, в раздел subnet своей сети я добавил 2 опции:

next-server 100.1.1.100;
filename "pxelinux.0";

где, 100.1.1.100 — IP адрес TFTP сервера
И перегрузил сервис:

servece dhcpd restart

Все! DHCP для нашей подсети теперь выдает необходимые для сетевой загрузки параметры, осталось настроить TFTP-сервер. В моем случае TFTP-сервер я решил поднять на CentOS 6.6. IP адрес TFTP-сервера, как я писал выше — 100.1.1.100.
Топаем по ssh на будущий TFTP сервер и изпод рута установим необходимые пакеты:

[root@cent6 ~]# yum install tftp-server syslinux -y

После установки подправим основной конфиг TFTP сервера. Для этого своим любимым текстовым редактором открываем файлик /etc/xinetd.d/tftp:

[root@cent6 ~]# vim /etc/xinetd.d/tftp

И редактируем его до такого состояния:

service tftp
{
    socket_type     = dgram
    protocol        = udp
    wait            = yes
    user            = root
    server          = /usr/sbin/in.tftpd
    disable         = no
    server_args     = -s /var/lib/tftpboot
    per_source      = 11
    cps         = 100 2
    flags           = IPv4
}

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

[root@cent6 ~]# service xinetd restart

Проверим что сервис поднялся и «слушает» 69-й порт по протоколу UDP:

[root@cent6 ~]# netstat -an | fgrep -w 69
udp        0      0 0.0.0.0:69                  0.0.0.0:*                              
[root@cent6 ~]#

Если у вас на данном сервере включен фаервол, не забудьте разрешить трафик на UDP/69-й порт

# TFTP for LAN
-A INPUT -s 10.1.1.0/24 -p udp --dport 69 -m state --state NEW -j ACCEPT

Все отлично! TFTP сервер настроен и поднят, осталось настроить netboot меню и выложить в сеть установочные файлы необходимых дистрибутивов. В данный момент корневая директория нашего TFTP-сервера пуста:

[root@cent6 ~]# ls -l /var/lib/tftpboot/
итого 0
[root@cent6 ~]#

Скопируем туда необходимые для PXE меню файлы:

[root@cent6 ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
[root@cent6 ~]# cp /usr/share/syslinux/menu.c32 /var/lib/tftpboot/
[root@cent6 ~]# cp /usr/share/syslinux/memdisk /var/lib/tftpboot/
[root@cent6 ~]# cp /usr/share/syslinux/mboot.c32 /var/lib/tftpboot/
[root@cent6 ~]# cp /usr/share/syslinux/chain.c32 /var/lib/tftpboot/

Создадим директорию для настроек меню:

[root@cent6 ~]# mkdir /var/lib/tftpboot/pxelinux.cfg

Любой Linux дистрибутив, будь то CentOS, Gentoo или Debian, для загрузки по сети требует особым образом собранное ядро и образ initrd. У каждого дистрибутива уже есть такие файлы, достаточно знать где их скачать под нужную вам версию ОС и архитектуру. Для удобства настройки и администрирования эти файлы лучше размещать в отдельных директориях TFTP сервера.
Создадим директории для размещения сетевого загрузчика CentOS:

[root@cent6 ~]# mkdir -p /var/lib/tftpboot/centos6/x86_64/minimal
[root@cent6 ~]# mkdir -p /var/lib/tftpboot/centos7/x86_64/minimal
[root@cent6 ~]# mkdir -p /var/lib/tftpboot/centos7/x86_64/DVD

И тоже самое для Debian/Ubuntu:

[root@cent6 ~]# mkdir -p /var/lib/tftpboot/ubuntu_14_04/amd64
[root@cent6 ~]# mkdir -p /var/lib/tftpboot/debian7/amd64

Теперь о том где взять эти самые файлы базового загрузчика. Для нужных мне дистрибутивов источник файлов сетевой загрузки оказался разный. Так для CentOS нужные мне файлы содержатся непосредственно на ISO дисках дистрибутивов, а у Debian/Ubuntu эти файлы можно скачать напрямую с любого репозитария и загружать тяжелые ISO-шки не требуется. Увидите дальше … сначала разберемся с CentOS, я выкачал 2 установочных ISO файла CentOS 6.6 и CentOS 7 под архитектуру x86_64 в директорию /root/dist_iso:

[root@cent6 ~]# mkdir dist_iso
[root@cent6 ~]# cd dist_iso
[root@cent6 dist_iso]# wget -c ftp://ftp.linux.kiev.ua/centos/6.6/isos/x86_64/CentOS-6.6-x86_64-minimal.iso
[root@cent6 dist_iso]# wget -c ftp://ftp.linux.kiev.ua/centos/7/isos/x86_64/CentOS-7.0-1406-x86_64-Minimal.iso
[root@cent6 dist_iso]# wget -c ftp://ftp.linux.kiev.ua/centos/7/isos/x86_64/CentOS-7.0-1406-x86_64-DVD.iso
[root@cent6 dist_iso]# cd /root

теперь создам директорию /root/iso и смонтирую туда сначала ISO диск с CentOS 6.6 minimal:

[root@cent6 ~]# mkdir iso
[root@cent6 ~]# mount -o loop /root/dist_iso/CentOS-6.6-x86_64-minimal.iso /root/iso/

Для удобства перейдем в корневую директорию TFTP сервера:

[root@cent6 ~]# cd /var/lib/tftpboot

Кстати вот листинг этой директории, у вас должно быть примерно также 🙂

[root@cent6 tftpboot]# ls -l
итого 196
drwxr-xr-x 3 root root  4096 Ноя 28 09:59 centos6
drwxr-xr-x 3 root root  4096 Ноя 28 10:36 centos7
-rw-r--r-- 1 root root 20832 Ноя 28 09:51 chain.c32
-rw-r--r-- 1 root root 35676 Ноя 28 09:51 mboot.c32
-rw-r--r-- 1 root root 26268 Ноя 28 09:51 memdisk
-rw-r--r-- 1 root root 61796 Ноя 28 09:51 menu.c32
-rw-r--r-- 1 root root 26759 Ноя 28 09:50 pxelinux.0
drwxr-xr-x 2 root root  4096 Ноя 28 09:54 pxelinux.cfg
drwxr-xr-x 3 root root  4096 Ноя 28 09:56 ubuntu_14_04
drwxr-xr-x 3 root root  4096 Ноя 28 09:57 debian7
[root@cent6 tftpboot]#

А вот листинг содержимого ISO-файла диска CentOS-6.6-x86_64-minimal.iso

[root@cent6 tftpboot]# ls -l /root/iso/
итого 82
-r--r--r-- 1 root root    14 Окт 24 16:59 CentOS_BuildTag
dr-xr-xr-x 3 root root  2048 Окт 24 17:12 EFI
-r--r--r-- 1 root root   212 Ноя 27  2013 EULA
-r--r--r-- 1 root root 18009 Ноя 27  2013 GPL
dr-xr-xr-x 3 root root  2048 Окт 24 17:22 images
dr-xr-xr-x 2 root root  2048 Окт 24 17:12 isolinux
dr-xr-xr-x 2 root root 40960 Окт 24 17:22 Packages
-r--r--r-- 1 root root  1354 Окт 19 19:00 RELEASE-NOTES-en-US.html
dr-xr-xr-x 2 root root  4096 Окт 24 17:22 repodata
-r--r--r-- 1 root root  1706 Ноя 27  2013 RPM-GPG-KEY-CentOS-6
-r--r--r-- 1 root root  1730 Ноя 27  2013 RPM-GPG-KEY-CentOS-Debug-6
-r--r--r-- 1 root root  1730 Ноя 27  2013 RPM-GPG-KEY-CentOS-Security-6
-r--r--r-- 1 root root  1734 Ноя 27  2013 RPM-GPG-KEY-CentOS-Testing-6
-r--r--r-- 1 root root  3380 Окт 24 17:22 TRANS.TBL
[root@cent6 tftpboot]#

Как видите, много всего. Но нам нужны файлики initrd.img и vmlinuz из директории /root/iso/images/pxeboot, скопируем их в заготовленную на TFTP сервере под CentOS 6.6 minimal директорию:

[root@cent6 tftpboot]# cp /root/iso/images/pxeboot/vmlinuz centos6/x86_64/minimal/
[root@cent6 tftpboot]# cp /root/iso/images/pxeboot/initrd.img centos6/x86_64/minimal/

И отмонтируем ISO диск:

[root@cent6 tftpboot]# umount /root/iso/

Повторим процедуру для CentOS 7!
Монтируем ISO образ:

[root@cent6 tftpboot]# mount -o loop /root/dist_iso/CentOS-7.0-1406-x86_64-DVD.iso /root/iso/

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

[root@cent6 tftpboot]# cp /root/iso/images/pxeboot/vmlinuz centos7/x86_64/DVD/
[root@cent6 tftpboot]# cp /root/iso/images/pxeboot/initrd.img centos7/x86_64/DVD/

Отмонтируем ISO диск:

[root@cent6 tftpboot]# umount /root/iso/

Повторим для CentOS 7 Minimal:

[root@cent6 tftpboot]# mount -o loop /root/dist_iso/CentOS-7.0-1406-x86_64-Minimal.iso /root/iso/
[root@cent6 tftpboot]# cp /root/iso/images/pxeboot/* centos7/x86_64/minimal/
[root@cent6 tftpboot]# umount /root/iso/

А вот с Ubuntu 14.04 и Debian чуть интереснее … У данных дистрибутивов нужные файлы для загрузки по сети в базовую систему есть на зеркалах репозитариев. Достаточно их только скачать и разместить на TFTP сервер.
Переходим в директорию /var/lib/tftpboot/ubuntu_14_04/amd64:

[root@cent6 tftpboot]# cd /var/lib/tftpboot/ubuntu_14_04/amd64

И качаем сначала ядро Ubuntu-installer:

[root@cent6 amd64]# wget -c ftp://ftp.linux.kiev.ua/ubuntu/dists/trusty/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64/linux

А потом и файлик initrd.gz:

[root@cent6 amd64]# wget -c ftp://ftp.linux.kiev.ua/ubuntu/dists/trusty/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64/initrd.gz

Точно также для Debian Stable (Wheezy).
Переходим в директорию /var/lib/tftpboot/debian7/amd64:

[root@cent6 amd64]# cd /var/lib/tftpboot/debian7/amd64

И качаем с репозитория файлы linux и initrd.gz
Сначала файлик ядра linux:

[root@cent6 amd64]# wget -c ftp://ftp.linux.kiev.ua/debian/dists/wheezy/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux

А потом файлик initrd.gz:

[root@cent6 amd64]# wget -c ftp://ftp.linux.kiev.ua/debian/dists/wheezy/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz

Как я и говорил в начале статьи, мне нужно розшарить по HTTP инстал-диски CentOS 6/7. Сделал я это с помощью nginx. Для начала установим его:

[root@cent6 ~]# yum install nginx

После чего в /var/www я создал необходимые директории:

[root@cent6 ~]# cd /var/www
[root@cent6 www]# mkdir pxe_install_images
[root@cent6 www]# cd pxe_install_images/
[root@cent6 pxe_install_images]# mkdir -p CentOS/6.6-minimal/x86_64
[root@cent6 pxe_install_images]# mkdir -p CentOS/7.0-minimal/x86_64
[root@cent6 pxe_install_images]# mkdir -p CentOS/7.0-DVD/x86_64

Опять 25, монтируем ISO диски и копируем содержимое инстал дисков в соответствующие директории:

[root@cent6 pxe_install_images]# mount -o loop /root/dist_iso/CentOS_6/CentOS-6.6-x86_64-minimal.iso /root/iso/

[root@cent6 pxe_install_images]# rsync -Pavl /root/iso/ CentOS/6.6-minimal/x86_64/

[root@cent6 pxe_install_images]# mount -o loop /root/dist_iso/CentOS_7/CentOS-7.0-1406-x86_64-DVD.iso /root/iso/
[root@cent6 pxe_install_images]# rsync -Pavl /root/iso/ CentOS/7.0-DVD/x86_64/
[root@cent6 pxe_install_images]# umount /root/iso/

[root@cent6 pxe_install_images]# mount -o loop /root/dist_iso/CentOS_7/CentOS-7.0-1406-x86_64-Minimal.iso /root/iso/
[root@cent6 pxe_install_images]# rsync -Pavl /root/iso/ CentOS/7.0-minimal/x86_64/
[root@cent6 pxe_install_images]# umount /root/iso/

Простейший конфиг nginx /etc/nginx/conf.d/default.conf для нашей задачи:

server {
    listen       80;
    server_name  _;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }

    location /pxe_install_images {
    root /var/www;
    autoindex on;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Запускаем nginx:

[root@cent6 ~]# service nginx start

Добавляем в автозагрузку:

[root@cent6 ~]# chkconfig nginx on

Если включен фаервол не забудьте разрешить подключение на порт TCP/80:

# HTTP for LAN
-A INPUT -s 10.1.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT

С любого компа в сети проверяем доступность файлов по HTTP ссылке

http://100.1.1.100/pxe_install_images

Теперь собираем все наши заготовки в единый файлик настроек, он же менюшка: /var/lib/tftpboot/pxelinux.cfg/default
Не забываем добавить вариант загрузки с локального HDD0, это иногда полезно, чтоб лишний раз не перегружаться.
Вот так вышло у меня:

default vesamenu.c32
prompt 0
timeout 300
ONTIMEOUT local

MENU TITLE PXE Menu
#Local HHD0 Boot
LABEL local
    MENU LABEL Boot From Local HDD0
    LOCALBOOT 0

LABEL Ubuntu install
    MENU LABEL Install Ubuntu Desktop/Server 14.04 LTS amd64
#      KERNEL vesamenu.c32
#      APPEND pxelinux.cfg/ubuntu-install.cfg
    KERNEL ubuntu-installer/amd64/linux
    APPEND initrd=ubuntu-installer/amd64/initrd.gz -- quiet

LABEL CentOS 7 x86_64 DVD
        MENU LABEL Install CentOS 7.0-1406 x86_64 DVD
        KERNEL centos7/x86_64/DVD/vmlinuz
        APPEND initrd=centos7/x86_64/DVD/initrd.img ramdisk_size=100000 ip=dhcp inst.repo=http://100.1.1.100/pxe_install_images/CentOS/7.0-DVD/x86_64/

LABEL CentOS 7 x86_64 Minimal
        MENU LABEL Install CentOS 7.0-1406 x86_64 Minimal
        KERNEL centos7/x86_64/minimal/vmlinuz
        APPEND initrd=centos7/x86_64/minimal/initrd.img ramdisk_size=100000 ip=dhcp inst.repo=http://100.1.1.100/pxe_install_images/CentOS/7.0-minimal/x86_64/

LABEL CentOS 6.6 x86_64 Minimal
        MENU LABEL Install CentOS 6.6 x86_64 Minimal
        KERNEL centos6/x86_64/minimal/vmlinuz
        APPEND initrd=centos6/x86_64/minimal/initrd.img ramdisk_size=100000 method=http://100.1.1.100/pxe_install_images/CentOS/6.6-minimal/x86_64/

LABEL debian7_install
        MENU LABEL Install Debian Stable (Wheezy) Desktop/Server amd64
        KERNEL debian7/amd64/linux
        APPEND initrd=debian7/amd64/initrd.gz -- quiet

Выглядит это безобразие вот так:
PXE NetInstall Menu

Проверял виртуалбоксом и железными компами — работает отлично! Чего и Вам желаю.

Хай щастить!

    • Алик
    • Март 9th, 2015 10:21дп

    отличная статья спасибо.
    а как такое можно сделать для установки дистрибутивов Windows 7 и 8

    • admin
    • Март 9th, 2015 12:55пп

    @Алик
    Я с виндой уже много лет не дружу, незнаю что там. Но google выдает что это возможно. Например:
    http://rus-linux.net/MyLDP/win-lin/windows-over-pxe-from-linux.html

    • Николай Пономарев
    • Октябрь 3rd, 2015 7:19пп

    Увы.. К великому сожалению, это еще один из авторов, который советует то, что не работает.

    > Как я и говорил в начале статьи, мне нужно розшарить по HTTP
    > инстал-диски CentOS 6/7. Сделал я это с помощью nginx. Для начала
    > установим его:
    > [root@cent6 ~]# yum install nginx

    выполняю (чтобы не было вопросов по моей «косорукости» — тупое «копи-паст) и получаю

    [root@linux etc]# yum install nginx
    Загружены модули: fastestmirror, langpacks
    Loading mirror speeds from cached hostfile
    * base: mirror.yandex.ru
    * extras: mirror.yandex.ru
    * updates: mirror.yandex.ru
    Пакета с названием nginx не найдено.
    Ошибка: Выполнять нечего

    • admin
    • Октябрь 4th, 2015 3:59пп

    @Николай Пономарев
    Попробуйте добавить epel репозитарий
    # yum install epel-release
    После этого уже nginx
    # yum install nginx

    • Пономарев Николай
    • Октябрь 8th, 2015 5:15пп

    [root@localhost sysconfig]# systemctl restart xinetd.service

    [root@localhost sysconfig]# systemctl status xinetd.service
    xinetd.service — Xinetd A Powerful Replacement For Inetd
    Loaded: loaded (/usr/lib/systemd/system/xinetd.service; enabled)
    Active: active (running) since Чт 2015-10-08 17:13:19 MSK; 8s ago
    Process: 7927 ExecStart=/usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid $EXTRAOPTIONS (code=exited, status=0/SUCCESS)
    Main PID: 7928 (xinetd)
    CGroup: /system.slice/xinetd.service
    └─7928 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid

    окт 08 17:13:19 localhost.localdomain xinetd[7928]: removing echo
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: removing echo
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: removing tcpmux
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: removing time
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: removing time
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: xinetd Version 2.3.15 started with libwrap loadavg labeled-networking options compiled in.
    окт 08 17:13:19 localhost.localdomain xinetd[7928]: Started working: 1 available service
    окт 08 17:13:18 localhost.localdomain systemd[1]: Starting Xinetd A Powerful Replacement For Inetd…
    окт 08 17:13:18 localhost.localdomain systemd[1]: PID file /var/run/xinetd.pid not readable (yet?) after start.
    окт 08 17:13:19 localhost.localdomain systemd[1]: Started Xinetd A Powerful Replacement For Inetd.

    [root@localhost sysconfig]# systemctl status tftp.service
    tftp.service — Tftp Server
    Loaded: loaded (/usr/lib/systemd/system/tftp.service; static)
    Active: failed (Result: resources)

    окт 08 16:36:23 localhost.localdomain systemd[1]: Starting Tftp Server…
    окт 08 16:36:23 localhost.localdomain systemd[1]: tftp.service failed to run ‘start’ task: Invalid argument
    окт 08 16:36:23 localhost.localdomain systemd[1]: Failed to start Tftp Server.
    окт 08 16:36:23 localhost.localdomain systemd[1]: Unit tftp.service entered failed state.

    • admin
    • Октябрь 9th, 2015 8:00дп

    @Пономарев Николай
    а что при этом в /var/log/messages ?

    • Пономарев Николай
    • Октябрь 13th, 2015 12:40пп

    ввиду многочисленных косяков, возникших при допиливании настроек, было принято решение — начать с нуля, т.е. полностью переустановить CentOS 7.

  1. Трэкбэков пока нет.

Why ask?