NetBird

NetBird es la malla VPN privada (WireGuard) que conecta todos los hosts de Esteban entre sí, sin depender de reglas de firewall de la nube. Decisión de diseño explícita: todos los clientes de Glances se monitorean por su IP de NetBird, nunca por IP privada de VCN ni abriendo puertos — más simple, no depende de tocar la consola de OCI, y ya se tenía NetBird desplegado en casi todos los hosts de todos modos.

Las computadoras personales (pop-os, minibook) también son peers de la misma malla, pero por un motivo distinto al de las VMs: no se monitorean con Glances, se usan para tener acceso administrativo remoto a la infraestructura (SSH, gcloud, etc.) sin exponer nada a internet.

Migración de cuenta en curso (2026-08-09)

Esteban cambió de cuenta de NetBird. Los peers no se mueven solos entre cuentas — cada host necesita reconectarse a mano con una setup key nueva de la cuenta destino. Migrados: pop-os, vm-backup, vm-playground, vm-main, vm-personal. Pendiente: minibook — no está en ningún ~/.ssh/config de la flota (dispositivo personal sin ruta de acceso remoto conocida), así que la migración ahí tiene que hacerse en persona/local, no por SSH.

vm-personal se migró por su IP pública (vm-personal_public en ~/.ssh/config), nunca por su propia IP de NetBird — cortar el túnel a mitad de un netbird down estando conectado sobre ese mismo túnel habría dejado la sesión colgada a medio migrar.

Efecto colateral: todo lo que apunta a una IP de NetBird fija se rompe al migrar

La IP de NetBird de un host cambia por completo al re-registrarse en la cuenta nueva (rango 100.71.x.x en vez de 100.124.x.x). Cualquier servicio de ese host que esté bindeado a la IP vieja en vez de escuchar en todas las interfaces se queda sordo — el proceso sigue active según systemd, pero escuchando en una IP que ya no existe en wt0. Se encontraron y corrigieron dos casos, ambos por diseño intencional de bindear solo a NetBird (ver Samba y Glances):

  • Samba en vm-playground: interfaces = en /etc/samba/smb.conf seguía en 100.124.53.166/16 → corregido a 100.71.230.199/16 y systemctl restart smbd.
  • Glances: el flag -B <ip> de glances-agent.service en vm-main, vm-backup y vm-playground, más los server_N_name de glances.conf en el hub (vm-playground) — todos corregidos a las IPs nuevas y reiniciados. vm-personal no tiene agente de Glances instalado todavía, así que no aplicó ahí.

Checklist para la próxima migración de cuenta (minibook, o cualquier host futuro): después de migrar, grep del host por la IP de NetBird vieja en configs de servicios (smb.conf, systemd units con -B/--bind, docker-compose.yml, glances.conf/config de hubs) antes de dar la migración por terminada — el netbird status en verde no garantiza que todo lo que dependía de esa IP se haya dado cuenta del cambio.

Gotcha de la migración: netbird up --setup-key <key> no basta si el host ya tenía una identidad de peer registrada (de la cuenta vieja) — el cliente reutiliza el keypair existente en /var/lib/netbird/default.json y solo reconecta a esa misma cuenta, ignorando la key nueva en silencio (sin error). Pasó exactamente eso en el primer intento con vm-backup: siguió reportando los peers de la cuenta vieja pese a la key nueva. Para forzar el cambio de cuenta hace falta borrar la identidad local antes de reconectar:

netbird down
systemctl stop netbird
rm -f /var/lib/netbird/default.json   # fuerza un keypair y registro nuevos
systemctl start netbird
netbird up --setup-key <key-de-la-cuenta-nueva>

Señal de que sí migró: la IP de NetBird cambia (nueva identidad, nuevo peer) y netbird status dejar de listar los peers de la cuenta vieja.

Routing peer para la LAN de casa

pop-os (t640-pop) está configurado como routing peer de NetBird para la red local de casa, 192.168.54.0/24 — expone esa LAN a los demás peers de la malla sin necesidad de VPN adicional ni de que cada dispositivo de casa corra NetBird. Verificado end-to-end desde vm-backup: ping a 192.168.54.1 (gateway) y 192.168.54.102 con 0% de pérdida a través del túnel.

Nota operativa: la ruta no se refleja en netbird networks list/netbird routes list de cada peer hasta que el Network Resource tiene una política de acceso en el dashboard que incluya el grupo de ese peer — un peer recién migrado a la cuenta nueva puede mostrar Networks: - aunque el routing peer ya esté publicando la red, simplemente porque todavía no tiene la política asignada.

vm-dev (Conkafecito, Hyper-V) es el mismo patrón para la subred del vSwitch de sr250, 10.10.20.0/24 — ver Acceso vía NetBird y PowerShell Direct para el porqué (los peers individuales de las VMs Windows de ese vSwitch se quedaron en la cuenta vieja, no migrada).

Doble instancia en un mismo host — vm-personal (ehalsou + conkafecito)

Un mismo host puede ser peer de dos cuentas de NetBird a la vez, siempre que cada cuenta corra su propio daemon — el CLI de NetBird soporta “profiles” (netbird profile add/select) pero esos son excluyentes entre sí en un mismo daemon: seleccionar un perfil nuevo desconecta el que estaba activo, porque comparten la misma interfaz de kernel. No sirven para tener dos cuentas conectadas simultáneamente, solo para alternar manualmente entre identidades en un daemon que de todos modos está limitado a una interfaz.

Para las dos conectadas al mismo tiempo hace falta un segundo daemon completo, instalado como servicio systemd independiente, con su propio config, socket de control e interfaz de kernel. En vm-personal (2026-08-10), junto al servicio netbird (default, cuenta ehalsou) se instaló netbird-conka (cuenta conkafecito):

