Sistemas

hpServer: la Wi-Fi que se caía y cómo se cura sola

Diagnóstico completo de un adaptador Realtek RTL8822BU que perdía el enlace:

5 min de lectura

Hace poco mi servidor se quedaba solo. De repente, y sin motivo aparente, dejaba de responder: no podía entrar desde mi ordenador, los servicios que dependían de él se colgaban y durante un rato pareció que la máquina había muerto.

No estaba muerta. Seguía encendida y funcionando. Lo único que fallaba era su conexión a la red: un pequeño adaptador Wi-Fi conectado por USB. Esta es la historia de cómo lo descubrí y de cómo le construí un sistema que se repara solo.

¿Qué es hpServer y por qué me importa?

hpServer es un ordenador viejo reconvertido en servidor doméstico. En él corren servicios internos de casa —almacenamiento, pruebas, automatizaciones— y accedo a él desde cualquier sitio: por SSH (la forma de entrar a un ordenador remoto como si estuvieras delante) y por Tailscale (una red privada que conecta todos mis equipos como si estuvieran en la misma habitación). Aclaración por si alguien se lo pregunta: esta web que estás leyendo no vive aquí, sino en fxserver, otro de mis servidores. Cuando cae, varias cosas de casa dejan de funcionar a la vez, y siempre parece peor de lo que es.

Cómo saber qué ha fallado: pensar por capas

Cuando internet falla, la culpa puede ser de muchos sitios: el ordenador, su adaptador, el router, el proveedor... Una conexión es como una cadena: si un eslabón se rompe, todo lo que viene después deja de funcionar. El truco está en encontrar el primer eslabón roto, porque es el único que hay que arreglar.

Durante una caída miré el estado del Wi-Fi y vi esto:

wlx6c5ab074f239: <NO-CARRIER,BROADCAST,MULTICAST,UP>
state DOWN
Not connected.

Traducido: el sistema le pedía al adaptador "conéctate" y el adaptador no podía. El ping al router (un "¿estás ahí?" que comprueba si una máquina contesta) tampoco recibía respuesta. Con eso descarté de golpe todo lo que venía después: el router, el proveedor, mi red privada... El problema era el primer eslabón: el adaptador.

Descartando sospechosos

Aun así, fui cerrando puertas una a una:

  • Ahorro de energía: ya lo tenía desactivado (a veces el sistema "duerme" los adaptadores para gastar menos).
  • El puerto USB: el problema se repetía en puertos distintos.
  • La señal: buena, con fuerza de sobra.
  • El software del sistema: actualizado. Incluso probé una versión más nueva del sistema entero. El problema siguió igual.

La pista definitiva

El sistema guarda un diario de todo lo que pasa (los famosos "logs"). En ese diario, cada caída dejaba el mismo mensaje: el adaptador pide una confirmación a un mini-programa que vive dentro de él (el "firmware") y no recibe respuesta. Es como hablarle a alguien que se ha quedado dormido.

Y aquí el descubrimiento importante: reiniciar la conexión no servía de nada. Lo que funcionaba era apagar y encender el software del adaptador (el "driver": el programa que hace de traductor entre el sistema y el aparato). Como apagar y encender el router de casa, pero solo del adaptador.

La solución: un vigilante automático

Como el problema volvería a pasar, quería que el servidor se curara solo. Para eso monté un "watchdog", literalmente un perro guardián: un programa pequeño que cada minuto se hace una pregunta muy sencilla —¿hay red?— y si la respuesta es no dos veces seguidas, apaga y enciende el adaptador. En un minuto o dos, la conexión vuelve.

Este es el guion que sigue (la idea está en el párrafo anterior; los detalles, en el código):

#!/bin/bash

IFACE="wlx6c5ab074f239"
ROUTER="192.168.0.1"
MODULE="rtw88_8822bu"
LOG_TAG="wifi-watchdog"

# Si el router responde, todo está bien.
if ping -I "$IFACE" -c 2 -W 2 "$ROUTER" >/dev/null 2>&1; then
    exit 0
fi

logger -t "$LOG_TAG" "Wi-Fi sin conexión. Esperando 10 segundos antes de confirmar..."

# Evitar actuar por un microcorte.
sleep 10

if ping -I "$IFACE" -c 2 -W 2 "$ROUTER" >/dev/null 2>&1; then
    logger -t "$LOG_TAG" "La conexión se ha recuperado sola."
    exit 0
fi

logger -t "$LOG_TAG" "Wi-Fi sigue caído. Reiniciando módulo $MODULE..."

ifdown --force "$IFACE" >/dev/null 2>&1 || true
modprobe -r "$MODULE"
sleep 2
modprobe "$MODULE"
sleep 5
ifup "$IFACE" >/dev/null 2>&1 || true
sleep 10

if ping -I "$IFACE" -c 2 -W 2 "$ROUTER" >/dev/null 2>&1; then
    logger -t "$LOG_TAG" "Wi-Fi recuperado correctamente."
    exit 0
else
    logger -t "$LOG_TAG" "ERROR: no se ha podido recuperar el Wi-Fi."
    exit 1
fi

Fíjate en un detalle: el ping va al router, no a internet. Si un día se cae internet de toda la casa, el vigilante no toca nada: solo actúa cuando el problema es interno, que es el que puede arreglar.

Para que se ejecute solo cada minuto uso el planificador de tareas del sistema (systemd), con dos ficheros muy cortos:

# /etc/systemd/system/wifi-watchdog.service
[Unit]
Description=HPServer Wi-Fi watchdog
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/wifi-watchdog.sh
# /etc/systemd/system/wifi-watchdog.timer
[Unit]
Description=Comprobar Wi-Fi de HPServer cada minuto

[Timer]
OnBootSec=2min
OnUnitActiveSec=1min
AccuracySec=5s
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now wifi-watchdog.timer

La prueba

Instalar un sistema que se autorepara y confiar a ciegas es mala idea. Así que hice una prueba: apagué la conexión a propósito y esperé sin tocar nada.

sudo ifdown --force wlx6c5ab074f239

En poco más de un minuto, el vigilante lo detectó, recargó el adaptador y la red volvió. En el diario del sistema quedó la secuencia completa:

Wi-Fi sin conexión. Esperando 10 segundos antes de confirmar...
Wi-Fi sigue caído. Reiniciando módulo rtw88_8822bu...
Wi-Fi recuperado correctamente.

Cuando todo va bien, el vigilante calla: si no dice nada, es que todo va bien.

Para la próxima vez

# ¿está conectado el Wi-Fi y con qué fuerza?
sudo /usr/sbin/iw dev wlx6c5ab074f239 link

# los errores de red del día (el "diario" del sistema)
sudo journalctl -k -b --no-pager | grep -Ei 'rtw|8822|wlx|firmware' | tail -100

# qué ha hecho el vigilante
sudo journalctl -t wifi-watchdog --since today

# recuperar el Wi-Fi a mano (lo mismo que hace el vigilante)
sudo modprobe -r rtw88_8822bu && sleep 2 && sudo modprobe rtw88_8822bu && sleep 5 && sudo ifup wlx6c5ab074f239

Qué me llevo

Cuando algo "se muere" en casa, casi nunca es el aparato entero: es un solo eslabón de la cadena. Y muchas veces puedes construir algo que lo arregle mientras duermes. Esta vez el eslabón era un adaptador Wi-Fi de veinte euros; el vigilante, media hora de trabajo.

Y la saga continuó: en la siguiente nota, un router viejo del cajón acabó trabajando al revés para que el servidor dejara de depender del Wi-Fi en el día a día.