8.1. Interfaces

El kernel de Linux nombra las interfaces físicas de red con un nombre que identifica su tipo seguido de un ordinal que permite distinguirlas en caso de que haya varias de un mismo tipo. De este modo, las interfaces ethernet se nombran eth0, eth1, eth2, etc. o las interfaces inalámbricas wlan0, wlan1, etc. Por su parte, la interfaz virtual de loopback siempre recibe el nombre lo.

El problema de esta nomenclatura es su impredecibilidad. Sus nombres se asignan al cargar su driver correspondiente después de haber sido detectadas y, si hay varias, no hay garantías de que la asignación de nombres se producza siempre en el mismo orden. Por ello, en un equipo con dos interfaces ethernet podría ocurrir que una interfaz que en un arranque se detectó como eth0 se detecte como eth1 en un arranque posterior, lo cual puede tener consecuencias catastróficas si se usaron los nombres de las interfaces para definir reglas en el cortafuegos. Es por esto que SystemD, desde su versión 147 y en conjunción con udev, establece un sistema predecible de nombres que más adelante discutiremos[1].

Nota

Este epígrafe se limita a discutir sobre las interfaces físicas. Algunos tipos de interfaces virtuales se irán introduciendo bajo epígrafes posteriores y otros ya han aparecido en algunas partes del manual (p.e. VPN).

8.1.1. Detección

Como ocurre con todo el hardware durante el proceso de arranque, las tarjetas se detectan automáticamente y podemos consultar en el registro o a través de alguna utilidad adecuada cómo se identificaron ante el núcleo. Por ejemplo, si las tarjetas son PCI, podremos usar lspci:

# lspci | grep -i controler
[...]
01:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32)
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.  RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15)
[...]

Las tarjetas que estén soportadas (esto es, aquellas para las que existe un controlador), recibirán un nombre y aparecen listadas dentro de la jerarquía de /sys:

$ ls /sys/class/net
eno1 lo wlp1s0

Como puede verse ahí aparecen las dos tarjetas físicas, eno1 y wlp1s0[2] (además de la interfaz de loopback), señal de que para ambas había un driver adecuado.

También es posible consultar las interfaces con ip:

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN
mode DEFAULT group default qlen 1000
    link/ether 8c:47:be:45:9a:06 brd ff:ff:ff:ff:ff:ff
3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
mode DORMANT group default qlen 1000
    link/ether 5c:ba:ef:5c:9e:bf brd ff:ff:ff:ff:ff:ff

Esta orden devuelve más información. Por ejemplo, podemos saber que eno1 no tiene conectado el cable, puesto que no aparece LOWER_UP en su descripción.

8.1.2. Nombre

¿Cómo nombran los linuces actuales que utilizan SystemD las interfaces de red? La explicación superficial se encuentra en el artículo Predictable Network Interface Names, que conviene complementar al menos con la página de manual de systemd.net-naming-scheme.

Para construir el nombre se utilizan dos letras para identificar el tipo de interfaz física (en para ethernet o wl para interfaz wifi)[3] seguido de una identificación predecible y única para cada interfaz. Para contruir este identificador SystemD puede utilizar hasta cinco estrategias distintas:

onboard (o)

para la que se utiliza un índice que asigna el firmware a los dispositivos integrados. Por ejemplo, eno1.

slot (s)

para la que se utiliza un número asociado a la ranura PCI utilizada. Por ejemplo, ens1.

path (p)

para la que se utiliza la localización física del conector. Por ejemplo, para las dos tarjetas antes detectadas los nombres serán wlp1s0 y enp2s0, puesto que la salida de lspci nos las ubica en 01:00.0 y 02:00.0 respectivamente.

mac (x)

para la que se utiliza la dirección MAC de la tarjeta. Por ejemplo, enx8c47be459a06 para la interfaz ethernet de nuestro ejemplo (véase la salida de ip link show)

nombre clásico

la cual no es en realidad una estrategia predecible: simplemente es el nombre clásico que asigna el kernel a la interfaz. Se nombrará así, si no ha habido forma de nombrarla mediante un nombre predecible.

Nota

Las interfaces, además, permiten ser renombradas arbitrariamente.

Por lo general, las tarjetas no pueden ser nombradas mediante todas las estrategias. Por ejemplo, la interfaz eno1:

$ udevadm test-builtin net_id /sys/class/net/eno1 2>/dev/null
ID_NET_NAMING_SCHEME=v245
ID_NET_NAME_MAC=enx8c47be459a06
ID_NET_NAME_ONBOARD=eno1
ID_NET_LABEL_ONBOARD=Realtek RTL8111H
ID_NET_NAME_PATH=enp2s0

tiene disponibles nombres para tres estrategias (mac, onboard y path), mientras que wlp1s0 para solamente dos (mac y path):

$ udevadm test-builtin net_id /sys/class/net/eno1 2>/dev/null
ID_NET_NAMING_SCHEME=v245
ID_NET_NAME_MAC=wlx5cbaef5c9ebf
ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD.
ID_NET_NAME_PATH=wlp1s0

