SSH config de la flota — organización por prefijo

El ~/.ssh/config de pop-os (t640-pop) es el punto de acceso administrativo a toda la flota — 28 hosts entre Trivasa, Conkafecito, GCP, Oracle Cloud y máquinas personales. Al 2026-08-10 se reorganizó por completo: cada alias lleva un prefijo de origen, replicando la misma convención que ya usa Beszel para nombrar sistemas en su dashboard — así el origen de un host se lee de un vistazo en cualquiera de las dos herramientas, sin tener que recordar a qué proyecto pertenece cada alias suelto.

Todo este ~/.ssh/ (config + llaves) sincroniza vía Syncthing entre pop-os y vm-personal — así que en la práctica cualquiera de los dos hosts sirve como jump host con el mismo archivo, y una edición hecha desde vm-personal (ej. corregir un HostName desactualizado) se propaga sola al otro lado. La migración de agentes de Beszel del 2026-08-16 se hizo enteramente desde vm-personal, sobre esta misma copia sincronizada.

Prefijos

PrefijoOrigenEjemplos
TRV_Trivasa, on-premise (192.168.117.x)TRV_ocs, TRV_svr-dev, TRV_svr-api2, TRV_ctunlinux, TRV_svr-gateway
CK_Conkafecito, on-premise (Hyper-V de sr250, vía NetBird)CK_eri-sr250, CK_vm-contpaq, CK_vm-rds, CK_vm-biotime, CK_vm-mpro, CK_vm-test, CK_vm-dev
GCP_Google CloudGCP_hub, GCP_vm-personal, GCP_vm-personal_public
OCI_Oracle Cloud InfrastructureOCI_vm-main, OCI_vm-playground
WS_Workstations personales de EstebanWS_t640-pop, WS_t640-pop-local, WS_raspberrypi

Las identidades de Git (github.com, github-ehalsou, github-claude-skills) se dejaron sin prefijo a propósito — github.com en particular necesita matchear el hostname real que usa git en cualquier git clone git@github.com:... sin alias explícito; renombrarlo habría roto ese flujo.

raspberrypi se reclasificó de TRV_ a WS_ — es una computadora personal de Esteban, no infraestructura de Trivasa, aunque por conveniencia reutiliza la misma llave (trv_onprem_surface) que el resto de los hosts de esa subred.

Renombrar un alias no es gratis: cualquier script, cron o memoria muscular que use el nombre viejo (ssh vm-dev, ssh eri-sr250) deja de funcionar tal cual — hay que actualizarlo al nuevo prefijo (ssh CK_vm-dev, ssh CK_eri-sr250).

hs — listar/seleccionar hosts interactivo

El alias hs (de hosts-ssh, en ~/.dotfiles, repo github.com/ehalso/shell-tools) lee este mismo ~/.ssh/config y numera los hosts para seleccionarlos sin escribir el alias completo. Solo carga en shells interactivos de login — no aparece en type hs desde un shell no interactivo (como el que usa Claude Code por default), hay que invocarlo con bash -lic 'hs' en ese caso.

vm-dev — llave dedicada y acceso por IP local

vm-dev (Conkafecito, ver hosts.md) se agregó el 2026-08-10 con un patrón distinto al resto del vSwitch de Hyper-V: en vez de la llave compartida oracle_conka_surface, tiene su propio par ed25519 (~/.ssh/vm-dev, sin passphrase), generado e instalado en authorized_keys vía una contraseña temporal de un solo uso que dio Esteban en la conversación (no se guarda en ningún lado, ni aquí ni en el repo).

El HostName apunta a la IP local del vSwitch (10.10.20.10), no a la IP overlay de NetBird — porque vm-dev está configurada como routing peer de esa subred completa (ver NetBird y Acceso vía NetBird y PowerShell Direct), la IP local es directamente alcanzable desde cualquier peer de la cuenta nueva sin pasar por el overlay de vm-dev mismo.

Host CK_vm-dev
  HostName 10.10.20.10
  User ubuntu
  IdentityFile ~/.ssh/vm-dev
  IdentitiesOnly yes

