GNU/Linux >> Tutoriales Linux >  >> Linux

Esperando la configuración de red de Linux en el ramdisk inicial (initrd)

Un initrd (ramdisk inicial) es un pequeño sistema de archivos cargado durante el proceso de arranque en un sistema Linux. Una de las tareas de las que podría ser responsable el initrd es la configuración de la red.

Este artículo explica los casos en los que es necesaria la configuración de la red al principio del proceso de arranque, cómo se implementa y las mejoras que trae Red Hat Enterprise Linux 8.3.

La necesidad de un initrd

Cuando presiona el botón de encendido de una máquina, el proceso de arranque comienza con un mecanismo dependiente del hardware que carga un cargador de arranque . El software del gestor de arranque encuentra el kernel en el disco y lo inicia. A continuación, el kernel monta el sistema de archivos raíz y ejecuta un init proceso.

Este proceso suena simple y podría ser lo que realmente sucede en algunos sistemas Linux. Sin embargo, las distribuciones modernas de Linux tienen que admitir un amplio conjunto de casos de uso para los que este procedimiento no es adecuado.

Primero, el sistema de archivos raíz podría estar en un dispositivo que requiere un controlador específico. Antes de intentar montar el sistema de archivos, se debe insertar el módulo de kernel correcto en el kernel en ejecución. En algunos casos, el sistema de archivos raíz está en una partición encriptada y, por lo tanto, necesita un asistente de espacio de usuario que solicite la frase de contraseña al usuario y la envíe al kernel. O bien, el sistema de archivos raíz podría compartirse a través de la red a través de NFS o iSCSI, y montarlo puede requerir primero direcciones IP y rutas configuradas en una interfaz de red.

[ También te puede interesar: Redes de Linux:13 usos para netstat ]

Para superar estos problemas, el gestor de arranque puede pasar al núcleo una pequeña imagen del sistema de archivos (el initrd) que contiene secuencias de comandos y herramientas para encontrar y montar el sistema de archivos raíz real. Una vez hecho esto, el initrd cambia a la raíz real y el arranque continúa como de costumbre.

La infraestructura dracut

En Fedora y RHEL, el initrd se construye a través de dracut . Desde su página de inicio, dracut es "una infraestructura initramfs impulsada por eventos". dracut (la herramienta) se usa para crear una imagen initramfs copiando herramientas y archivos de un sistema instalado y combinándolo con el marco dracut, que generalmente se encuentra en /usr/lib/dracut/modules.d ."

Una nota sobre la terminología:a veces, los nombres initrd y initramfs se usan indistintamente. En realidad, se refieren a diferentes formas de construir la imagen. Un initrd es una imagen que contiene un sistema de archivos real (por ejemplo, ext2) que monta el núcleo. Un initramfs es un archivo cpio que contiene un árbol de directorios que se descomprime como tmpfs. Hoy en día, las imágenes initrd están en desuso a favor del esquema initramfs. Sin embargo, el nombre initrd todavía se usa para indicar el proceso de arranque que involucra un sistema de archivos temporal.

Línea de comandos del núcleo

Repasemos el escenario raíz de NFS que se mencionó anteriormente. Una forma posible de arrancar a través de NFS es usar una línea de comandos del kernel que contenga root=dhcp argumento.

La línea de comandos del kernel es una lista de opciones que se pasan al kernel desde el cargador de arranque, accesibles para el kernel y las aplicaciones. Si usa GRUB, puede cambiarlo presionando la e clave en una entrada de arranque y editando la línea que comienza con linux .

El código dracut dentro de initramfs analiza la línea de comandos del kernel e inicia DHCP en todas las interfaces si la línea de comandos contiene root=dhcp . Después de obtener una concesión de DHCP, dracut configura la interfaz con los parámetros recibidos (dirección IP y rutas); también extrae el valor de la opción DHCP de ruta raíz del contrato de arrendamiento. La opción lleva la dirección y la ruta de un servidor NFS (que podría ser, por ejemplo, 192.168.50.1:/nfs/client ). Luego, Dracut monta el recurso compartido NFS en esta ubicación y continúa con el arranque.

