# NetGrip

English | Español

Sitio web Demo en vivo Release Licencia Cobertura

Cada servicio de tu router OpenWrt, detrás de un interruptor que puede pulsar tu familia.
NetGrip es un panel companion que corre en el propio router, junto a LuCI: WireGuard, WiFi de invitados, QoS, DNS y más, un clic cada uno, con snapshot, comprobación de salud y rollback automático si algo sale mal.

Prueba la demo en vivo · Visita la web

Resumen de NetGrip: tarjetas de sistema y WAN, gráfico de tráfico en vivo y panel de puertos ethernet, en tema claro

## Míralo antes de instalarlo - **[demo.netgrip.cloudless.club](https://demo.netgrip.cloudless.club)** corre el panel real con datos de ejemplo: pulsa cada interruptor, abre cada tarjeta, no se aplica nada en ningún sitio. - **[netgrip.cloudless.club](https://netgrip.cloudless.club)** lista **todas y cada una de las funcionalidades**, pantalla a pantalla, con el razonamiento detrás de cada una. ## ¿Por qué NetGrip? Seguía entregándoles routers OpenWrt a personas que solo quieren WiFi y una VPN que funcionen. LuCI es una herramienta para ingenieros: cada toggle te pide una sección, una interfaz y una opción. Los portales del fabricante son más amables, pero son apps cerradas que solo funcionan en su firmware. Yo quería la máquina intermedia: el router de verdad, detrás de botones que pueda pulsar un familiar. NetGrip toma los servicios que LuCI ya expone vía rpcd y les pone un interruptor delante. Lo pulsas, y NetGrip hace snapshot de la config, aplica el cambio, espera, comprueba que el servicio levantó, y se deshace solo si no fue así. Cuatro reglas lo dan forma: - **Vive en el router.** Un único binario Go estático con la UI embebida (12-15 MB en disco según arquitectura, y ~16-18 MB de RAM en uso, medidos en routers reales), empaquetado como `.apk`/`.ipk` real de OpenWrt que sobrevive al sysupgrade. Sin contenedores, sin caja extra, sin Node en un router y sin LuCI: sirve su propia UI y habla directo con rpcd/ubus de OpenWrt, siendo `ethtool-full` su única dependencia extra. - **Seguro por construcción.** Cada cambio pasa por un executor con allowlist, con snapshot de config y rollback automático. El panel no puede salirse del camino trazado. - **Se adapta al dispositivo.** El mismo binario lee la caja donde corre y muestra solo lo que aplica allí: un router, un punto de acceso o un switch gestionado reciben cada uno las pantallas que tienen sentido, y lo que necesita algo que esa caja no tiene (una radio, un uplink, un paquete) simplemente se aparta. - **Sin cuentas nuevas.** El login se valida contra rpcd, la misma sesión que usa LuCI; un admin por router, nada extra que administrar. AGPL-3.0, sin premium de ningún tipo. ## Qué te llevas **Un resumen que responde a "¿está todo bien?"** Salud del sistema, estado WAN y tráfico en vivo en una sola pantalla, más un chasis ethernet con estado por puerto, nombres de dispositivo y detección de switches no gestionados. Es la captura de arriba. **Clientes que se pueden gestionar de verdad.** Cada estación con velocidad y señal, reservas de IP en un clic, bloqueo y límites de ancho de banda por dispositivo.

Página de clientes: tabla ordenable con nombres, tipo de conexión, señal y uso por cliente

**Una tarjeta por servicio, cada una con su interruptor real.** WireGuard (peers con código QR) y OpenVPN (`.ovpn` listo para descargar), DNS con protección rebind, SQM basado en cake con nota de bufferbloat, DDNS, WiFi de invitados e IoT en subredes aisladas, reenvío de puertos y un conmutador router/AP que mueve el rol WAN sin editar `network` y `firewall` a mano.

Página de servicios con tarjetas de WireGuard, DDNS, SQM y el firewall visual

**Cuidado del sistema sin ceremonia.** Acceso y sesión, tarjetas de seguridad, asistente de primer arranque, auto-actualización (el panel se actualiza a sí mismo en el sitio, sin reinstalar), actualizaciones de firmware vía owut/ASU que reconstruyen la imagen con tus paquetes dentro, y la malla de roaming dibujada como grafo radial vía usteer.

