eth0 o enp0s3? Nombres de interfaces de red en Linux

Hoy aprenderemos por qué, en los GNU/Linux systemd, los nombres de las interfaces de red cambiaron, y se dejó de lado el clásico “eth0/eth1/wlan0/etc” por una nueva nomenclatura.


Nombres predecibles en las interfaces de red

Desde la versión v197 de systemd/udev automáticamente se asignan nombres de interfaces de red predecibles y persistentes para todas las interfaces de red Ethernet, WLAN y WWAN, en contra del nombrado tradicional eth0, eth1, wlan0, etc… con la intención de solucionar problemas reales en la detección y configuración de interfaces.

¿Por qué se hace esto?

El esquema clásico para nombrar las interfaces de red aplicado por el kernel permitía asignar nombres del estilo eth0, eth1, eth2, wlan0, wlan1, etc a todas las interfaces de red que tienen drivers detectados.systemd eth0 ethX nombres predecibles interfaces red network linux gnu enp0s3

Como el checkeo de todos los controladores no es generalmente predecible en las tecnologías modernas, esto significa que tan pronto como múltiples interfaces de red estén disponibles, se les asignarán nombres como eth0, eth1, etc, ni bien se detecten, y no hay seguridad de que estos nombres sean los mismos… lo que quiere decir que una interfaz que inicialmente se llama “eth0”, al siguiente inicio del sistema puede llamarse “eth1”.

Como se puede ver, esto puede causar graves inconvenientes de seguridad, por ejemplo, las reglas de un firewall que está codificada para cierto nombre de interfaz serán muy sensibles al cambio del nombre de dicha interfaz de red.

Por mucho tiempo udev asignó nombres del estilo “ethX” a las interfaces de red, e intentó mantenerlos basándose en la dirección MAC del hardware. Esto ocasionó muchos problemas, entre ellos:

  • Se requiere un directorio raíz (root) con permisos de escritura para algunos subdirectorios.
  • El arranque de una imagen del sistema operativo en una computadora da como resultado una configuración cambiada de la imagen original, ya que los nombres de dispositivos deben asignarse al vuelo.
  • En muchos sistemas, las direcciones MAC no son realmente fijas, como en dispositivos embebidos y equipos virtualizados.

No obstante, el mayor problema es que los componentes del espacio de usuario que requieren un nombre compiten contra el núcleo para obtener el suyo, siempre en el espacio de nombres “ethX”, y esta “carrera” por obtener los nombres a veces falla. Como resultado, el soporte para este tipo de nomenclatura fue eliminado en systemd/udev.