Si no hay un servidor DHCP que proporcione la dirección y la ruta raíz de NFS, los valores se pueden configurar explícitamente en la línea de comando:

root=nfs:192.168.50.1:/nfs/client ip=192.168.50.101:::24::ens2:none

Aquí, el primer argumento especifica la dirección del servidor NFS y el segundo configura el ens2 interfaz con una dirección IP estática.

Hay dos sintaxis para especificar la configuración de red para una interfaz:

ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]

ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<mtu>][:<macaddr>]]

El primero puede usarse para configuración automática (DHCP o IPv6 SLAAC), y el segundo para configuración estática o una combinación de automática y estática. Aquí algunos ejemplos:

ip=enp1s0:dhcp
ip=192.168.10.30::192.168.10.1:24::enp1s0:none
ip=[2001:0db8::02]::[2001:0db8::01]:64::enp1s0:none

Tenga en cuenta que si pasa un ip= opción, pero dracut no necesita conexión en red para montar el sistema de archivos raíz, la opción se ignora. Para forzar la configuración de red sin una raíz de red, agregue rd.neednet=1 a la línea de comando.

Probablemente haya notado que entre los métodos de configuración automática, también está ibft . iBFT significa iSCSI Boot Firmware Table y es un mecanismo para pasar parámetros sobre dispositivos iSCSI desde el firmware al sistema operativo. iSCSI (interfaz de sistemas informáticos pequeños de Internet) es un protocolo para acceder a dispositivos de almacenamiento en red. Describir iBFT e iSCSI está fuera del alcance de este artículo. Lo importante es que al pasar ip=ibft al núcleo, la configuración de la red se recupera del firmware.

Dracut también admite agregar rutas personalizadas, especificar el nombre de la máquina y los servidores DNS, crear enlaces, puentes, VLAN y mucho más. Consulte la página de manual de dracut.cmdline para obtener más detalles.

Módulos de red

El framework dracut incluido en initramfs tiene una arquitectura modular. Comprende una serie de módulos, cada uno de los cuales contiene scripts y archivos binarios para proporcionar una funcionalidad específica. Puede ver qué módulos están disponibles para ser incluidos en initramfs con el comando dracut --list-modules .

Por el momento, existen dos módulos para configurar la red:network-legacy y network-manager . Quizás se pregunte por qué diferentes módulos brindan la misma funcionalidad.

network-legacy es más antiguo y utiliza scripts de shell que llaman a utilidades como iproute2 , dhclient y arping para configurar interfaces. Después del cambio a la raíz real, se ejecuta un servicio de configuración de red diferente. Este servicio no es consciente de lo que network-legacy módulo destinado a hacer y el estado actual de cada interfaz. Esto puede ocasionar problemas para mantener el estado a través del límite del conmutador raíz.

Un ejemplo destacado de un estado que debe mantenerse es el arrendamiento de DHCP. Si la dirección de una interfaz cambia durante el arranque, la conexión a un recurso compartido NFS se interrumpirá y provocará una falla en el arranque.

Para garantizar una transición fluida, se necesita un mecanismo para pasar el estado entre los dos entornos. Sin embargo, pasar el estado entre servicios que tienen diferentes modelos de configuración puede ser un problema.

El network-manager El módulo dracut fue creado para mejorar esta situación. El módulo ejecuta NetworkManager en el initrd para configurar los perfiles de conexión generados desde la línea de comandos del kernel. Una vez hecho esto, NetworkManager serializa su estado, que luego lee la instancia de NetworkManager en la raíz real.

Fedora 31 fue la primera distribución en cambiar a network-manager en initrd por defecto. En RHEL 8.2, network-legacy sigue siendo el predeterminado, pero network-manager está disponible. En RHEL 8.3, dracut usará network-manager por defecto.

Habilitar un módulo de red diferente

Si bien los dos módulos deberían ser en gran medida compatibles, existen algunas diferencias en el comportamiento. Algunos de ellos están documentados en el nm-initrd-generator página de manual En general, se sugiere utilizar el network-manager módulo cuando NetworkManager está habilitado.