Página de sistema con acceso, seguridad, modo Router/AP y tarjetas de actualización

**Y más:** análisis de tráfico avanzado por aplicación (netifyd) con timeline de 24 h, la entrada opcional `luci-app-netgrip` bajo LuCI > Servicios, e interfaz ES/EN que cambia en un clic. Y esto todavía no es todo: **[en la web están todas las funcionalidades](https://netgrip.cloudless.club)**, cada una con sus capturas a tamaño real. **Agente de NetPulse integrado.** El mismo binario reporta métricas, eventos WiFi y clientes a [NetPulse](https://netpulse.cloudless.club): el router aparece etiquetado como NetGrip en su flota sin instalar nada más. Es una capacidad adicional, no un requisito: si no usas NetPulse, nada cambia. **MQTT y Home Assistant, si los quieres.** Opcional y desactivado por defecto: apúntalo a un broker MQTT y Home Assistant descubre el router solo. Publica el estado en `netgrip//state` y crea **23 entidades**: 17 sensores (CPU, núcleo más cargado, temperatura, memoria, uptime, modo, versión, clientes totales/WiFi/cable/débil, señal WiFi mínima y media, y tráfico de entrada y salida de la red local), 4 interruptores (WiFi de invitados, banIP, IPv6 y SQM) y 2 botones (recargar los feeds de banIP y reiniciar). Los interruptores y botones actúan: Home Assistant manda la orden por `netgrip//command/...` y el router contesta en `netgrip//result`. Se configura desde la tarjeta MQTT de la página Sistema, o escribiendo `/etc/netgrip/mqtt.env` (permisos 600). La tarjeta prueba la conexión antes de guardar, y un servidor de NetPulse puede enviarle la configuración del broker al router (aplicada con el mismo snapshot-y-rollback que cualquier otro cambio). Con TLS: el certificado se verifica contra las raíces del sistema, con una casilla para aceptar uno autofirmado. No se publica nada hasta que lo actives. **Asistentes de IA (MCP), si los quieres.** NetGrip puede exponer un endpoint local de [MCP](https://modelcontextprotocol.io/) para que un asistente de IA consulte el estado del router en su propio vocabulario. Está desactivado por defecto y la primera tanda de tools es de solo lectura: 1. Actívalo y pon un token: `uci set netgrip.mcp='mcp'; uci set netgrip.mcp.enabled=1; uci set netgrip.mcp.token=; uci commit netgrip` (el primer comando crea la sección; un `uci set netgrip.mcp.enabled=1` directo en una instalación nueva falla con "Invalid argument"). 2. Apunta tu cliente MCP a `http://:8080/mcp` (o el puerto que use el panel) y envía el token como `Authorization: Bearer `. El endpoint nunca acepta la cookie de sesión del navegador, responde 404 mientras está desactivado y tiene rate limit por IP (60 peticiones/minuto por defecto, ajustable con `uci set netgrip.mcp.rate_per_min=`). Los tools (`server_status`, `list_clients`, `wireless_status`, `wan_status`, `multiwan_status`, `list_leases`, `list_devices`) leen las mismas sondas y cachés que el panel, y cada llamada queda en el log. ## Lista de funcionalidades | Área | Qué te llevas | | --- | --- | | Resumen | Salud del sistema, estado WAN, gráfica de tráfico en vivo, chasis ethernet por puerto, detección de switch no gestionado | | Clientes | Velocidad y señal por estación, IPs reservadas, bloqueo, límite de ancho de banda por dispositivo | | LAN y DHCP | Reservas, rango, tiempo de concesión | | IPv6 | Servidor / relay, DNS anunciado | | Dual WAN | Políticas y reparto de mwan3 | | Modo router / AP | Mover el rol WAN sin editar network y firewall a mano | | WiFi | SSID, WPA2/WPA3, canal y ancho, potencia, separar o unificar bandas, red oculta | | WiFi invitados e IoT | Subredes aisladas, un interruptor cada una | | Malla / roaming | Grafo radial, 802.11r/k/v vía usteer | | VPN | WireGuard (servidor + cliente, peers con QR) y OpenVPN (servidor + cliente, descarga .ovpn) | | DNS | Protección contra rebinding | | QoS | SQM/cake con nota de bufferbloat | | DDNS | Actualización DNS dinámica | | Redirección de puertos | Redirects DNAT | | UPnP | miniupnpd / NAT-PMP | | Firewall | Reglas de tráfico y políticas de zona | | Control parental | Horarios de internet por dispositivo | | Tráfico | Análisis por aplicación (netifyd), línea de 24 h | | Historial de uso | Totales diarios y mensuales (vnstat + nlbwmon) | | Protección | Feeds de banIP y detección de AdGuard Home | | Almacenamiento USB | SMB (ksmbd o samba) + DLNA | | Asistente inicial | Configuración guiada | | Auto-actualización | Actualización en sitio con firma del binario verificada | | Firmware | Reconstrucción owut/ASU con tus paquetes dentro | | Seguridad | Snapshots de config, rollback automático, temporizador de confirmación anti-bloqueo | | Copia de seguridad | Descargar y restaurar la config | | Administración | Acceso, sesión, seguridad, contraseña, reinicio programado | | Software | Lista de paquetes vía apk/opkg | | Logs | Log del sistema | | MQTT / Home Assistant | Discovery + 23 entidades (sensores, interruptores, botones) | | Agente de NetPulse | Telemetría de flota integrada, opcional | | LuCI | No lo necesita; entrada opcional luci-app-netgrip | | MCP | Endpoint con token Bearer y tools de solo lectura para agentes | | Idioma | ES / EN | ## Ponlo en tu router Requisitos: un target amd64, ARM64, ARMv5/6/7, MIPS little-endian o MIPS big-endian compatible, con OpenWrt 24.10 o 25.12. El instalador consulta al gestor de paquetes la arquitectura exacta del router y elige el paquete y ABI Go genérico correspondientes. El panel escucha en el puerto 8090 y entra con tus credenciales de LuCI. SSH al router y ejecuta: ```sh wget -qO- https://raw.githubusercontent.com/gnacho/netgrip/main/install.sh | sh ``` El script elige el paquete correcto para la arquitectura y el gestor del router (`apk` en OpenWrt 25.12+, `opkg` en 24.10), instala la última release, habilita y arranca el servicio, e imprime la URL del panel. ¿Prefieres revisarlo antes? Lee [install.sh](install.sh). Para fijar versión: `NETGRIP_VERSION=vX.Y.Z sh install.sh`. Abre `http://:8090` y entra con el mismo usuario y contraseña que usas en LuCI.
Instalación manual (paquetes) Descarga el paquete correcto desde la página de [releases](https://github.com/gnacho/netgrip/releases/latest) y, en el router: ```sh # OpenWrt 25.12 (apk; el sufijo es la arquitectura genérica del binario) apk add netgrip--r1-arm64.apk # OpenWrt 24.10 (ipk; el sufijo es la arquitectura exacta del paquete) opkg install netgrip_-1_aarch64_cortex-a53.ipk /etc/init.d/netgrip enable && /etc/init.d/netgrip start ``` El postinst añade el binario, el init y el enlace rc.d a `/etc/sysupgrade.conf`, así que el panel vuelve tras una actualización de firmware. El paquete opcional `luci-app-netgrip` incrusta el panel bajo LuCI > Servicios de la misma forma.
Instalación manual (binario suelto) y build desde fuente Un binario suelto funciona, pero muere en cada actualización de firmware; el paquete es el camino recomendado. ```sh # dropbear de busybox no tiene scp; mejor por pipe: cat netgrip-linux-arm64 | ssh root@ "cat > /usr/sbin/netgrip && chmod 755 /usr/sbin/netgrip" /usr/sbin/netgrip -listen 0.0.0.0 -port 8090 ``` Compilar desde fuente requiere Go 1.24+ y Node 22+: ```sh git clone https://github.com/gnacho/netgrip.git cd netgrip cd app && npm ci && npm run build && cd .. VERSION=dev sh deploy/build-binaries.sh ``` Ese comando compila el frontend una vez y genera binarios genéricos para amd64, ARM64, ARMv5/6/7, mipsle y mips en `dist/`. Puedes pasar uno o más targets, como `linux-armv7` o `linux-mipsle`, para compilar solo esos binarios.
Referencia para curiosos: flags, servicio y API JSON Flags (los defaults sirven para casi cualquier router): | Flag | Default | Descripción | | --- | --- | --- | | `-listen` | `0.0.0.0` | Dirección a la que bindear. | | `-port` | `8090` | Puerto. El firmware GL.iNet sirve su propia web en el 8080, de ahí el default. | | `-rpcd-url` | `http://127.0.0.1/ubus` | Endpoint JSON-RPC de rpcd para validar el login. | El timeout de sesión se cambia desde la tarjeta Acceso de la UI (`options.main.session_timeout` en UCI). El servicio corre con procd: ```sh /etc/init.d/netgrip status logread -e netgrip -f /etc/init.d/netgrip restart ``` Detrás de cada tarjeta hay una API JSON, la misma que usa el frontend: lecturas por `GET /api/board`, `/api/system`, `/api/wan`, `/api/wifi`, `/api/lan`, `/api/dns`, `/api/usteer`, `/api/clients`, `/api/netifyd`, `/api/dpi/apps`, `/api/dpi/timeline` y `/api/nftqos`; escrituras por los `POST` correspondientes (`/api/wireguard`, `/api/openvpn`, `/api/sqm`, `/api/guestwifi`, `/api/iotwifi`, `/api/portforward`, `/api/netifyd`, `/api/nftqos`) con forma `{ "state": ..., "rolled_back": ..., "status": "applied|rolled_back|failed" }`. Toda escritura exige cookie de sesión.
## Qué viene Reciente: integración con Home Assistant sobre MQTT (estado, sensores e interruptores/botones que actúan, descubiertos automáticamente), siete ABI Go genéricos por release de amd64 a MIPS, e interfaz bilingüe cuyo idioma del documento sigue al idioma activo. Lo siguiente: un feed de paquetes propio para que owut/ASU conserve NetGrip dentro de tu imagen de firmware ([#63](https://github.com/gnacho/netgrip/issues/63)) y mantener la demo pública al día del panel. Las ideas y reportes en los [issues](https://github.com/gnacho/netgrip/issues) dirigen qué se construye. ## Desarrollo Stack: Go (binario estático único) + React 19 + TypeScript + Vite + Tailwind, embebido con `go:embed`. Sin base de datos externa. ```sh cd app && npm ci npm run dev # dev server del frontend (el proxy /api está en vite.config.ts) go build -o netgrip ./cmd/netgrip go test ./... ``` En cada tag de release, el CI compila y precomprime el frontend una sola vez, cross-compila siete binarios para ABI Go genéricos y los distribuye en paquetes `.apk`/`.ipk` específicos de cada target mediante el SDK de OpenWrt. El resumen de la release muestra el tamaño de cada binario y del frontend comprimido. Tamaño del binario (assets de release, con la UI embebida): | Arquitectura | Tamaño (aprox) | | --- | ---: | | arm64 | 12,7 MB | | amd64 | 13,8 MB | | armv5 / armv6 | 13,4 MB | | armv7 | 13,3 MB | | mips / mipsle | 15,1 MB | El uso de RAM en ejecución es de ~16-18 MB RSS. Los 12-15 MB son el daemon autónomo entero, no la UI: el runtime de Go más el backend (cliente ubus/rpcd, sondas, MQTT, el agente de NetPulse, self-update) más el frontend embebido. El frontend en sí son ~344 KB gzip; el resto es lo que hace que NetGrip corra autónomo donde una capa solo-UI (como LuCI) pesa unos cientos de KB sobre servicios que OpenWrt ya trae. ## Licencia AGPL-3.0-only. Ver [LICENSE](LICENSE). Construido por gnacho como proyecto personal self-hosted. Si NetGrip te sirve, una estrella en GitHub es la forma de dar las gracias; issues y PRs son bienvenidos.