sudo mkdir -p /var/lib/netbird-conka /var/log/netbird-conka
sudo netbird service install \
  -s netbird-conka \
  -c /var/lib/netbird-conka/config.json \
  --daemon-addr unix:///var/run/netbird-conka.sock \
  --log-file /var/log/netbird-conka/client.log
sudo systemctl enable --now netbird-conka
netbird up --daemon-addr unix:///var/run/netbird-conka.sock \
  --interface-name wt-conka --wireguard-port 51821 \
  --setup-key <setup-key-de-la-cuenta-conkafecito>

Gotcha: por default cada daemon intenta crear la interfaz wt0 y escuchar WireGuard en el puerto 51820 — ambos valores fijos independientemente del --daemon-addr. El primer intento con netbird-conka reportó Connected (el canal de control con el management server sí se autenticó) pero no había interfaz de kernel real: ip addr show wt0 solo mostraba la IP de la cuenta ehalsou, la de conkafecito no estaba en ningún lado. El fix es forzar --interface-name y --wireguard-port distintos en el segundo daemon (wt-conka / 51821 en este caso) — con eso sí aparecen las dos interfaces con IP propia (ip -brief addr show).

Para operar cada instancia por separado, siempre hay que pasar --daemon-addr apuntando al socket correcto (sin el flag, apunta al daemon default):

netbird status --daemon-addr unix:///var/run/netbird-conka.sock
netbird down   --daemon-addr unix:///var/run/netbird-conka.sock
netbird up     --daemon-addr unix:///var/run/netbird-conka.sock

El servicio queda enabled — sobrevive reinicios y reconecta solo (auto-connect por default).

Gotcha nuevo (2026-08-16): las dos instancias comparten la tabla de ruteo del kernel

--interface-name y --wireguard-port distintos (arriba) resuelven el conflicto de interfaz de WireGuard, pero no el de rutas: ambos daemons instalan sus rutas selected en la misma tabla fija del kernel, 7120 (nombre netbird en /etc/iproute2/rt_tables, con una sola regla ip rule apuntando ahí por fwmark 0x1bd00) — valor hardcodeado en el binario de NetBird, sin flag de netbird up/service run para aislarlo por instancia (confirmado revisando --help de ambos subcomandos).

Síntoma: netbird routes list muestra la red de vm-dev (10.10.20.0/24) como Selected, y netbird status --detail muestra el peer Connected con handshake reciente — pero ip route show table netbird está completamente vacía, y cualquier IP de esa subred da 100% de pérdida de paquetes, incluida la IP local del propio routing peer. Los dos daemons compiten por escribir en la misma tabla y ninguno gana de forma consistente entre reinicios.

sudo systemctl restart netbird.service (el daemon dueño de esa ruta) la reclama y aparece de inmediato en ip route show table netbird — pero no es un fix permanente: si netbird-conka.service se reinicia después (tiene Restart=always, así que puede pasar solo, no solo a mano), puede volver a pisarla sin aviso. Un aislamiento real requeriría un network namespace separado por daemon — evaluado, no aplicado todavía por el alcance que implica tocar la red de vm-personal en producción. Detectado y reparado al migrar agentes de Beszel que dependían de esta ruta para llegar a Conkafecito.

IPs conocidas

  • vm-playground: 100.71.230.199 (cuenta nueva, desde 2026-08-09)
  • vm-main: 100.71.231.234 (cuenta nueva, desde 2026-08-09)
  • vm-backup: 100.71.112.105 (cuenta nueva, desde 2026-08-09)
  • vm-personal: 100.71.92.49 (cuenta nueva/ehalsou, desde 2026-08-09) — segunda identidad netbird-conka (cuenta conkafecito, interfaz wt-conka): 100.124.91.60, desde 2026-08-10
  • pop-os (t640-pop): 100.71.24.35 (cuenta nueva, desde 2026-08-09)
  • vm-dev: 100.71.169.39 (cuenta nueva, desde su alta), routing peer de 10.10.20.0/24
  • minibook (minibook-pop): 100.124.141.13 (cuenta vieja — pendiente, ver arriba)

Peer duplicado pendiente de limpiar: al reinstalar minibook con Pop!_OS se generó un peer nuevo (minibook-pop) con una identidad de máquina distinta a la del peer viejo (esteban-minibook, de la instalación anterior en Ubuntu/Zorin). El viejo sigue apareciendo en el dashboard de NetBird sin poder conectar — hay que borrarlo a mano desde ahí, netbird no lo hace solo. Esto queda obsoleto una vez que ambos hosts terminen de migrar a la cuenta nueva (el peer viejo no existirá ahí).

Véase también

  • Glances — caso de uso principal de esta malla
  • Docker — por qué los contenedores de este host necesitan network_mode: host para llegar a la IP de NetBird propia
  • Acceso SSH entre VMs — acceso administrativo entre hosts, complementario a NetBird (NetBird es para tráfico de aplicación, no para SSH)
  • Claude Code remoto — visualizar outputs (Rich) desde el cel — alternativa privada al túnel público de Cloudflare para servir un output HTTP efímero
  • SSH config de la flota — organización por prefijo — dónde vive el alias vm-dev y por qué los _ip viejos de las VMs de sr250 se reemplazaron por IPs locales
  • Acceso vía NetBird y PowerShell Direct — el otro lado del routing peer de vm-dev, con el detalle de por qué las VMs Windows de ese vSwitch no aparecen como peers en la cuenta nueva
  • Beszel — incidente 2026-08-16 donde el hallazgo de la tabla de ruteo compartida se hizo evidente, migrando agentes que dependían de la ruta a Conkafecito