7.6.3.4. Particularidades¶
7.6.3.4.1. Soporte multiarquitectura¶
Advertencia
Dicutiremos una solución para soportar BIOS y UEFI, aunque este último arranque siempre ha sido un poco problemático con syslinux. En principio, debe funcionar, aunque depende mucho de que la implementación PXE del firmware UEFI de la placa base no sea deficiente, como pasa en muchas ocasiones. La configuración se ha comprobado con OVMF que es una implementación de UEFI que utilizan Virtualbox o QEmu.
Nota
Si se quieren hacer pruebas con máquinas virtuales, deberá saber cómo arrancarlas en UEFI. Si se utiliza QEmu es necesario:
Instalar el paquete qemu-efi.
Utilizar como tarjeta de red virtio-net.
Añadir al ejecutable de qemu la opción -bios /usr/share/ovmf/OVMF.fd.
Ya se ha comentado que un ordenador puede disponer de BIOS, si es más antiguo,
o de UEFI, si más moderno. Tal es así que nuestra estructura de ficheros está pensada para atender esta circunstancia. Sin embargo, en la
configuración propuesta se carga de manera incondicional
bios/pxelinux.0
, por lo que sólo somos capaces de dar soporte a clientes
PXE con BIOS o, si son UEFI, en modo compatibilidad con BIOS (Legacy).
Sin embargo, comienzan a aparecer placas sin esta compatibilidad, por lo que sólo
dar soporte a clientes BIOS empieza a no ser adminisible.
La solución, no obstante, es conceptualmente bastante sencilla: detectar de qué
tipo de arquitectura es el cliente y enviar el fichero adecuado:
bios/lpxelinux.0
, efi32/syslinux.efi
o
efi64/syslinux.efi
. Al determinar éste cuál es el directorio de
trabajo, el resto de módulos necesarios también será de la arquitectura
apropiada. Así pues, el objetivo es modificar la configuración del servidor
DHCP (o del PXE dependiendo del escenario).
De acuerdo con el RFC 4578, el cliente PXE debe enviar la opción DHCP 93 con un número que identifica la arquitectura:
Tipo |
Nombre de la arquitectura |
CSA en dnsmasq |
---|---|---|
0 |
Intel X86PC |
x86PC |
1 |
NEC/PC98 |
PC98 |
2 |
EFI Itanium |
IA64_EDI |
3 |
DEC Alpha |
Alpha |
4 |
Arc x86 |
Arc_x86 |
5 |
Intel Lean Client |
Intel_Lean_Client |
6 |
EFI IA32 |
IA32_EFI |
7 |
EFI BC |
BC_EFI |
8 |
EFI Xscale |
Xscale_EFI |
9 |
EFI x86-64 |
X86-64_EFI |
10 |
EFI ARM32 |
ARM32_EFI |
11 |
EFI ARM64 |
ARM64_EFI |
Además, cambía tambien el valor enviado al servidor para la opción 60, que es de la forma «PXEClient:Arch:00NN:UNDI:XXXX». «NN» coincide con el número expuesto en la tabla: 00 para el primero tipo, 06 para el 6 y así sucesivamente.
Dependiendo de si el servicio PXE es independiente (segundo y tercer escenarios) o está incluido en el DHCP (1º escenario), habrá que hacer una cosa u otra.
7.6.3.4.1.1. DHCP¶
Si la información de red la facilita directamente el servidor DHCP entonces tendremos explícitamente que analizar la opción 93.
7.6.3.4.1.1.1. dnsmasq¶
dhcp-match=bios,93,0
dhcp-match=efi32,93,6
dhcp-match=efi64,93,7
dhcp-match=efi64,93,9
dhcp-boot=tag:bios,bios/lpxelinux.0
dhcp-boot=tag:efi32,efi32/syslinux.efi
dhcp-boot=tag:efi64,efi64/syslinux.efi
Y, si queremos que generar configuraciones dinámicas, esto es, menús de arranque cuyas entradas dependan del cliente que realiza la petición, entonces tendremos que obtener el fichero de configuración a través del protocolo HTTP:
dhcp-option=bios,encap:43,210,http://192.168.255.1/boot/bios/
dhcp-option=efi32,encap:43,210,http://192.168.255.1/boot/efi32/
dhcp-option=efi64,encap:43,210,http://192.168.255.1/boot/efi64/
7.6.3.4.1.1.2. Servidor del ISC¶
Hay que hacer exactamente lo mismo que en dnsmasq, aunque la sintaxis es algo más verborreica:
option arch code 93 = unsigned integer 16;
if option arch = 00:06 {
filename "efi32/syslinux.efi";
} elsif option arch = 00:07 or option arch = 00:09 {
filename "efi64/syslinux.efi";
}
else {
filename "bios/lpxelinux.0";
}
Adicionalmente, podemos enviar la opción 210 para adelantar un paso del proceso de arranque.
7.6.3.4.1.2. PXE¶
Recordemos que dijimos que la forma de prestar el servicio era incluir esta línea:
pxe-service=x86PC,"Servicio de clonaciones",bios/lpxelinux.0
pero sin dar demasiadas explicaciones. El primer argumento es el tipo de arquitectura del cliente y la línea solamente se envía si el tipo de la línea coincide con el del cliente. Por tanto, nos basta con repetir la línea para las distintas arquitecturas que soportemos:
pxe-service=x86PC,"Servicio de clonaciones",bios/lpxelinux.0
pxe-service=IA32_EFI,"Servicio de clonaciones",efi32/syslinux.efi
pxe-service=BC_EFI,"Servicio de clonaciones",efi64/syslinux.efi
pxe-service=x86-64_EFI,"Servicio de clonaciones",efi64/syslinux.efi
Ahora bien, esta configuración no envía la opción 210 y en consecuencia, no podremos descargar por HTTP la configuracióni de syslinux. Para hacerlo necesitamos enriquecer la configuración:
dhcp-match=bios,93,0
dhcp-match=efi32,93,6
dhcp-match=efi64,93,7
dhcp-match=efi64,93,9
# Configuración para BIOS
pxe-service=x86PC,"Servicio de clonaciones",bios/lpxelinux.0
dhcp-option=tag:bios,encap:43,vendor:PXEClient,210,http://192.168.255.2/boot/bios/
pxe-prompt="Leyenda escondida...",0
# Configuración para EFI32
pxe-service=IA32_EFI,"Servicio de clonaciones",efi32/syslinux.efi
pxe-service=IA32_EFI,"Servicio de clonaciones",efi32/syslinux.efi
dhcp-option=tag:efi32,encap:43,vendor:PXEClient,210,http://192.168.255.2/boot/efi32/
# Configuración para EFI64
pxe-service=BC_EFI,"Servicio de clonaciones",efi64/syslinux.efi
pxe-service=BC_EFI,"Servicio de clonaciones",efi64/syslinux.efi
pxe-service=x86-64_EFI,"Servicio de clonaciones",efi64/syslinux.efi
pxe-service=x86-64_EFI,"Servicio de clonaciones",efi64/syslinux.efi
dhcp-option=tag:efi64,encap:43,vendor:PXEClient,210,http://192.168.255.2/boot/efi64/
La configuración requiere una aclaración. En principio, para cada arquitectura basta con encapsular la opción 210 en la 43 como se hace para la arquitectura BIOS, esto es, añadir una línea más. Sin embargo, para UEFI esto no basta, ya que para mejorar la compatibilidad con implementaciones deficientes de PXE en algunos firmwares UEFI, desde la versión 2.76 (véase las notas para esta versión en el changelog) cuando se envía una sola línea de menú PXE, en vez de enviar un menú de una sola línea, se envía directamente la IP del servidor TFTP y el nombre del fichero[1]. Esto provoca que no se envíe la opción 43 y no haya forma de informar a syslinux de que descargue a través de HTTP la configuración.
Para evitar este inconveniente (a costa por supuesto de perder compatibilidad con firmwares defectuosos) duplicamos las líneas de menú y añadimos la directiva pxe-prompt para reducir la temporización a 0. De este modo, se envía menú (pero sin percatarnomos de ello) y, como efecto secundario, sí se envía la opción 210.
7.6.3.4.2. Soporte para varias redes¶
Hasta ahora hemos supuesto que queremos dar servicio a una sola red y no a varias. Cuando se da este segundo caso es claro que el servidor DHCP tendrá que servir configuraciones de red a todas las redes y que, en consonancia, en el tercer escenario, habrá que definir el servidor proxyDHCP también para todas las redes. El resto de nuestra configuración es casi independiente de cuáles y cuántas sean las redes, y el script PHP es capaz de saber la IP del cliente con lo que conocerá la red de origen, si es que queremos particularizar el arranque para cada red.
Ahora bien, hemos dicho casi y no completamente, porque hay un punto de nuestra configuración que la hemos hecho depender de la IP del servidor y, por tanto, de la red en la que esté. Este punto es el envío de la opción 210 para cambiar del protocolo de TFTP a HTTP:
dhcp-option=encap:43,210,http://192.168.255.1/boot/bios/
Nota
De hecho, si nuestro escenario es el tercero, debíamos cambiar esta IP, por aquella del servidor PXE, que supusimos la 192.168.255.2.
Pues bien, al haber varias redes el servidor dispondrá de varias direcciones, una para cada red y, aunque tomar una de ellas funciona, podría aparecer algún problema si decidimos mantener totalmente separadas las redes impidiendo el acceso mediante cortafuegos de una al resto.
Una excelente solución es valernos del DNS, ya que pxelinux lo soporta y convertir la URL[2]:
http://192.168.255.1/boot/bios/
en:
http://pxeserver/boot/bios/
Tal nombre añadirá el dominio de búsqueda asociado a cada red (p.e. aula.ies, dpto.ies, admon.ies, direccion.ies, etc.) con lo que los nombres serán distintos y cada uno de ellos podremos asociarlo a la IP correspondiente. Configurar bind o dnsmasq para ello es absolutamente trivial.
7.6.3.4.3. Detección de hardware¶
hdt es una herramienta de detección del hardware
integrada como módulo de syslinux (hdt.c32
, que requiere, además,
libmenu.c32
y libgpl.c32
). Por ello, es interesante añadirlo a las
posibiilidades de arranque:
LABEL hdt
MENU LABEL Hardware Detection Tool (HDT)
COM32 hdt.c32
APPEND modules_alias=../cfg/files/hdt/modules.ali pciids=../cfg/files/hdt/pci.ids
Requiere dos ficheros:
pci.ids
, que puede obtenerse del propio sistema dentro del directorio/usr/share/misc
(al menos en debian) o bien descargarse directamente de aquí.modules.ali
, que es una copia demodules.alias
, sito en/lib/modules/$(uname -r)
.
Ambos ficheros pueden comprimirse con gzip, para hacer más ligera la descarga.
7.6.3.4.5. Arranque con iPXE¶
Aunque no hemos profundizado en la configuración de iPXE, éste puede usarse como trampolín para la carga de otro NBP o, mediante la escritura de un script, para presentar directamente un menú de arranque. Bajo este epígrafe nos limitaremos a exponer cómo usarlo, aunque no sea el firmware de arranque por red que use nuestra tarjeta.
En dnsmasq la configuración para el primer escenario (para el segundo y tercero basta con usar la versión con pxe-service) puede ser esta:
dhcp-match=ipxe,175
dhcp-boot=tag:!ipxe,ipxe.pxe
dhcp-boot=tag:ipxe,start.ipxe
donde start.ipxe
es un script de iPXE. La
configuración es tal que, cuando se arranca con un firmware PXE que no es iPXE,
se lanzará iPXE y, cuando se arranca con iPXE, se obtiene el script para
iPXE. La desventaja de este método es que, por lo general, se necesita obtener
IP dos veces, una al obtener el fichero ipxe.pxe
y otra al obtener
posteriormente start.ipxe
. Puede evitarse esto, incrustando el script
start.ipxe
dentro de ipxe.pxe
, pero ello exige recompilar el
programa.
Notas al pie