El problema
El GMKtec G11 (AMD Ryzen Embedded R2514) monta dos controladoras de red 2.5GbE Realtek RTL8125 (rev 05), una por cada puerto físico. Con el driver de fábrica r8169 que trae el kernel:
- Una de las dos NIC funcionaba con normalidad (aunque limitada a negociar 1000Mb/s en vez de 2.5G a causa de mi infraestructura).
- La otra nunca levantaba enlace (
Link detected: no), pasara lo que pasara. Descarté cable y puerto de switch como causa cruzando ambos entre las dos tarjetas: el fallo se quedaba fijo en la misma NIC, no viajaba con el cable ni con el puerto.

Este es un problema de compatibilidad conocido entre el driver r8169 del kernel y esta revisión concreta del chip RTL8125 (rev 05), documentado en varios foros de Proxmox y Arch. La solución habitual es sustituirlo por el driver del propio fabricante, r8125, instalado vía DKMS para que sobreviva a las actualizaciones de kernel.
El riesgo a evitar
En un intento anterior, instalar r8125 y bloquear r8169 justo antes de un apt full-upgrade que trajo un kernel nuevo dejó el módulo DKMS compilado solo para el kernel viejo. Resultado: ambas NIC desaparecieron del sistema al reiniciar, obligándome a reinstalar Proxmox desde cero.
La causa real: sin el meta-paquete de headers correcto instalado, un kernel nuevo llega sin sus headers correspondientes, DKMS no puede reconstruir el módulo, y si r8169 ya está en blacklist, ninguna NIC tiene driver disponible — ni siquiera la que funcionaba bien de fábrica.
Plan de instalación, en orden
1. Repositorios (instalación limpia de PVE 9.2)
Una instalación nueva de Proxmox VE 9.2 (Debian Trixie) trae el repo enterprise activado por defecto, que sin suscripción de pago da un 401 al hacer apt update. En Trixie el formato de repos cambió a deb822 (ficheros .sources):
echo 'Enabled: false' >> /etc/apt/sources.list.d/pve-enterprise.sources
echo 'Enabled: false' >> /etc/apt/sources.list.d/ceph.sources # si no usas Ceph
cat > /etc/apt/sources.list.d/pve-no-subscription.sources << 'EOF'
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
apt update2. Comprobar Secure Boot
Un módulo DKMS sin firmar puede compilar perfectamente y aun así no cargar tras reiniciar si Secure Boot está activo. Lo comprobé antes de nada:
dmesg | grep -i secure
mokutil --sb-state 2>/dev/nullSi está activo, lo más simple en un homelab es desactivarlo en la UEFI.
3. El meta-paquete de headers: la pieza que evita romperlo la próxima vez
apt search proxmox-default-headers pve-headers
apt install pve-headers # el nombre exacto depende de la versión de PVE
apt install build-essential dkmsEs importante instalar el meta-paquete (pve-headers, sin versión de kernel fija), no unos headers pinneados a la versión actual. Este meta-paquete sigue siempre al kernel "por defecto" vigente, así que cualquier apt full-upgrade futuro que traiga un kernel nuevo arrastra automáticamente sus headers correspondientes, disparando el hook de DKMS (/etc/kernel/postinst.d/dkms) que reconstruye el módulo antes incluso de reiniciar.
4. Instalar el driver r8125
Usando el paquete DKMS de awesometic/realtek-r8125-dkms (última versión estable en el momento de escribir esto: 9.018.00-1):
wget https://github.com/awesometic/realtek-r8125-dkms/releases/download/9.018.00-1/realtek-r8125-dkms_9.018.00-1_amd64.deb
dpkg -i realtek-r8125-dkms_9.018.00-1_amd64.deb
apt --fix-broken install # solo si dpkg se queja de dependencias
dkms statusDetalle importante: si apt install pve-headers instaló de paso un kernel nuevo (porque ya no coincidía con el "por defecto"), el módulo se compilará para ese kernel nuevo, no para el que tienes arrancado en ese momento. Comprobar con uname -r y, si no coincide con lo que muestra dkms status, reiniciar antes de continuar (es un reinicio de bajo riesgo, todavía no se ha tocado r8169 ni ningún blacklist).
5. La prueba en caliente (y el problema que apareció aquí)
Antes de persistir nada, probé el módulo en caliente desde teclado/monitor local (quitar r8169 puede tirar la sesión SSH si la interfaz de gestión depende de él):
rmmod r8169
modprobe r8125
ip linkLo que pasó realmente: tras el rmmod/modprobe, ambas interfaces físicas desaparecieron por completo de ip link (solo quedaban lo y la interfaz WiFi). lsmod confirmaba que r8125 sí estaba cargado en memoria, y dmesg mostraba únicamente:
r8125: module verification failed: signature and/or required key missingEste mensaje es solo un aviso de "taint" del kernel (Secure Boot estaba desactivado, así que no bloqueaba nada) — el módulo sí se había cargado. El problema real era que r8125 nunca llegó a engancharse (bind) a los dispositivos PCI tras quedar huérfanos por el rmmod de r8169. lspci -k lo confirmaba: aparecían los módulos disponibles (r8169, r8125) pero sin ninguna línea Kernel driver in use:.
La solución fue forzar el bind manualmente:
ls /sys/bus/pci/drivers/r8125/ # confirmar que existe el fichero "bind"
echo 0000:03:00.0 > /sys/bus/pci/drivers/r8125/bind
echo 0000:04:00.0 > /sys/bus/pci/drivers/r8125/bindTras esto, dmesg mostró inmediatamente:
r8125 0000:03:00.0 nic0: renamed from eth0
r8125 0000:04:00.0 nic1: renamed from eth0Las interfaces reaparecieron, pero en estado DOWN (el bind manual por sysfs crea el netdev pero no lo levanta; eso normalmente lo hace ifupdown al arrancar, paso que aquí se salta). Tuve que subirlas a mano para completar la prueba:
ip link set nic0 up
ip link set nic1 up
ethtool nic0 | grep -E 'Speed|Link detected'
ethtool nic1 | grep -E 'Speed|Link detected'Con esto, ambas NIC confirmaron Link detected: yes a 1000Mb/s (el switch/router de la instalación solo negocia a Gigabit, así que no se alcanzaron los 2.5G que soporta el chip — es una limitación del otro extremo del cable, no del driver).
Como efecto colateral, nic0 había salido de vmbr0 durante el lío, cortando la sesión de gestión; la recoloqué con:
ip link set nic0 master vmbr06. Persistir el cambio
Con el driver confirmado funcionando en caliente:
echo "blacklist r8169" > /etc/modprobe.d/blacklist-r8169.conf
update-initramfs -u
rebootTras el reinicio, nic0 volvió a subir sola (por formar parte de vmbr0) ya con r8125 desde el arranque, sin necesidad de ningún bind manual — confirmando que la blacklist + initramfs habían quedado bien aplicados. nic1, al no tener todavía ninguna configuración de red asociada, se quedó DOWN hasta levantarla a mano — comportamiento normal, no relacionado con el driver.
7. Segunda red interna (vmbr1)
Con las dos NIC ya estables, monté vmbr1 sobre la segunda tarjeta para una red interna dedicada (subred 10.50.99.0/24, pensada para los LXC accesibles desde fuera por WireGuard — Pi-hole, AdGuard, gestión de Proxmox, Home Assistant — evitando acumular rutas /32 sueltas en el AllowedIPs):
# /etc/network/interfaces
auto nic1
iface nic1 inet manual
auto vmbr1
iface vmbr1 inet static
address 10.50.99.1/24
bridge-ports nic1
bridge-stp off
bridge-fd 0Importante dejar el campo gateway en blanco en esta bridge — solo puede haber un gateway por nodo, y ya lo tiene vmbr0. Se aplica con ifreload -a.
8. WiFi de emergencia (lección aprendida de un incidente previo)
El GMKtec trae WiFi 6E de serie (wlp2s0). En un incidente anterior con el mini PC que este equipo sustituye (un BMAX B2Plus con un único puerto Ethernet que se averió), eché en falta tener el WiFi disponible configurado de antemano como red de emergencia — estaba presente pero nunca lo había configurado, así que no sirvió de nada en el momento en que hizo falta.
Para no repetir el error, dejé preparado (pero sin arrancar automáticamente) un perfil WiFi en wlp2s0:
apt install wpasupplicant wireless-tools
wpa_passphrase "SSID" > /etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf
# editar el fichero para borrar la línea "#psk=..." en texto plano que queda comentada# /etc/network/interfaces — SIN "auto", para que no arranque sola
iface wlp2s0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant-wlp2s0.confLo probé una vez con ifup wlp2s0 (confirmó IP por DHCP correctamente) y lo volví a dormir con ifdown wlp2s0. Queda listo para activarse con un simple ip link set wlp2s0 up + ifup wlp2s0 el día que ambas NIC fallen a la vez, sin tener que configurar nada a ciegas bajo presión.
9. Actualización completa, al final
Solo entonces, con las dos NIC verificadas y persistentes:
apt full-upgrade
dkms status # confirmar antes de reiniciar si trajo kernel nuevo y compiló para él
rebootResultado final
nic0ynic1funcionando conr8125, persistente tras reinicio, sin intervención manual.vmbr0(gestión) yvmbr1(red interna10.50.99.0/24) operativas.- WiFi de emergencia configurado y dormido.
- Meta-paquete de headers (
pve-headers) instalado, garantizando que futuras actualizaciones de kernel reconstruyan el módulo DKMS automáticamente.
Notas para quien repita este proceso
- El mensaje
module verification failed: signature and/or required key missingendmesges inofensivo con Secure Boot desactivado — no lo confundas con la causa real del fallo. - Si tras un
rmmod/modprobeen caliente las interfaces desaparecen deip link, comprueba primerolspci -kbuscando la líneaKernel driver in use:antes de asumir que el módulo no cargó — puede estar cargado pero sin bind. El bind manual vía/sys/bus/pci/drivers/<driver>/bindes una herramienta útil para diagnosticar (y resolver) esta situación sin necesidad de reiniciar. - Las interfaces "bindeadas" a mano por sysfs no se levantan solas (
state DOWN); hay que subirlas conip link set <if> uppara completar la prueba.