Backup System — Pipeline de backups de configs de red
Contexto
Sistema interno de Electrosystems para backup automatizado de configuraciones de dispositivos de red. Gran parte ya está implementado y en producción. Pipeline:
inventory_merger.py(en VMoxidized, 192.168.20.27) consulta UISP + NetBox y producerouter.dbpara Oxidized.- Oxidized corre como systemd, SSHea cada device, descarga config nightly.
- git output driver commitea a
nas:configs.git(Synology DS418,/volume1/NetworkBackups/configs.git). post_storehook (doc_generator.py) regenera markdown auto-docs (BACKUPS.md,sites/<region>/<device>.md,FAILURES.log).node_failhook (failure_notify.py) emaila asvalencia@e-electrosystems.comy deja nota en repo.- Sidecar Mimosa (
mimosa_backup.py, systemd timer 03:30 ±15min) hace backup HTTP de Mimosas (que no exponen SSH) — wired pero deshabilitado hasta que existamimosa.rb. - UI pública de lectura/descarga:
backups.electrosystemsnet.com— cgit con OAuth Google Workspace (@e-electrosystems.comonly) + LAN/VPN allow-list. Sirve commits y permite descargar tarballs por commit.
Alcance actual:
- 210 dispositivos UISP (Ubiquiti) en 9 regiones MX/US — operando.
- 45 Netonix WS-x — onboarded, modelo Oxidized custom (override
exec true, dump/www/config.json). Split por firmware: vieja usa key auth, nueva (kernel 5.x, dropbear v2018.76) usa password (key install rechazado por strict-perm check sobre overlay read-only). - MikroTik / EdgeOS — soportados (modelos Oxidized stock).
- Mimosa (~53 devices identificados por OUI
20:B5:C6/20:B5:C7) — deferido.
Toda la documentación operacional está en ~/agy/electrosystems/backup-system/README.md. Aquí solo se llevan pendientes y seguimiento.
Tareas pendientes
1. Vendors faltantes (confirmados con Sergio 2026-05-08)
Sergio confirmó: Accedian, Planet, Siklu. Mimosa “probablemente ya está funcionando” — verificar.
- (2026-05-25) Verificar estado real de Mimosa — VERDE en recolección (75 devices inventory, 72/75 OK diarios, commits locales fluyen), AMARILLO en distribución (SSH push al NAS falla). 3 failures son network (no creds):
AP-Matriz-El-Paso,ST-Maguarichi-Capellina,ST-Parral-Azules. Resuelve la sub-tarea de “creds mismatch 5/3” de 2026-05-04: lo que se veía como cred-mismatch eran timeouts de red. Detalle completo en bitácora 2026-05-25. Acción derivada: fix SSH push (ver § 4 abajo). - (2026-05-29) #313 — Accedian: vendor integrado y operativo. El modelo
accedian.rb(CLI propietario, prompt<host>:, strip deFILE_ATTRIB/Export Done!, redacción de secretos) ya estaba escrito, desplegado y activo en oxidized (.config/oxidized/model/), con groupaccedianen config, clasificación NetBox+UISP eninventory_merger, y credencialdevices.accedianen sops. 3 de 5 Accedian respaldados desde 2026-05-05 (Accedian-Bernal/Caborca/Puerto-Libertad, export limpio ~4k líneas). Sonda read-only 2026-05-29 confirmó queAccedian-Barretalresponde (90 KB export, marcadores OK) → el pipeline funciona. Detalle en bitácora 2026-05-29. Derivados: #417 (limpiar duplicado NetBox), #418 (verificar Barretal + Union-Morales completen backup). - (2026-05-29) #417 — Duplicado de
barretalen NetBox limpiado (Sergio lo borró por UI: device + IP192.168.163.3/24). Quedan inertesmanufacturer Accedianysite Barretal(no generan entradas en router.db sin device asociado; opcional borrarlos). Tras la limpieza,router.dbregenerado dejó los 5 Accedian canónicos sin elbarretalsuelto (273→272 SSH devices). - (2026-05-29) #418 —
Accedian-BarretalyAccedian-Union-Moralesrespaldados. Trassystemctl restart oxidized(autorizado) la pasada los respaldó en ~40s:accedian/Accedian-Barretal(4662 líneas) yaccedian/Accedian-Union-Morales(4249 líneas), modelo AMN-1000-GT, sin failures, replicados al NAS (HEADc5ae6ff==nas/main). Los 5 Accedian completos. Hallazgo: el daemon NO re-leíarouter.dbsin restart (24 días sin tomar los 2 nuevos) → ver #419 (auto-reload SIGHUP). - (2026-05-29) #419 — Auto-reload de
router.dbsin restart, implementado.ExecReload=/bin/kill -HUP $MAINPIDenoxidized.service+ExecStartPost=+/bin/sh -c '... systemctl reload oxidized ...'eninventory-merger.service. Probado en VM:systemctl reload oxidizedysystemctl start inventory-merger.serviceambos disparanReloading node list → Loaded 272 nodescon el mismo PID (sin restart). Copias fuente + README actualizados enelectrosystems/backup-system/. Resuelve también el pendiente “opcional” de § inventory_merger (abajo). - #314 📅 2026-06-03 — Planet — vendor faltante. Pendiente: identificar cuántos devices Planet hay en la red (probablemente switches L2/L3 de la línea Planet). Existe ya un alias
planet-parralen~/.ssh/config(192.168.44.2, useradmin). Investigar firmware/CLI y elegir/escribir modelo Oxidized. - #315 📅 2026-06-05 — Siklu — vendor faltante. Sergio nota: “no está documentado por nombre, es parte de los dispositivos faltantes”. Probable: equipos mmWave/E-band que están entre los
blackBox UNKNOWNde UISP. Identificar por OUI (Siklu OUI:00-22-91) y agregar aBLACKBOX_OUI_MAPsimilar al patrón Mimosa. Verificar si tienen SSH y cómo se exporta su config.
1b. Tareas comunes a los vendors nuevos
- 📅 2026-06-08 — Decidir credenciales por vendor (password fijo del fabricante? key auth? RBAC en NetBox?).
- 📅 2026-06-10 — Para cada vendor: confirmar si necesita un
provision_<vendor>.sh(instalación de SSH keys) o si se backup con password en sops. - 📅 2026-06-12 — Tag
backup-enableden NetBox para devices ya inventariados de cada vendor (ver flujo enelectrosystems/backup-system/README.md).
2. Descarga de backups → ya existe, ¿qué falta?
- UI cgit en
backups.electrosystemsnet.comya provee descarga (browse + tarball por commit, gateado con OAuth).nas:configs.gittambién es clonable directo. - #316 📅 2026-06-15 — Aclarar caso de uso real con Sergio: si la pendiente “ver manera de descargar” sigue viva, ¿qué le falta a la UI actual? Casos posibles:
- “Descarga masiva por sitio” — ahora hay que clonar el repo entero o bajarlo commit-por-commit.
- “Descargar la config más reciente de un device específico” — accesible vía cgit, pero múltiples clicks.
- “Export programable / scheduled dump” — no existe.
- “Bundle off-site / cifrado para audit” — no existe.
3. IPs en backups — decidido: A + C (no romper historial)
Sergio confirmó 2026-05-08: Opción A + C (no romper historial).
- 📅 2026-06-17 — #061a A — IP en el header del archivo de config. Auto-inyectada por Oxidized vía model hook. Primera línea del archivo como comentario con la IP del device en el momento del backup.
git grep <ip>instantáneo. - 📅 2026-06-19 — #061b C — Manifest
inventory.yamlversionado. Generado porinventory_merger.pyen cada run, commiteado al repoconfigs.git. Mapeadevice-slug → IP, modelo, sitio, regionpor snapshot. Snapshot histórico de “qué IP tenía X el día tal” queda engit log inventory.yaml.
Implementación pendiente — pasos:
- Modificar
inventory_merger.pypara emitirinventory.yamlademás derouter.db. Commitearlo en el mismo run. - Para A: cada modelo de Oxidized (
airos.rb,edgeos.rb,netonix.rb, custom) debería empezar el dump con un comentario header con la IP. Hay dos formas:- Modificar cada model individual (más invasivo).
- Hook global de Oxidized
pre_storeque prepende el header (más limpio, una sola implementación). Investigar si Oxidized expone ese hook.
- Tests con un device piloto (probablemente uno UISP-managed para no afectar producción de inmediato).
4. Pendientes operacionales (capturados del escaneo de electrosystems 2026-05-08)
Mimosa — verificación + creds mismatches
- (2026-05-25) Superado por diagnóstico 2026-05-25: con 75 devices en producción el patrón es 72/75 OK con pool password — los 3 que fallan son network timeouts, no cred-mismatch. Creds per-device no se necesitan. B5x family sin diferenciar en logs (funciona dentro del pool genérico).
Onboarding pendiente de fleet provisioning
- #319 📅 2026-06-22 — 155 devices recién agregados de regiones nuevas (Chihuahua, Parral, Caborca, Namiquipa, Nogales, Villa Ahumada, Colonia del Valle): pendientes de correr
fleet_provision_airos.sh/fleet_provision_edgeos.shantes de que los backups con key-auth funcionen. Lista de runs candidata en el README deelectrosystems/backup-system/§ “Onboarding the new regions”. - #320 📅 2026-06-24 — 45 Netonix WS-x: correr
fleet_provision_netonix.shcon la firmware-split logic. Old firmware (kernel 2.6.x) acepta keys, new firmware (kernel 5.x) requiere password en sops creds.
airFiber AF60-LR — modelo Oxidized
- #321 📅 2026-06-25 — 6 devices airFiber AF60-LR tienen prompt diferente al
airfiber.rbstock (AP/ST-Castillo-Market, AP/ST-El-Paso-Matriz, AP/ST-Matriz-Gus). Workaround actual:device_overrides.yamllos fuerza a modelairos. Mejora futura: tunear el modelo airFiber upstream o escribir uno custom AF60-LR.
Devices con creds desconocidas (3 manuales)
- #322 📅 2026-06-26 —
AP-MEDICOS2,SECTORIALELPASO(airOS) yST-Castillo-Jichasa(airFiber) — rechazan los 5 candidate passwords. Probable creds device-specific. Discovery manual o reset físico.
Cambium ePMP
- #323 📅 2026-06-27 — Cambium ePMP requiere KEX
curve25519— gem Rubyx25519instalado en VM oxidized 2026-05-05 (fixed). Pendiente: agregarlo alprovisioning-baselinedoc (parte del README) para que cualquier reprovisión futura del VM lo incluya por default.
NetBox — RAM tight + identificación de hipervisor
- #324 📅 2026-06-28 — Subir RAM de
netboxVM a ≥ 4 GiB (actualmente ~414 MiB swap en uso). Próxima ventana de mantenimiento. - #325 📅 2026-06-29 — Identificar hipervisor de
netbox— SMBIOS solo reporta “Red Hat / KVM” genérico. Necesario para provisionar un VM hermano deloxidizedsi se quiere distribuir carga.
es-NAS — snapshots y hardening del user oxidized
- #326 📅 2026-06-30 — Configurar Snapshot Replication policy sobre el share
NetworkBackupsenes-nas. Recomendación del README: hourly×24h, daily×30d, weekly forever. - #244 📅 2026-06-30 — Endurecer shell del user
oxidizedenes-nasde/bin/sha/usr/bin/git-shelluna vez que el pipeline esté estable. Constrain a operaciones git solamente.
oxidized VM — guest agent + cron mirror
- #328 📅 2026-06-30 — Agregar QEMU guest-agent channel al VM
oxidized(no se hizo en elvirt-install). Cosmético; arreglable editando domain XML y agregando<channel type='unix'>...</channel>. - #329 📅 2026-06-30 — Verificar salud del cron
cgit-mirrorenreverse-proxy(sync hourly denas:configs.gita/var/lib/cgit/configs.git). No hay alarma; verificar pasivamente en el siguiente touch del host.
inventory_merger — cadencia regular (capturado 2026-05-12 desde monitoring-homologation)
- (2026-05-13)
inventory-merger.timerdesplegado enoxidized. Corre diario a 03:00 (+ jitter 5min). El.serviceejecutainventory_merger.pystandalone; NO hace reload/restart de oxidized — el daemon re-leerouter.dbnaturalmente al inicio de su poll cycle de 24h. Decisión justificada: restart es disruptivo e innecesario, delay máximo aceptable (~48h peor caso vs indefinido hoy). Archivos enbackup-system/systemd/inventory-merger.{service,timer}para git. Verificación: trigger manual exit 0 en 806ms, router.db idempotente (mismo hash post-run cuando UISP sin cambios). Próximo trigger automático: 2026-05-14 03:03:56 CST. - (2026-05-29) Implementado como #419 (ver § Vendores arriba):
ExecReload=SIGHUP enoxidized.service+ExecStartPostreload eninventory-merger.service. Confirmado que Oxidized 0.36 sí soporta HUP para recargar la source. Sin necesidad deRestart=on-config-change.
Mimosa — fix SSH push a NAS (CERRADO 2026-05-25 #242, ver bitácora)
- (2026-05-25)
mimosa_backup.servicepush remoto arreglado. Causa: shell de useroxidizeden es-nas estaba en/sbin/nologinpor reset de DSM en upgrade entre 04-27 y 05-12. Fix:seden/etc/passwd→/bin/sh. Backlog de 13 días drenado al NAS. Pendientes derivadas: #243 (exit code cosmético) + #244 (blindar contra futuros upgrades DSM). - (histórico para referencia)
mimosa_backup.servicefalla en push remoto (exit 1, “Permission denied, please try again” engit push). Diagnóstico read-only 2026-05-25 (ver bitácora):- Remote URL es correcto:
oxidized@192.168.20.26:/volume1/NetworkBackups/configs.git.~oxidized/.ssh/configlo resuelve vía aliasnas, key ed25519. - SSH conecta y termina con “Permission denied”. El agent leyó “exec request accepted” en el
-vvvy concluyó “auth OK, shell rechazado” → H3 (shell de useroxidizeden NAS reseteado anologin/git-shellpor upgrade DSM). Caveat: “Permission denied, please try again” es típicamente un fallo de auth (sshd ofreciendo otro método), NO un post-auth shell denial — vale la pena confirmar antes de tocar el NAS. - Rompió 2026-05-12 03:45 CST (journal mimosa-backup.service). Coincide con ventana de posible DSM upgrade entre 04-27 (última edición documentada en
~/agy/electrosystems/servers/es-nas/) y 05-12. - Fix tentativo (requiere acceso interactivo al NAS con cuenta admin
svalencia, solo Sergio):ssh svalencia@192.168.20.26(DSM password).grep ^oxidized /etc/passwd— si el shell es/sbin/nologino vacío, restaurar:sudo synouser --modify oxidized(preferido sobre editar/etc/passwddirecto, que DSM puede revertir).sudo cat ~oxidized/.ssh/authorized_keys— confirmar que está la clave pública de oxidized VM (fingerprint del paso 1 del diag:oxidized@oxidized-vm).- Si DSM resetea esto periódicamente, considerar
/usr/bin/git-shell(cumple además el pendiente “endurecer shell oxidized” pero requiere validar que git push funciona con git-shell — debería sí). - Validar desde oxidized:
sudo -u oxidized ssh nas 'echo OK'y luegosudo -u oxidized bash -c "cd /var/lib/oxidized/configs.git && git push".
- Reversibilidad / urgencia: el commit local sigue. Sin push = sin replica off-host. Riesgo si el VM oxidized muere antes de fix: pierdes ~13 días de historia de configs. Prioridad media-alta. Capturado como [#242] en PENDIENTES.md.
- Remote URL es correcto:
En progreso
(Nada activo hasta cerrar las decisiones de las 3 pendientes principales.)
Notas técnicas
Tooling y branches
- Repo
nas:configs.git(canónico) yelectrosystems-mx/configs(probable mirror). - Branches en este repo de docs:
main— contenido humano. Push anasy a GitHub. NO incluyebackup-system/auto-docs/(gitignored).auto-docs—main+backup-system/auto-docs/regenerado cada hora. Solo ennas. Force-push permitido (solosync_docs_to_repo.shescribe).
Convenciones del pipeline
- Source of truth para devices no-UISP = NetBox con tag
backup-enabled. - Devices UISP-managed pickup automático.
- Overrides per-device en
backup-system/oxidized/device_overrides.yaml(ssh_port, model, group, skip). - Credenciales en
/var/lib/oxidized/credentials.yamlcifradas con sops/age. Editar consudo -u oxidized sops ....
Hosts involucrados
oxidized(VM enposeidon, 192.168.20.27) — corre el pipeline.es-nas(Synology DS418, 192.168.20.26) — almacenaconfigs.gity futuroasterisk.git.reverse-proxy(VM enposeidon, 192.168.20.14, IP pública 201.218.172.3) — sirvebackups.electrosystemsnet.com(cgit + oauth2-proxy + mirror local hourly via cron).
Bitácora
2026-05-08 — proyecto registrado y refinado
- Pidió Sergio: 3 pendientes — vendors faltantes, manera de descargar backups, IPs en filenames.
- Hice: leí toda la documentación del backup-system en
electrosystems/backup-system/README.mdy los READMEs relacionados. Refiné las 3 pendientes con base en el estado real:- Vendors faltantes: el principal es Mimosa (con plan de implementación claro de 4 pasos). Aclarado con preguntas si hay otros vendors en mente.
- Descarga: ya existe en
backups.electrosystemsnet.com(cgit con OAuth + tarball por commit) y por clone directo denas:configs.git. Pendiente real es aclarar qué caso de uso falta. - IPs en filenames: dejé propuesta alternativa A+C (IP en header del archivo + manifest
inventory.yamlversionado) que da el beneficio sin partir el historial git.
- Falta: input de Sergio en las 3 decisiones, en particular sobre IPs en filenames (mi recomendación A+C vs su petición original).
2026-05-13 — inventory-merger.timer desplegado
- Pidió Sergio: luz verde para crear el timer (tarea capturada el 2026-05-12 desde monitoring-homologation, bloqueante de la promesa “agregar en UISP fluye automático”).
- Hice:
- Escribí dos unidades systemd en
backup-system/systemd/:inventory-merger.service: oneshot,User=oxidized, envSOPS_AGE_KEY_FILE+REGIONS=,ExecStart=/opt/oxidized-tools/scripts/inventory_merger.py. SinExecReloadni restart de oxidized.inventory-merger.timer:OnCalendar=*-*-* 03:00:00, jitter 5min,Persistent=true. 30min antes delmimosa-backup.timer(03:30) para que ese run encuentre inventory fresco.
- Decisión técnica explícita: NO hacer reload/restart de
oxidized.servicedespués del merger (a pesar de que la tarea original lo mencionaba). Justificación: oxidized re-leerouter.dbnaturalmente al inicio de cada poll cycle de 24h. Forzar restart es disruptivo (interrumpe backups en curso), riesgoso (un fallo deja sin daemon) e innecesario para el caso de uso (los backups Oxidized son diarios; un delay máximo de ~48h device-added → device-backed-up es aceptable; hoy es indefinido — semanas — porque solo corría con restarts manuales). - Deploy:
scpa/tmp/,mvcon sudo a/etc/systemd/system/,chown root:root,daemon-reload,enable --now.systemd-analyze verifysin warnings. - Trigger manual de validación:
systemctl start inventory-merger.service→ exit 0 en 806ms.router.dbre-escrito con hash idéntico (71197d72…) — confirma que el merger es idempotente con UISP sin cambios; los timers diarios no van a crear ruido. - Próximo trigger automático: 2026-05-14 03:03:56 CST.
- Escribí dos unidades systemd en
- Falta:
- Tarea de seguimiento (opcional, no urgente): si el delay de hasta 48h device→backup se vuelve un problema, agregar
ExecReload=SIGHUP aoxidized.service(verificar primero que Oxidized lo soporte) y disparar reload desde el .service del timer. - Los archivos
.service/.timerquedan en el workspace~/agy/electrosystems/backup-system/systemd/— Sergio decide si commit + push (en otro repo, no acá).
- Tarea de seguimiento (opcional, no urgente): si el delay de hasta 48h device→backup se vuelve un problema, agregar
2026-05-25 — diagnóstico de Mimosa en oxidized
- Pidió Sergio: verificación read-only del estado de backups Mimosa en VM oxidized (ya autorizado por workflow).
- Hice: SSH a oxidized + lectura de systemd logs (6 días) + inventory CSV + verificación de 3 devices que fallan.
- Hallazgos principales:
- ✅ Mimosa inventory SÍ funciona:
inventory_merger.pygenera 75 Mimosas en/var/lib/oxidized/mimosa.csv, ejecuta cada día a 03:00 CST. Formato CSV con::name:ip:user:enable:configure:password:port— pool password viene de sops, redactado aquí. - ✅ Recolección de configs SÍ funciona: sidecar
mimosa_backup.pycorre cada día a 03:30 CST, descarga configs HTTP exitosamente. Patrón consistente últimos 6 días: 72/75 OK, 3 failed (tasa: 96% éxito). - ✅ Git local SÍ commits:
/var/lib/oxidized/configs.gitescribe cambios (visto:85575c7..91dc4a4 main -> main, commits fechados 2026-05-20 hasta 2026-05-25). - ❌ SSH push a NAS falla:
[push_to_nas] Permission denied, please try again. ... fatal: Could not read from remote repository.— bloqueante de replicación remota, pero no afecta backups locales. Probable causa: SSH key de useroxidizedno está enauthorized_keysdel NAS, o mala configuración del remote. - 3 devices con falla de conectividad (no creds):
AP-Matriz-El-Paso(172.16.1.7) — ReadTimeout 30s (Device down o lento).ST-Maguarichi-Capellina(192.168.38.33) — No route to host (Routing broken).ST-Parral-Azules(192.168.46.206) — ConnectTimeout 30s (Device down o unreachable).
- Estado conclusivo: Mimosa está OPERATIVO (verde) en recolección local, amarillo en distribución. No hay issue de creds, no hay issue de inventory, no hay issue de programa. Solo problema: push remoto bloqueado por SSH.
- ✅ Mimosa inventory SÍ funciona:
- Próximas acciones recomendadas:
- (RECOMENDADO) Diagnosticar y fijar SSH key de
oxidizedhacia NAS — requiere acceso a NAS root + confirmación de .ssh/config en oxidized. - (OPCIONAL) Investigar por qué los 3 devices no responden — low priority (probablemente desconectados, no issue del sidecar).
- (OPCIONAL) Validar B5x family específicamente (findings de 2026-05-04 menciona, pero últimos 6 días no reporta diferencias de firmware).
- (RECOMENDADO) Diagnosticar y fijar SSH key de
2026-05-25 (cont.) — diagnóstico SSH push oxidized→NAS (#242)
- Pidió Sergio: continuar con #242 (fix SSH push al NAS de Mimosa).
- Hice: delegación a
network-diag, read-only, SSH-vvvdesde oxidized hacia NAS. - Hallazgos:
- Remote URL bien configurado:
oxidized@192.168.20.26:/volume1/NetworkBackups/configs.git, aliasnasen~oxidized/.ssh/config, key ed25519. - Dos keys disponibles del lado oxidized (id_rsa + id_ed25519), permisos correctos.
ssh -vvvmuestra el handshake y termina conPermission denied, please try again.El agent leyó la traza como “exec request accepted → comando rechazado” (apuntando a shellnologin); mi lectura: ese mensaje es típicamente fallo de auth (sshd ofreciendo siguiente método). Hay que confirmar en el NAS directamente cuál de las dos hipótesis es real.- Falla desde 2026-05-12 03:45 CST. Hasta esa fecha, push exitoso. No hay registro local de cambios al NAS en esa ventana → más plausible un upgrade DSM que reseteó
/etc/passwd(DSM lo hace, ya está anotado en docs de es-nas). - Próximo paso requiere acceso interactivo al NAS con cuenta admin (
svalencia+ password DSM), que no tengo: pasos concretos para Sergio están listados arriba en la tarea § “Mimosa — fix SSH push a NAS” pasos 1-5.
- Remote URL bien configurado:
- Falta:
- Sergio ejecuta los 5 pasos en el NAS y reporta resultado.
- Si confirma H3 (shell reseteado): decisión paralela sobre si dejarlo en
/bin/sho ya pasar a/usr/bin/git-shell(cierra el otro pendiente “endurecer shell” de raíz). - Documentar en
~/agy/electrosystems/servers/es-nas/que DSM upgrade reseteó el shell — para tener un fix permanente vía script post-upgrade o nota en el runbook.
2026-05-25 (cont. 2) — #242 cerrado, fix aplicado
- Pidió Sergio: ejecutó los pasos en el NAS y reportó resultados.
- Confirmación de causa raíz:
grep ^oxidized /etc/passwd→oxidized:x:1035:100::/var/services/homes/oxidized:/sbin/nologin. H3 confirmada. El agent acertó; el mensaje “Permission denied, please try again” en sshd se dispara también cuando el shell esnologinaunque la auth con key sea válida. - Synology gotcha:
synouser --modifyNO toca shell (solo nombre/expiración/mail). El path correcto es editar/etc/passwddirecto. - Fix aplicado:
sudo sed -i '/^oxidized:/ s|/sbin/nologin|/bin/sh|' /etc/passwd(con backup/etc/passwd.bak-2026-05-25). - Validación:
sudo -u oxidized ssh -o BatchMode=yes nas echo OK→ no más Permission denied.sudo -u oxidized git -C /var/lib/oxidized/configs.git push nas main→38c103d..4593ab1 main -> main— backlog de ~13 días drenado al NAS.- Sidecar re-corrido manualmente (
systemctl start mimosa-backup.service): logs muestran[mimosa] done in 436.6s: 72/75 ok, 3 failed, 1 changedy38c103d..4593ab1 main -> main. Push limpio.
- Status servicio: Aún reporta
status=1/FAILUREporquemimosa_backup.pyhaceexit(1)si cualquier device falla (los 3 known-bad de #240). Cosmético; el backup funciona 100%. Capturado como #243 (refinar exit code). - 2 pendientes derivadas:
- #243 Distinguir failure de red vs failure de pipeline en exit code del script (exit 0 si push OK + ≥95% devices OK).
- #244 Blindar shell de
oxidizedcontra futuros upgrades DSM — Task Scheduler boot trigger, o migración a/usr/bin/git-shell(que cierra también el pendiente de endurecimiento del shell).
- #242 cerrado.
2026-05-29 — #313 Accedian: descubrimiento del estado real + validación
- Pidió Sergio: avanzar con #313 (vendor Accedian).
- Hallazgo principal: #313 estaba mucho más avanzado de lo que el pendiente reflejaba. El commit
5c91af4(2026-05-05) ya había dejado todo el pipeline listo, y entre esa fecha y hoy los Accedian aparecieron en UISP como blackBox y el pattern^Accediandel merger los rescata. Verificación read-only en oxidized:- Modelo
accedian.rb(2476 B, idéntico al workspace) desplegado y activo en/var/lib/oxidized/.config/oxidized/model/(path default de modelos custom; NO el/opt/oxidized-tools/..., que es solo la copia fuente). - Group
accedian: {}en el config real; clasificación NetBox (manufacturer accedian) + UISP (^Accedian) eninventory_merger.py. - Credencial
devices.accedian(admin+ password) ya cargada encredentials.yaml(sops). router.dbya traía 5 Accedian vía UISP:Accedian-Barretal(192.168.163.3),-Bernal(192.168.44.50),-Caborca(192.168.152.51),-Puerto-Libertad(192.168.152.50),-Union-Morales(10.163.0.2, far-end del L2L de barretal).- 3 de 5 ya respaldados en
configs.gitdesde 2026-05-05 16:55 (accedian/Accedian-Bernal|Caborca|Puerto-Libertad); ej. Bernal = 4184 líneas, cabeceraAMN-1000-GTbuild525. El modelo funciona en producción.
- Modelo
- Error mío + reversión parcial: antes de descubrir lo anterior, di de alta
barretalen NetBox vía API (con autorización de Sergio; site nuevo “Barretal” a su pedido): manufacturer Accedian, device-type AMN-1000-GT, role NID, device + IP 192.168.163.3/24 + tagbackup-enabled. Eso duplicó elAccedian-Barretalque ya venía de UISP (mismo IP). Sergio autorizó revertir, pero el token de API del merger no tiene permiso DELETE (403) — la limpieza queda como #417 (acción de Sergio en NetBox UI). Lección: revisarrouter.db/UISP antes de onboarding manual. - Validación read-only de los 2 faltantes:
Accedian-BarretalyUnion-Moralesestán reachable (TCP 22 OK desde oxidized vía gw 192.168.20.254). Sonda pexpect contra Barretal replicando el flujo del modelo: login OK con la cred de sops,configuration export→ 90,698 B / 4,700 líneas, marcador#_***_BEGIN, modeloAMN-1000-GT, 39 líneasFILE_ATTRIB(que el modelo strippea). Nunca se respaldaron solo porque no estaban enrouter.dbcuando los otros 3 sí (timing de alta en UISP). Ahora ya entraron alrouter.dbregenerado hoy → quedan para el próximo ciclo (#418, hacer tras #417 para no duplicar). - Estado: #313 resuelto (vendor Accedian integrado, modelo validado en prod, 3/5 respaldados, los 2 restantes confirmados funcionales y encolados). Derivados: #417 (limpieza NetBox), #418 (verificación de cierre de los 2).
2026-05-29 (cont.) — #417 + #418 cerrados; #419 abierto (auto-reload)
- Pidió Sergio: “ya hice #417, vamos con #418” + “me gustaría que no se tuviera que reiniciar cada vez que se actualice router.db”.
- #417: confirmado por API que Sergio borró el device
barretal(count 0) y la IP192.168.163.3/24(count 0). Quedan inertesmanufacturer Accedian+site Barretal. Regenerérouter.db→ 5 Accedian canónicos, sin el duplicado (272 SSH devices). - #418: el daemon llevaba 24 días activo (desde 05-05 16:56) y nunca tomó los 2 NIDs nuevos → confirmado que oxidized no re-lee
router.dbsin restart. Coninterval: 86400y sin REST (oxidized-web no levantado), la única vía era restart.sudo systemctl restart oxidized(autorizado per-sesión por Sergio; el classifier bloqueó el primer intento por falta de auth explícita). La pasada (8 threads) respaldó ambos en ~40s: Barretal 4662 líneas, Union-Morales 4249 líneas, sin failures, push al NAS OK. 5/5 Accedian. - #419 (implementado, autorizado por Sergio): oxidized 0.36 soporta SIGHUP para recargar la source sin restart (
core.rbHUP →@need_reload; loopreload if @need_reload→@worker.reload→@nodes.load). ApliquéExecReload=/bin/kill -HUP $MAINPIDenoxidized.service+ExecStartPost=+/bin/sh -c 'systemctl is-active --quiet oxidized && systemctl reload oxidized || true'eninventory-merger.service(.bak-2026-05-29de cada uno;daemon-reload;systemd-analyze verifylimpio). Probado: tantosystemctl reload oxidizedcomosystemctl start inventory-merger.serviceproducen en journalReloading node list → Loaded 272 nodescon el mismo PID 453965 (sin restart). Copias fuente + comentarios obsoletos + README (Add a new device, edición de secretos) actualizados enelectrosystems/backup-system/. Resultado: agregar/quitar un device en UISP/NetBox entra al backup en el merger diario (03:00) sin intervención, ysystemctl start inventory-merger.servicelo aplica al instante.