PXE es una extensión de DHCP, y sus creadores lo hicieron compatible con redes que ya disponían de un servicio DHCP implementado, para que fuese posible tener los servicios separados y sin interferencias entre ellos.

En ese caso, el servidor PXE es en realidad un proxy del servicio DHCP, que añade la funcionalidad PXE pero no realiza la asignación de direcciones IP.

Para implementar este servicio como proxy de DHCP, usaremos dnsmasq, que es una herramienta Linux que combina un servidor DNS, un servidor DHCP y un servidor TFTP; de estos servicios, al menos los dos últimos son necesarios.

El ordenador que vamos a utilizar tiene instalado un Ubuntu 18.04 y, para comenzar, instalaremos los siguientes paquetes:

user@localhost:~$ sudo apt install dnsmasq pxelinux syslinux-common

Una vez instalados estos paquetes, procedemos a configurar el servicio DHCP de dnsmasq:

user@localhost:~$ sudo service dnsmasq stop
user@localhost:~$ sudo nano /etc/dnsmasq.conf

Copiamos lo siguiente en el archivo de configuración:

# Inhabilitamos el servidor DNS
port=0

# Habilitamos el log del servidor DHCP
log-dhcp

# Respondemos a las peticiones PXE en la red indicada;
# corre como un proxy DHCP
dhcp-range=192.168.24.0,proxy 
dhcp-boot=pxelinux.0

# Anunciamos el servicio PXE "Arranque por red".
pxe-service=x86PC,"Arranque por red",pxelinux

# Habilitamos el servidor TFTP
enable-tftp
tftp-root=/netboot/tftp/

Guardamos el archivo /etc/dnsmasq y modificamos el archivo /etc/default/dnsmasq:

user@localhost:~$ sudo nano /etc/default/dnsmasq

Añadiremos lo siguiente al final del archivo:

DNSMASQ_EXCEPT=lo

Sin esta línea, el sistema operativo enviará todas las consultas al servicio DNS a través de dnsmasq; como el servicio DNS está deshabilitado, nuestras consultas no recibirían ninguna respuesta.

Archivos de arranque

Tras realizar la configuración del servicio PXE, vamos a modificar el sistema de archivos para que permita el acceso al arranque a través de la red; para ello, creamos una carpeta donde copiaremos los archivos de arranque, y el menú del servicio:

user@localhost:~$ sudo mkdir -p /netboot/tftp/pxelinux.cfg
user@localhost:~$ sudo nano /netboot/tftp/pxelinux.cfg/default

Copiamos lo siguiente en el archivo default:

default vesamenu.c32

label install_1
    menu label ^Instalar Ubuntu 18.04
    menu default
    kernel ubuntu-18.04/vmlinuz
    append initrd=ubuntu-18.04/initrd boot=casper netboot=nfs nfsroot=192.168.24.2:/netboot/nfs/ubuntu-18.04/ splash toram ---

label install_2
    menu label ^Instalar Ubuntu 18.04 desde internet
    kernel net-install-18.04/linux
    append vga=788 initrd=net-install-18.04/initrd.gz locale=es_ES.UTF-8 keyboard-configuration/layoutcode=es hostname=ubuntu-1804

label boot_1
    menu label ^Iniciar Ubuntu 18.04
    kernel boot/vmlinuz
    append initrd=boot/initrd nfsroot=192.168.24.2:/home/nfsroot ip=dhcp rw

Ahora nuestro servicio PXE ofrece un menú al cliente para que se realice una de varias posibles acciones: arrancar por red o instalar por red.

 

NOTA: Durante el arranque del cliente, éste envía su UUID y su dirección MAC al servidor PXE para que busque la configuración apropiada; si no la encuentra, entonces usará la configuración del archivo default.

Los archivos de configuración se buscan en un orden determinado:

  1. Se busca un archivo con nombre como el UUID del cliente, todo en minúsculas.

  2. Si no lo encuentra, buscará uno con nombre igual al tipo de hardware + dirección MAC.

  3. Si tampoco encuentra este, buscará uno como la dirección IP del cliente en formato hexadecimal.

  4. Por ultimo, intentará encontrar archivos de configuración para las subredes IP en formato hexadecimal.

  5. Cuando no encuentra ningún archivo como los descritos, intentará cargar uno con nombre default.

 

Copiamos los archivos necesarios para que funcione el menú:

user@localhost:~$ sudo cp -v /usr/lib/syslinux/modules/bios/{ldlinux.c32,libcom32.c32,libutil.c32,vesamenu.c32} /netboot/tftp

Una vez copiados estos archivos, el sistema puede arrancar el proceso de instalación por red.

Instalación local

Descargamos un archivos de instalación desde la red, y la copiamos en la carpeta compartida; también copiamos los archivos de arranque de casper y otorgamos permisos:

