Registro di rischi e problemi¶
Priorità: 🔴 da risolvere prima della prod · 🟠 prima dell'aggiornamento senza fermo o a breve · 🟡 miglioramento · ⏸️ rimandato per decisione. Stato: aperto salvo diversa indicazione. La colonna "Attività" rimanda al piano.
Infrastruttura e organizzazione (R)¶
| # | Pri | Rischio | Attività |
|---|---|---|---|
| R1 | 🟠 | Monitoraggio della produzione solo sul Raspberry di Michele: il sistema di Michele (192.168.200.220, base dati system_controls, 18 server e servizi) controlla l'infrastruttura e avvisa su Telegram nel gruppo "Controllo Infrastrutture", che dal 30/10 riceve anche l'ufficio IT (Michele, 30/10). Restano due limiti: quali controlli fa e cosa fare a ogni avviso non è documentato (M-4), e tutto dipende da un Raspberry in ufficio senza backup (R13). Lo stack monitoring esiste ma controlla solo qAlarm e midserver v3 di dev (monitoring.md). Fuori scope per ora: non fa parte del lavoro attuale. |
— (fuori scope) |
| R2 | 🟠 | pfSense punto critico unico per internet, VPN e tutti gli impianti; nessuna ridondanza, backup settimanale. Unico fermo dal 2023: luglio 2026, 5 ore di notte, per una manutenzione programmata della rete di Netsons, risolta da Netsons (Michele, 30/10). Serve ricevere gli avvisi di manutenzione di Netsons. Michele suggerisce un secondo server in un altro datacenter con replica; il server attuale costa circa 300 €/mese. Confermato da Michele il 30/10. | T0.1, T6.4 (backup config), decisione futura su HA |
| R3 | 🟠 | VPN senza segmentazione (dalle regole lette): ogni box raggiunge MySQL, Redis, phpMyAdmin, ewelink e gli altri box. Le regole lette il 27/10 terminano con allow any → any con traffico reale; secondo Michele (30/10) le regole sono sull'interfaccia WG_VPN, non sul gruppo WireGuard: va riletto dove sta l'allow any. Gli AllowedIPs dei box limitano il tunnel a 172.16.16.1, .253 e .254, ma sono configurati sul box e .253 porta a tutte le porte di ServerIT. Confermato da Michele il 28/10: è una scelta, fatta perché persone diverse dovevano accedere di volta in volta; prima la rete era segmentata. Si può segmentare di nuovo, ma serve sapere chi deve accedere (dal 28/10 Lorenzo e Mattia). Resta aperto fino a T10.5. Tra i peer ci sono solo impianti dei clienti (Michele, 30/10). |
T0.4, T10.5 |
| R4 | 🔴 | Credenziali amministrative condivise (root Proxmox, admin pfSense). Prima le aveva solo Michele; sono state condivise su indicazione di Emanuele (Michele, 30/10). Oggi gli accessi sono nel Passbolt di Michele e non è stato deciso a chi passarli (M-7). Servono utenti nominali e un responsabile. | — |
| R5 | 🔴 | Conoscenza concentrata: rete e operatività dipendono da una persona; codice v3 e cluster dall'autore che è uscito. Urgente: Michele lascia l'azienda, presente fino al 30/10/2026 (poi disponibile a distanza per un periodo). In corso di mitigazione: questa knowledge base serve proprio a raccogliere e mettere per iscritto queste informazioni. | questa documentazione, T0.5, T0.6, T0.9 |
| R6 | 🟠 | Domini bsqdev.uk scritti nel codice di app distribuite. Dal 30/10 il team ha l'accesso a Cloudflare (credenziali condivise da Michele su Passbolt; bsqdev.uk è il dominio creato da Marco). Resta da decidere chi ne è responsabile. Azione possibile: preparare il codice perché un futuro cambio di dominio sia solo una modifica di configurazione. |
T0.7, T3.13 |
| R7 | 🟠 | Backup: solo settimanali, nessun dump MySQL. Erano ritenuti sufficienti perché il MySQL del midserver conteneva solo log (Franco); con allarmi e foto servono dump più frequenti. Un disco aggiuntivo per i backup costa poco (Michele, 28/10). Il ripristino delle VM è già stato fatto: ad aprile 2026, durante la migrazione tra le macchine (Michele, 30/10); la procedura non è scritta. | T0.1, T5.3, T6.4 |
| R8 | 🟡 | Indirizzamento LAN/Cava con range pubblici (170.10.0.0/24, 171.16.16.0/24). Confermato da Michele il 30/10. |
nessuna (non cambiare ora) |
| R9 | 🟡 | Spazio disco local-lvm in overcommit (thin provisioning). |
— (fuori scope, come R1) |
| R10 | 🟡 | VM 400 inutilizzata che occupa 32 GB RAM e 300 GB. | T6.2 (eliminarla prima di creare la nuova) |
| R11 | 🟠 | Dipendenza da Telegram per gli allarmi (limiti di invio, servizio esterno). Confermato da Michele il 30/10: si risolve con il nuovo frontend di qAlarm. | Fase 7 |
| R13 | 🟠 | Database del Raspberry di Michele: anagrafica di tutti gli impianti su un Raspberry in ufficio; credenziali nel codice con tutti i privilegi su tutte le basi dati; raggiungibile da tutta la VPN aziendale; due tabelle di log da 17,8 e 5,4 milioni di righe (~4,4 GB) su un dispositivo con storage limitato; nessun backup (Michele, 30/10). Sullo stesso Raspberry, in centrale operativa, girano anche il monitoraggio dell'infrastruttura (R1) e il controllo orario di presenza dell'operatore (buzzer e relè verso un istituto di vigilanza esterno): un suo guasto tocca anche la sicurezza dell'operatore. | T0.5 (inventario), decisione futura sulla migrazione |
| R14 | 🟠 | Il live del sistema nuovo apre connessioni in più verso la telecamera: una persistente e fino a tre brevi a ogni avvio (probe UDP/TCP e audio), prima in UDP. Le telecamere hanno pochi slot RTSP: superato il limite, il detector può perdere la telecamera e smettere di rilevare. Come guardano il video oggi gli operatori va riverificato: dal censimento solo 4 box Frigate su 24 hanno go2rtc. Sui box GANZ non c'è go2rtc e il GANZ non ripubblica i flussi; la telecamera di laboratorio accetta 4 sessioni. Il pannello crea telecamere Frigate dirette anche sui box con hub. Proposta del team: usare il DVR come sorgente del live. Analisi in connessioni-telecamere.md. | MDM-037, MDM-038, MDM-039 |
| R15 | 🟠 | Manomissione delle telecamere rilevata ma non notificata: il box calcola "coperta/spostata" e lo manda nello stato, ma midserver, pannello e qAlarm non lo usano; il controllo ha anche falsi positivi probabili (notte, luce) e consuma CPU. | anti-manomissione, MDM-082, A23 |
| R16 | 🔴 | Allarmi del GANZ possibilmente rifiutati dalla stage: le API /api/v1 accettano solo IP di 192.168.1.x, 192.168.3.x, VPN e Docker, più utente e password; il GANZ chiama /api/v1/alarm/... dalla rete del cliente. Da verificare subito sul box di prova. |
funzioni del box, MDM-083 |
| R17 | 🟠 | Funzioni accese dal pannello che non fanno niente: rilevamento incendio e fumo (analizza e scarta), monitoring_ganz_alarm_in nella stage, pulizia del disco solo sulle immagini Docker. Chi le accende crede di avere una protezione che non c'è. |
funzioni del box, MDM-084 |
| R18 | 🟠 | La stage può lasciare un impianto disinserito: rifiuta l'inserimento se un componente critico (detector, trombe, ingressi) non è sano, anche con l'inserimento automatico; nello stato ERROR rifiuta inserimento e disinserimento. |
A24 |
| R12 | 🟠 | Release diverse sui box non tracciate; aggiornamento remoto mai usato su scala. | T1.5, Fase 9 |
Midserver e MDM (M)¶
| # | Pri | Problema | Dove | Attività |
|---|---|---|---|---|
| M1 | ⏸️ | Access key AWS in chiaro in file versionati. Rimandato per decisione (27/10), da riprendere prima di aprire la prod. | .env.prod, .env.local, app/static/installer.sh, devscripts/docker_compose_run.py |
T10.6 |
| M2 | 🟠 | Porte interne (MySQL, Redis, Mosquitto, Flask, phpMyAdmin) aperte a tutta la VPN; port forward morti su pfSense. Non esposte da internet (verificato). | compose, pfSense | T0.3, T10.5 |
| M3 | 🔴 | Redis con solo volume anonimo e senza AOF: un compose down svuota l'unico registro dei box e lo stream eventi. |
compose redis |
T0.2, T3.7 |
| M4 | 🔴 | Server di sviluppo Flask in prod (flask run, FLASK_ENV: development). |
Dockerfile, compose |
risolto dalla v3 (Fase 8) |
| M5 | 🟠 | Nessun health check utilizzabile in v2 (/health/status richiede JWT e un box). |
app/health/ |
v3 /health |
| M6 | 🟠 | Con più istanze o più worker ogni evento finisce due volte nello stream (subscription MQTT e listener scadenze in ogni processo). | v2 e v3 | T3.5, T3.6 |
| M7 | 🟠 | Eventi MQTT persi durante i fermi (sessione non persistente). | client MQTT | T3.5 |
| M8 | 🟠 | Nessun backup MySQL. | — | T0.1, T6.4 |
| M9 | 🟡 | Tag latest per redis, mosquitto, OME, phpMyAdmin, NPM. |
compose | T3.7 |
| M10 | 🟡 | KEYS * all'avvio e in get_all. |
redis_connector.py |
T3.x (v3) |
| M11 | 🟡 | MQTT senza TLS (mitigato: passa nella VPN). | mosquitto.conf |
— |
| M12 | 🟡 | Pannello prod: link Grafana a IP privato in HTTP. | mdm_web_panel/config/production.json |
T3.4 |
| M13 | 🟡 | Pannello: configurazione dentro l'immagine, un'immagine per ambiente. Gestito con la variabile di build FLUTTER_TARGET (su Coolify dev lib/main_dev.dart → config/development.json). |
mdm_web_panel/Dockerfile |
futuro |
| M14 | 🟡 | Segreti in chiaro in Server.xml di OME e nel compose del box; credenziali MQTT/server di default probabilmente uguali su tutti i box. |
— | T10.6 |
| M15 | 🔴 | IP di OME scritto nel codice dei box (185.31.66.185:9999): anche i box di test mandano il video in prod; qualsiasi cambio di IP rompe il video su tutto il parco. |
mdm_installation/.../web_rtc_handler.py:186 |
T2.2 |
| M16 | 🟠 | L'installer scrive credenziali AWS sul box, ed è scaricabile dal midserver. | app/static/installer.sh |
T10.6 |
| M17 | 🟠 | ewelink-integration senza autenticazione, raggiungibile da tutta la VPN: ogni box può comandare relè e cancelli. Non esposto da internet. |
ServerIT :8080 | T10.1, T10.5 |
| M18 | 🟡 | phpMyAdmin con PMA_ARBITRARY=1 aperto a tutta la VPN; modifica locale non committata del 27/10 (fatta da un membro del team, da identificare). |
ServerIT :7070 | T0.2, T0.8 |
| M19 | 🟡 | Gestione Proxmox raggiungibile da tutta la VPN (non da internet). | 185.31.66.229:8006 |
T10.5 |
| M20 | 🟡 | Box dismessi restano nel pannello (chiavi Redis senza scadenza). | midserver | T0.5, T3.11 |
| M21 | 🟡 | Nessuna pipeline per il midserver; deploy di prod a mano sul server. | — | T3.9, Fase 8 |
| M22 | Rollout | Pagina live Protexia: requisito v3 annullato (D27). Nuova app solo con player interno; le app già distribuite possono ancora usare la pagina v2. Modifiche locali, rollout e test live ancora aperti. | protexia/stream_item.dart; MDM-043 |
T7.3, compatibilità dei client legacy |
| M26 | 🟠 | L'installer servito dal midserver installa versioni vecchie se si sceglie "stage": git clone senza branch prende main, e .env.build_tag.stage di main punta a tag vecchi (3.1.3-stage, wrapper 2.0.2). Inoltre non gestisce i ruoli master/slave. |
mdm_mid_server/app/static/installer.sh (tutti i branch) |
MDM-035 |
| M27 | 🟠 | Segreto mdm/installation/prod della linea stage incoerente con la prod reale: MQTTURL = mqtt.bsqdev.uk (→ 185.31.66.185, porta 1883 inoltrata a un IP inesistente: un box della linea stage di prod non si collegherebbe), SERVERBASEURL via Cloudflare invece della VPN, LOGSERVERBASEURL di prod e stage apparentemente invertiti. Da allineare prima di installare box della linea stage in prod. |
AWS Secrets Manager mdm/installation/prod, mdm/installation/stage I box 3.2.x di produzione usano oggi midserver e MQTT via VPN (172.16.16.253, .env versionato in main, commit 31764c60): il segreto va allineato a quei valori (dettaglio). |
MDM-031 |
| M28 | 🔴 | Token e chat del bot Telegram di Alertmanager scritti nel repository monitoring (configs/alertmanager/alertmanager.yml, su main e dev). Chi legge il repository può mandare messaggi con quel bot. |
Revocare il token, spostarlo in una variabile di Coolify (monitoring.md) | |
| M29 | 🟡 | Valori del segreto AWS in chiaro sul box nella linea stage: infra-cli scrive infra/environments/<env>/.infra.generated.env con tutte le variabili, comprese le credenziali MQTT; ogni avvio con infra-cli richiede AWS raggiungibile e la chiave scritta nell'updater (M1). |
infra-lib.md, MDM-081, T10.6 | |
| M30 | 🟠 | Grafana dev pubblico con accesso anonimo (variabili GF_AUTH_ANONYMOUS_* su Coolify, valore da verificare) e Loki su dominio pubblico: i log contengono dati degli impianti. Immagini latest nello stack. |
monitoring.md | |
| M31 | 🟠 | Stesso utente admin e stessa password su tutti i box stage, creati dalla prima migrazione: chi la conosce può usare le API v1 di qualsiasi box raggiungibile. |
MDM-083 | |
| M32 | 🟠 | PC degli impianti preparati con impostazioni deboli secondo la procedura di Michele: password fisse uguali per tutti (root di MySQL, pannello di Nginx Proxy Manager) scritte nelle guide; MySQL con utente % con tutti i privilegi e bind-address disattivato; root con password e login SSH di root; bsqsecurity con sudo senza password; pagina settings di televigilanza-mdm protetta da una chiave fissa nell'URL; pannello di Nginx Proxy Manager (81) raggiungibile dalla VPN. Con la VPN non segmentata (R3) chi è sulla VPN può arrivarci. Le guide in raw/michele/UBUNTU - MDM/ contengono queste password e una PresharedKey WireGuard. |
PC dei clienti, raw/michele/ |
da pianificare con T10.5 e T10.6 |
| M24 | 🟠 | Il frigate wrapper espone le credenziali dei webhook senza autenticazione: GET :5050/api/v1/webhooks restituisce URL, utente e password dei webhook degli allarmi a chiunque sia sulla VPN (verificato il 28/10 su un box 3.2.9; il censimento non le salva). |
mdm_frigate_wrapper src/api/v1/routers/configuration.py |
da pianificare (autenticazione sulle API del wrapper o almeno credenziali mascherate in lettura) |
| M23 | 🟡 | 3 box offline (uno dal 26/10, due da agosto): non si sa se siano dismessi. Aperto. | Redis | T0.5, T9.3 |
qAlarm 2 (Q)¶
| # | Pri | Problema | Attività |
|---|---|---|---|
| Q1 | 🔴 | Il frontend costruito punta a un IP privato di fallback. | T4.5 |
| Q2 | 🔴 | Il JWT viene stampato nei log. | T4.1 |
| Q3 | 🔴 | Nessuna build ECR per backend e worker. | T4.4 |
| Q4 | 🟠 | Nessun health; /metrics pubblico. |
T4.2 |
| Q5 | 🟠 | CORS aperto a tutti con credenziali. | T4.3 |
| Q6 | 🟠 | Il worker non ritenta gli eventi falliti; consumer con nome fisso. | T4.7 |
| Q7 | 🟠 | WebSocket e porta fissa: attenzione agli aggiornamenti senza fermo. | T6.2 |
| Q8 | 🟡 | index.html senza no-cache. |
T4.8 |
| Q9 | 🟡 | IP fissi in prod.yml. |
T4.6 |
| Q10 | 🟡 | wss://ome.bsqdev.uk/app nel codice del frontend. |
T4.5 |