Bien, entonces, ¿qué estrategia se sigue si hay varias disponibles? La respuesta la tiene el archivo /lib/systemd/network/99-default.link. Ahí se podrá observar cuál es la precedencia de cada estrategia y se verá que la de onboard es mayor que la de path. Por esa razón, la interfaz cableada se nombró como eno1 y no como enp2s0.

Nota

Compruebe si en el mismo directorio hay algún otro archivo de extensión .link con menor número que afecte al nombrado. En Debian lo hay, aunque sólo afecta al nombrado de las interfaces USB.

Nota

Si por alguna razón se prefiere prescindir de las estrategias de nombrado predecible, basta con añadir el parámetro de arranque net.ifnames=0 editando /etc/default/grub[4].

8.1.3. Renombrado

Es posible alterar los nombres asignados a una o varias interfaces creando archivos de extensión .link dentro del directorio /etc/systemd/network. Para ello hay que tener presente que:

  1. Para los archivos hay, en principio, dos ubicaciones posibles[5]: /lib/systemd/network y la citada /etc/systemd/network. La primera debe reservarse para las configuraciones predefinidas en los empaquetados de Debian, por lo que nos limitaremos a escribir sólo en la segunda de las ubicaciones.

  2. Los archivos, con independencia de cuál sea su ubicación, se ordenan alfabéticamente según su nombre y se asignará sólo la configuración del primer archivo aplicable.

  3. En caso de que los nombres de las dos ubicaciones coincidan tiene prevalencia el incluido en /etc/systemd/network y el menos prioritario no tendrá efecto alguno. Como consecuencia, si el prevalente es un archivo vacío o un enlace simbólico a /dev/null, no habrá configuración relacionada con estos archivos[6].

  4. Para añadir configuración a un archivo podemos crear un subdirectorio que al mismo nombre añada .d (p.e. /etc/systemd/network/99-network.link.d/ para /lib/systemd/network/99-network.link) y dentro de él crear archivos con extensión .conf[7]. En caso de haber varios archivos se mezclan en orden alfabético. Tal estrategia ya la hemos visto al editar servicios.

  5. Los archivos, en formato ini, se componen, fundamentalmente, de dos secciones:

    • [Match], que incluye directivas para determinar si el archivo es aplicable a una interfaz. Para que sea aplicable deben satisfacerse todas las directivas.

    • [Link], que incluye las directivas de configuración

    Nota

    Además del nombre, los archivos .link, permiten definir otras características de la interfaz para las cuales se ha usado tradicionalmente ethtool (p.e la velocidad de transmisión). También permite redefinir la dirección MAC. Échele un ojo al manual de systemd.link.

  6. Para asegurarnos de cuál es el archivo que se ha aplicado a una interfaz, podemos ejecutar la orden:

    $ udevadm info --query=property --value --property=ID_NET_LINK_FILE /sys/class/net/eno1
    /usr/lib/systemd/network/99-default.link
    

Por tanto, si escribiéramos:

# /etc/systemd/network/98-default.link
[Match]
OriginalName=*

[Link]
NamePolicy=mac

y, con todas las interfaces desactivas, forzásemos el renombrado:

# systemctl restart systemd-udev-trigger

las dos interfaces anteriores pasarían a formar el nombre a partir de su MAC. Podemos, por supuesto, dar un nombre concreto a una interfaz (a ser posible que no coincida con un nombre clásico para evitar problemas):

# /etc/systemd/network/70-cableada.link
[Match]
Path=pci-0000:02:00.0

[Link]
Name=cable0

donde para referir la interfaz hemos preferido usar su path inmutable, el cual puede consultarse cuál es con:

$ udevadm info --query=property --value --property=ID_PATH /sys/class/net/eno1
pci-0000:02:00.0

Una alternativa sería mantener el nombre predecible y añadir como nombre alternativo el que gustemos[8], para lo cual podríamos hacer:

# ln -s /lib/systemd/network/99-default.link /etc/systemd/network/98-cableada.link
# mkdir /etc/systemd/network/98-cableada.link.d
# cat > /etc/systemd/network/98-cableada.link.d/alternativo.conf
[Match]
Path=pci-0000:02:00.0

[Link]
AlternativeName=cable0

Nota

Nótese que la configuración de 98-cableada.link sólo afectará a la interfaz de cable y no a la inalámbrica, porque el archivo resultante de aplicar tal configuración y la incluida en el subdirectorio correspondiente contiene dos condiciones en [Match]: la general que cumple cualquier interfaz y la de Path= que sólo cumple ella.

Advertencia

Tenga presente que el nombrado de interfaces se incluye también en el arranque temprano incluido en el archivo initrd.img de su sistema. Podría darse que intente cambiar el nombre de una interfaz editando los archivos como se ha indicado y no tenga efecto la configuración, porque la interfaz ya se nombró en tal arranque temprano y dentro de initrd.img no se haya obrado ningún cambio[9]. Si es así, puede probar a regenerar el archivo:

# update-initramfs -u

Notas al pie