user@localhost:~$ sudo mount -o loop ubuntu-18.04.05-desktop-amd64.iso /mnt
user@localhost:~$ sudo cp -Rfv /mnt/* /netboot/nfs/ubuntu-18.04
user@localhost:~$ sudo cp -v /netboot/nfs/ubuntu-18.04/casper/{vmlinuz,initrd} /netboot/tftp/ubuntu-18.04
user@localhost:~$ sudo chmod -Rfv 777 /netboot

Editamos ahora el archivo /etc/exports para compartir las carpetas de red:

user@localhost:~$ sudo nano /etc/exports

Copiamos lo siguiente dentro del archivo:

## Entradas del servidor PXE
/netboot/nfs    *(ro,sync,no_wdelay,insecure_locks,no_root_squash,insecure,no_subtree_check)

A continuación, publicamos la carpeta e iniciamos el servicio:

user@localhost:~$ sudo exportfs -rv
user@localhost:~$ sudo service dnsmasq start

Instalación tipo netinstall

Veamos ahora como implementar una instalación desde internet.

Comenzaremos descargando un arranque netinstall del sistema, y a continuación copiaremos los archivos de arranque a una carpeta asociada al menú.

user@localhost:~$ wget http://http://archive.ubuntu.com/ubuntu/ubuntu/dists/bionic/main/installer-amd64/current/images/netboot/netboot.tar.gz
user@localhost:~$ sudo mkdir -p /netboot/tftp/net-install-18.04
user@localhost:~$ sudo tar -xzv netboot.tar.gz --strip-components 3 -C /netboot/tftp/net-install-18.04 ./ubuntu-installer/amd64/{linux,initrd.gz}
user@localhost:~$ sudo chmod -Rfv 777 /netboot/tftp/net-install-18.04

Y con esto ya tenemos la opción de instalar desde internet.

Arrancar un sistema sin discos

Hasta ahora tenemos implementadas las dos opciones "Instalar" del menú. Ahora vamos a implementar la opción de "Iniciar" un sistema Ubuntu 18.04 clonado del local. Para comenzar, creamos las carpetas necesarias:

user@localhost:~$ sudo mkdir -v /netboot/tftp/boot
user@localhost:~$ sudo mkdir -v /home/nfsroot

Necesitamos un sistema Ubuntu 18.04 operativo y funcional para ser usado por todas las máquinas de la red. Hay que optar por una de estas alternativas:

  • debbootstrap: método usado en ocasiones para instalar el servidor Apache con chroot.

  • Copiar la instalación del servidor, que ya está operativa.

  • Hacer una instalación nueva en la máquina cliente, y copiarla al servidor.

Optamos en esta ocasión por la segunda opción, y comenzamos copiando los archivos de arranque:

user@localhost:~$ cp -v /boot/vmlinuz-`uname -r` /netboot/tftp/boot

Ahora vamos a crear el archivo initrd.img para ser utilizado en el arranque por red. Comenzamos editando el archivo /etc/initramfs-tools/initramfs.conf:

# BOOT: [ local | nfs ]
# local - Inicia con los medios locales (disco, cd, usb, etc).
# nfs - Inicia usando un disco NFS para /

BOOT=nfs

A continuación, modificamos la configuración para que los módulos se carguen desde la red, y creamos la lista de módulos incluyendo sólo los que sean estrictamente necesarios:

 
# MODULES: [ most | netboot | dep | list ]
# most - Añade todos los módulos que sean necesarios: framebuffer, acpi, filesystem, y controladores de disco.
# dep - Prueba y determina cuales son los módulos a cargar.
# netboot - Añade los módulos básicos y los de red, pero evita los dispositivos de bloque.
# list - Sólo se incluyen los módulos de la lista 'additional modules'.

MODULES=netboot

Comprobamos en el cliente cuales son los módulos de red necesarios, y añadimos la lista en /etc/initramfs-tools/modules:

user@client:~$ sudo lshw -C network
  *-network                 
       descripción: Ethernet interface
       producto: NetXtreme BCM5754 Gigabit Ethernet PCI Express
       fabricante: Broadcom Inc. and subsidiaries
       id físico: 0
       información del bus: pci@0000:02:00.0
       nombre lógico: enp2s0
       versión: 02
       serie: 00:18:8b:6e:bd:99
       tamaño: 100Mbit/s
       capacidad: 1Gbit/s
       anchura: 64 bits
       reloj: 33MHz
       capacidades: pm vpd msi pciexpress bus_master cap_list ethernet physical tp 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuración: autonegotiation=on broadcast=yes driver=tg3 driverversion=3.137 duplex=full firmware=5754-v3.15 ip=192.168.1.36 latency=0 link=yes multicast=yes port=twisted pair speed=100Mbit/s
       recursos: irq:25 memoria:fe7f0000-fe7fffff

A la vista de esta información, copiaremos "enp2s0" en la lista de módulos. A continuación, creamos la imagen:

user@localhost:~$ sudo mkinitramfs -o /netboot/tftp/boot/initrd.img-`uname -r`

NOTA: Una vez creada la imagen en la carpeta de arranque, debemos dejar los archivos editados como estaban. En caso contrario, cuando se produzca una actualización del kernel y se cree una nueva imagen, el sistema dejará de arrancar.

Procedemos ahora a clonar la instalación de nuestro sistema, para usarla en los clientes de red:

user@localhost:~$ sudo rsync -auvz --exclude 'home' --exclude 'proc' --info=progress2 ../../ /home/nfsroot

Esto copiará todo el sistema a la carpeta /home/nfsroot.

Modificamos ahora la configuración de red del sistema de arranque, porque durante el proceso el servidor DHCP ya ha asignado una IP a la tarjeta de red y no queremos que accidentalmente se le asigne otra diferente al cargar el sistema.

Modificaremos el archivo /home/nfsroot/etc/network/interfaces para que nuestra tarjeta de red se configure de forma manual; esto impedirá la recarga de IP.

auto lo
iface lo inet loopback
iface eth0 inet manual

Modificaremos ahora el archivo /home/nfsroot/etc/fstab para retirar cualquier referencia a los dispositivos de bloque locales, dado que no estarán disponibles. Copiaremos lo siguiente:

/dev/nfs        /               nfs     defaults        1       1
none            /tmp            tmpfs   defaults        0       0
none            /var/run        tmpfs   defaults        0       0
none            /var/lock       tmpfs   defaults        0       0
none            /var/tmp        tmpfs   defaults        0       0

¡Ni siquiera se puede usar swap!

Dado que los sistemas sin disco local no necesitan grub para arrancar, lo mejor es deshabilitar la actualización, editando el archivo /home/nfsroot/etc/kernel/postinst.d/zz-update-grub para comentar la línea exec.

Finalmente, editamos el archivo /etc/exports para compartir las carpetas necesarias para el arranque; copiaremos lo siguiente:

/home/nfsroot   *(rw,no_root_squash,async,insecure)

Publicamos la carpeta:

user@localhost:~$ sudo exportfs -rv

Monitorizar

Si queremos visualizar lo que está ocurriendo con el servidor PXE, usamos el terminal:

user@localhost:~$ journalctl -efu dnsmasq
sep 23 08:37:09 localhost systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
sep 23 08:37:09 localhost dnsmasq[8617]: dnsmasq: sintaxis correcta.
sep 23 08:37:09 localhost systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
sep 23 08:37:09 localhost dnsmasq[8626]: iniciado, versión 2.79 DNS desactivado
sep 23 08:37:09 localhost dnsmasq[8626]: opciones al compilar: IPv6 GNU-getopt DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth nettlehash DNSSEC loop-detect inotify
sep 23 08:37:09 localhost dnsmasq-dhcp[8626]: DHCP, proxy on subnet 192.168.24.0
sep 23 08:37:09 localhost dnsmasq-tftp[8626]: TFTP root está /netboot/tftp
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/pxelinux.0 to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/ldlinux.c32 to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/9c9d68ae-4fd6-11da-b84d-000fb0bb1bd5 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/01-00-0f-b0-bb-1b-d5 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A8182A no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A8182 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A818 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A81 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A8 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0A no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C0 no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: archivo /netboot/tftp/pxelinux.cfg/C no encontrado
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/pxelinux.cfg/default to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/vesamenu.c32 to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/libcom32.c32 to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/libutil.c32 to 192.168.24.42
sep 23 08:38:51 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/pxelinux.cfg/default to 192.168.24.42
sep 23 08:42:47 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/netinstall-18.04/linux to 192.168.24.42
sep 23 08:42:59 localhost dnsmasq-tftp[8626]: sent /netboot/tftp/netinstall-18.04/initrd.gz to 192.168.24.42
sep 23 08:43:51 localhost dnsmasq-dhcp[8626]: 2533296700 available DHCP subnet: 192.168.24.0/255.255.255.0
sep 23 08:43:51 localhost dnsmasq-dhcp[8626]: 2533296700 vendor class: d-i
sep 23 08:43:51 localhost dnsmasq-dhcp[8626]: 2533296700 available DHCP subnet: 192.168.24.0/255.255.255.0
sep 23 08:43:51 localhost dnsmasq-dhcp[8626]: 2533296700 vendor class: d-i
sep 23 08:48:25 localhost dnsmasq-dhcp[8626]: 568859713 available DHCP subnet: 192.168.24.0/255.255.255.0
sep 23 08:48:25 localhost dnsmasq-dhcp[8626]: 568859713 vendor class:  ""
sep 23 08:58:26 localhost dnsmasq-dhcp[8626]: 568859713 available DHCP subnet: 192.168.24.0/255.255.255.0
sep 23 08:58:26 localhost dnsmasq-dhcp[8626]: 568859713 vendor class:  ""

Y esto, más o menos, es todo por hoy.

Para ver toda la oferta de precios necesitas hacer login.