Limpieza de los _ip obsoletos de Conkafecito

Los alias eri-sr250_ip, vm-contpaq_ip, vm-rds_ip, vm-biotime_ip y vm-mpro_ip apuntaban a IPs de NetBird (100.124.x.x) de una cuenta que ya no está migrada (ver el hallazgo completo en Acceso vía NetBird y PowerShell Direct) — daban timeout, no error de conexión rechazada, lo cual los hacía parecer temporalmente caídos en vez de estructuralmente rotos. Se eliminaron los cinco y, para eri-sr250/vm-contpaq/vm-rds, el HostName del alias sin sufijo se reapuntó directo a la IP local real del vSwitch (descubierta con un barrido de ping a 10.10.20.0/24, posible gracias al routing peer de vm-dev):

Host CK_eri-sr250
  HostName 10.10.20.207
  ...
Host CK_vm-contpaq
  HostName 10.10.20.6
  ...
Host CK_vm-rds
  HostName 10.10.20.5
  ...

vm-biotime y vm-mpro no respondieron al barrido — se dejaron con su HostName de DNS de NetBird tal cual (aunque esa cuenta no esté migrada, por si se recupera solo) más un comentario dejando constancia de que no se pudieron confirmar ese día.

Actualización 2026-08-16: vm-mpro sí resultó alcanzable (por su HostName de NetBird DNS existente, confirmado con SSH real) — el “no respondió” del 2026-08-10 fue puntual. CK_vm-test tenía HostName 10.10.20.55, dato viejo y erróneo — confirmado contra el listado de clientes DHCP del router de sr250, la IP real es 10.10.20.57; corregido.

Bug de doble salto SSH: operadores sin escapar ejecutan en el host intermedio, no en el destino

Detectado migrando agentes de Beszel el 2026-08-16 — documentado acá porque el patrón de acceso en sí (ssh vm-personal ssh <alias> "<comando>") es el tema central de esta página, no un detalle de Beszel.

El cliente SSH del salto intermedio reconstruye el comando remoto concatenando sus argumentos con espacios simples, sin preservar las comillas del salto anterior. Si <comando> lleva ;, &&, | o un salto de línea sin quedar dentro de una comilla que sobreviva esa reconstrucción, todo lo que sigue al primer operador se ejecuta en el host intermedio (vm-personal), no en el destino — sin ningún error, porque casi cualquier comando de diagnóstico también es válido ahí y la salida parece plausible. No hay ninguna señal visible de que el comando corrió en el host equivocado.

# riesgoso — todo lo que sigue al primer "&&" corre en vm-personal, no en CK_vm-mpro
ssh vm-personal ssh CK_vm-mpro "comando1 && comando2"
 
# seguro — el script completo va por stdin, vm-personal lo parsea con un shell real
ssh vm-personal bash -s <<'EOF'
ssh -o BatchMode=yes -o ConnectTimeout=8 CK_vm-mpro 'comando1 && comando2'
EOF

Para hosts Windows (PowerShell), la mitigación equivalente es codificar el script completo en Base64 (powershell -NoProfile -EncodedCommand <blob>) — sin espacios ni operadores en el argumento, inmune a la reconstrucción del salto intermedio.

Véase también

  • NetBird — cuenta nueva vs. vieja, y el routing peer que hace posible alcanzar 10.10.20.0/24 por IP local
  • Acceso vía NetBird y PowerShell Direct — el hallazgo completo de por qué los peers de Conkafecito no aparecen en la cuenta nueva
  • Acceso SSH entre VMs — el otro patrón de acceso SSH de la flota (jump host vía vm-personal), sin superposición con este
  • Beszel — mismo esquema de prefijos por origen, aplicado a nombres de sistema en vez de alias SSH; también el incidente 2026-08-16 donde se detectó el bug de doble salto
  • Syncthing — cómo ~/.ssh/ termina siendo el mismo archivo en pop-os y vm-personal
  • hosts.md — registro canónico de todos los hosts mencionados aquí