Otra solución que se ha implementado es la denominada “biosdevname“, que trata de encontrar información de topología de “slot fijo” en ciertas interfaces de firmware, y utilizarlas para asignar nombres fijos a las interfaces que incorporan su ubicación física en la placa base. En cierto modo, este esquema de nombres es similar a lo que ya se hace de forma nativa en udev para varios nodos de dispositivos a través de los enlaces simbólicos de /dev/*/by-path/. En muchos casosystemd eth0 ethX nombres predecibles interfaces red network linux gnu enp0s3s, biosdevname se aleja de los esquemas de identificación de dispositivos de kernel de bajo nivel que generalmente utiliza udev para estos enlaces simbólicos, y en su lugar inventa sus propios esquemas de enumeración.

Finalmente, muchas distribuciones admiten el cambio de nombre de las interfaces a los nombres elegidos por el usuario (por ejemplo: “internet0“, “dmz0“, …) y descodifican sus direcciones MAC o ubicaciones físicas como parte de sus scripts de red. Esta es una muy buena opción, pero tiene el problema de que implica que el usuario esté dispuesto y sea capaz de elegir y asignar estos nombres.

Asignar nombres fijos basados ​​en información de firmware/topología/ubicación tiene la gran ventaja de que los nombres son completamente automáticos, totalmente predecibles, que permanecen fijos incluso si se agrega o quita hardware (es decir, no se realiza una nueva enumeración) y que el hardware dañado puede reemplazarse sin problemas. Dicho esto, es cierto que a veces son más difíciles de leer que los “eth0” o “wlan0” a los que todo el mundo está acostumbrado, que un nombre del tipo “enp0s3“… de eso no hay duda 😛

¿Qué es lo que cambió en la v197?

Con systemd v197 se ha agregado compatibilidad nativa para una serie de políticas de nombres diferentes en systemd/udevd propiamente dicho, y se hizo un esquema similar al de biosdevname, pero generalmente más potente y más cercano a los esquemas de identificación de dispositivos internos del núcleo.

Los siguientes esquemas de nombres diferentes para las interfaces de red ahora son compatibles con udev de forma nativa, y se se puede ver el orden de selección de las políticas de nombramiento de las interfaces de red.

  1. Si los nombres que incorporan el Firmware/BIOS proporcionan los números de índices para los dispositivos conectados (ejemplo, en01), se aplica esa información. Si no, se utiliza el esquema 2.
  2. Si los nombres que incorporan el Firmware/BIOS proporcionan los números de las ranuras PCI Express (ejemplo, ens1), se aplica esa información. Si no, se utiliza el esquema 3.
  3. Si el hardware incorpora información de ubicación física del conector (ejemplo, enp2s0), se aplica esta política.
    En caso contrario, se aplica el esquema 5 para cualquier otro caso.
  4. Los nombres que incorporan la dirección MAC no es utilizado por defecto, pero está disponible si se quiere implementar (ejemplo, enx78e7d1ea46da).
  5. Si no se pueden aplicar ninguna de las políticas anteriores, se utiliza la nomenclatura tradicional del kernel (ejemplo, eth0, eth1, etc).

Esta política combinada solo se aplica como último recurso. Eso significa que, si el sistema tiene biosdevname instalado, tendrá prioridad. Si el usuario ha agregado reglas udev que cambian el nombre de los dispositivos kernel, estos tendrán prioridad también. Además, cualquier esquema de nomenclatura específico de distribución generalmente tiene prioridad.

¿Que ganamos con este nuevo esquema?

  • Nombres fijos de interfaces de red entre reinicios del sistema.
  • Nombres fijos de interfaces de red incluso si se agrega o remueve hardware, ya que nunca se lleva a cabo una re-enumeración.systemd eth0 ethX nombres predecibles interfaces red network linux gnu enp0s3
  • Nombres fijos de interfaces de red cuando se cambian o actualizan controladores o el mismo kernel.
  • Nombres fijos de interfaces de red incluso si se ha removido una interfaz de red rota y se la cambia por una nueva.
  • Los nombres son determinados automáticamente sin configuraciones adicionales de usuario.
  • Los nombres de las interfaces de red son predecibles completamente… por ejemplo, solo mirando la salida de un lspci podrás saber los nombres que tendrán las interfaces de red en el sistema.
  • Cambiando las configuraciones del hardware no se producirán cambios en el directorio /etc, lo que le da compatibilidad con un directorio “/” de solo lectura.
  • Los nombres de las interfaces de red ahora siguen más de cerca el esquema utilizado por el bloque de alias de dispositivos de bloque (sda1, sda2, sdb6, etc) y otros dispositivos del /dev basados en enlaces simbólicos.
  • Políticas de nombres aplicables tanto cualquier arquitectura, tanto x86 como no.
  • Las mismas políticas para todas las distribuciones de GNU/Linux que adopten systemd/udev.
  • Es fácil salirse de este esquema y configurar nombres a nivel de usuario.

Pero… no todas son rosas… y sí, hay algunos inconvenientes. Con las nomenclaturas previas, prácticamente se garantizaba que los ordenadores equipados con una sola interfaz de red tendrían un simple “eth0“. Con este nuevo esquema, en su lugar, un administrador tendrá que verificar primero el nombre de las interfaces locales antes de invocar comandos que previamente funcionaban con “eth0”.

Y… ¿si quiero desactivar esto? Volviendo al eth0

Para algunos estos nuevos nombres de interfaces de red pueden parecer horribles… pero a no desmoralizarse! Hay algunas opciones para cambiar los nombres de las interfaces:

  1. Deshabilita la asignación de nombres fijos, de modo que los nombres de kernel no predecibles se vuelvan a utilizar. Para esto, simplemente enmascare el archivo .link de udev para la política predeterminada: ln -s /dev/null /etc/systemd/network/99-default.link
  2. Crea tu propio esquema de nombres manual, por ejemplo nombrando sus interfaces “internet0”, “dmz0” o “lan0”. Para eso, cree sus propios archivos .link en /etc/systemd/network/. Ver systemd.link (5) para más información. man 5 systemd.link
  3. Agrega net.ifnames = 0 en la línea de comando del kernel al momento de iniciar el sistema.

Conclusión

Ahora sabemos por qué los las nuevas implementaciones y distros GNU/Linux que están basadas en systemd tienen este importante cambio en los nombres de interfaces.

Se que a muchos les ha disgustado esta nueva forma de nomenclatura, y les resulta incómodo incluso para typear comandos y configuraciones… pero claro está que esta nueva forma de nombrar interfaces de red tiene sus propósitos, y soluciona algunos problemas de detección de hardware.

Esto me recuerda a los dispositivos de bloque, discos y particiones… en un momento un si teníamos un dispositivo solo no había problema, pero con, por ejemplo, dos discos, corríamos el riesgo de que en un inicio el disco sda pasara a llamarse sdb, y el sistema no arrancase… razón por la cual comenzamos a utilizar UUID’s en el archivo /etc/fstab… al final, la solución fue aceptada casi por todos.

Espero les resulte interesante!


Fuentes:

https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c#L20

https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/networking_guide/ch-consistent_network_device_naming