Para reconstruir el initrd usando un módulo de red específico, use uno de los siguientes comandos:

# dracut --add network-legacy  --force --verbose
# dracut --add network-manager --force --verbose

Dado que este cambio se revertirá la próxima vez que se reconstruya el initrd, es posible que desee que el cambio sea permanente de la siguiente manera:

# echo 'add_dracutmodules+=" network-manager "' > /etc/dracut.conf.d/network-module.conf
# dracut --regenerate-all --force --verbose

El --regenerate-all La opción también reconstruye todas las imágenes de initramfs para las versiones del kernel que se encuentran en el sistema.

El módulo dracut administrador de red

Al igual que con todos los módulos de Dracut, el network-manager El módulo se divide en etapas que se llaman en diferentes momentos durante el arranque (consulte la página del manual de dracut.modules para obtener más detalles).

La primera etapa analiza la línea de comandos del kernel llamando a /usr/libexec/nm-initrd-generator para generar una lista de perfiles de conexión en /run/NetworkManager/system-connections . La segunda parte del módulo se ejecuta después de que udev se haya asentado, es decir, después de que el espacio de usuario haya terminado de manejar los eventos del kernel para los dispositivos (incluidas las interfaces de red) que se encuentran en el sistema.

Cuando NM se inicia en el entorno raíz real, se registra en D-Bus, configura la red y permanece activo para reaccionar ante eventos o solicitudes de D-Bus. En initrd, NetworkManager se ejecuta en configure-and-quit=initrd modo, que no se registra en D-Bus (ya que no está disponible en el initrd, al menos por ahora) y sale después de llegar al startup-complete evento.

El inicio completo El evento se activa después de que todos los dispositivos con un perfil de conexión coincidente hayan intentado activarse, con éxito o no. Una vez que todas las interfaces están configuradas, NM sale y llama a dracut hooks para notificar a otros módulos que la red está disponible.

Tenga en cuenta que /run/NetworkManager El directorio que contiene los perfiles de conexión generados y otros estados de tiempo de ejecución se copia en la raíz real para que el nuevo proceso NetworkManager que se ejecuta allí sepa exactamente qué hacer.

Resolución de problemas

Si tiene problemas de red en Dracut, esta sección contiene algunas sugerencias para investigar el problema.

Lo primero que debe hacer es agregar rd.debug a la línea de comandos del kernel, lo que permite el registro de depuración en dracut. Los registros se guardan en /run/initramfs/rdsosreport.txt y también están disponibles en la revista.

Si el sistema no arranca, es útil obtener un shell dentro del entorno initrd para verificar manualmente por qué las cosas no funcionan. Para esto, existe un rd.break argumento de la línea de comandos. Tenga en cuenta que el argumento genera un shell cuando el initrd ha terminado su trabajo y está a punto de dar control al proceso de inicio en el sistema de archivos raíz real. Para detenerse en una etapa diferente de Dracut (por ejemplo, después del análisis de la línea de comandos), use el siguiente argumento:

rd.break={cmdline|pre-udev|pre-trigger|initqueue|pre-mount|mount|pre-pivot|cleanup}

La imagen initrd contiene un conjunto mínimo de archivos binarios; si necesita una herramienta específica en el shell de dracut, puede reconstruir la imagen, agregando lo que falta. Por ejemplo, para agregar el ping y tcpdump binarios (incluidas todas sus bibliotecas dependientes), ejecute:

# dracut -f  --install "ping tcpdump"

y luego, opcionalmente, verifique que se hayan incluido correctamente:

# lsinitrd | grep "ping\|tcpdump"
Arguments: -f --install 'ping tcpdump'
-rwxr-xr-x   1 root     root        82960 May 18 10:26 usr/bin/ping
lrwxrwxrwx   1 root     root           11 May 29 20:35 usr/sbin/ping -> ../bin/ping
-rwxr-xr-x   1 root     root      1065224 May 29 20:35 usr/sbin/tcpdump

El generador

Si está familiarizado con la configuración de NetworkManager, es posible que desee saber cómo se traduce una determinada línea de comandos del kernel en los perfiles de conexión de NetworkManager. Esto puede ser útil para comprender mejor el mecanismo de configuración y encontrar errores de sintaxis en la línea de comandos sin tener que arrancar la máquina.

El generador está instalado en /usr/libexec/nm-initrd-generator y debe llamarse con la lista de argumentos del núcleo después de un guión doble. El --stdout La opción imprime las conexiones generadas en la salida estándar. Intentemos llamar al generador con una línea de comando de muestra:

$ /usr/libexec/nm-initrd-generator --stdout -- \
          ip=enp1s0:dhcp:00:99:88:77:66:55 rd.peerdns=0

802-3-ethernet.cloned-mac-address: '99:88:77:66:55' is not a valid MAC
address

En este ejemplo, el generador informa un error porque falta un campo para la MTU después de enp1s0 . Una vez que se corrige el error, el análisis tiene éxito y la herramienta imprime el perfil de conexión generado:

$ /usr/libexec/nm-initrd-generator --stdout -- \
        ip=enp1s0:dhcp::00:99:88:77:66:55 rd.peerdns=0

*** Connection 'enp1s0' ***

[connection]
id=enp1s0
uuid=e1fac965-4319-4354-8ed2-39f7f6931966
type=ethernet
interface-name=enp1s0
multi-connect=1
permissions=

[ethernet]
cloned-mac-address=00:99:88:77:66:55
mac-address-blacklist=

[ipv4]
dns-search=
ignore-auto-dns=true
may-fail=false
method=auto

[ipv6]
addr-gen-mode=eui64
dns-search=
ignore-auto-dns=true
method=auto

[proxy]

Observe cómo rd.peerdns=0 argumento se traduce en ignore-auto-dns=true propiedad, lo que hace que NetworkManager ignore los servidores DNS recibidos a través de DHCP. Puede encontrar una explicación de las propiedades de NetworkManager en la página del manual de configuración de nm.

[ ¿La red se sale de control? Consulte Automatización de redes para todos, un libro gratuito de Red Hat. ] 

Conclusión

El módulo Dracut de NetworkManager está habilitado de forma predeterminada en Fedora y pronto también estará habilitado en RHEL. Brinda una mejor integración entre las redes en initrd y NetworkManager que se ejecuta en el sistema de archivos raíz real.

Si bien la implementación actual está funcionando bien, hay algunas ideas para posibles mejoras. Una es abandonar el configure-and-quit=initrd mode y ejecute NetworkManager como un demonio iniciado por un servicio systemd. De esta forma, NetworkManager se ejecutará de la misma manera que cuando se ejecuta en la raíz real, reduciendo el código que se debe mantener y probar.

Para descartar por completo configure-and-quit=initrd modo, NetworkManager también debería poder registrarse en D-Bus en el initrd. Actualmente, Dracut no tiene ningún módulo que proporcione un demonio D-Bus porque la imagen debería ser mínima. Sin embargo, ya hay propuestas para incluirlo, ya que es necesario para implementar algunas funciones nuevas.

Con D-Bus ejecutándose en el initrd, la poderosa API de NetworkManager estará disponible para otras herramientas para consultar y cambiar el estado de la red, desbloqueando una amplia gama de aplicaciones. Uno de ellos es ejecutar nm-cloud-setup en el initrd. El servicio, enviado en el NetworkManager-cloud-setup El paquete de Fedora obtiene metadatos de la infraestructura de los proveedores de la nube (EC2, Azure, GCP) para configurar automáticamente la red.


Linux
  1. El juego de nombres:Nombrar interfaces de red en Linux

  2. Cómo usar el comando mtr de Linux

  3. Linux:¿participa en la lista de correo del kernel?

  4. Linux:¿partes propietarias o cerradas del kernel?

  5. Linux:¿cómo reenviar tráfico entre espacios de nombres de red de Linux?

Cómo el kernel de Linux maneja las interrupciones

Cómo verificar la versión del kernel en Linux

Linux:¿por qué el kernel no puede ejecutar Init?

Cómo usar el comando netstat en Linux

Cambiar el temporizador del kernel de Linux

¿Cómo carga Linux la imagen 'initrd'?