Hermes: Come funziona e sicurezza

Hermes è un’integrazione custom per Home Assistant che collega una mesh Meshtastic (LoRa) alla domotica. Fa due cose:

  • Comandi dalla mesh → Home Assistant. Un nodo autorizzato manda un messaggio di testo, Hermes esegue l’azione mappata su quella parola chiave e risponde via radio.
  • Notifiche da Home Assistant → mesh. I servizi hermes.broadcast e hermes.send_direct si chiamano da qualsiasi automazione, anche pianificata, così un allarme arriva a chi non ha copertura telefonica.

Per installazione e diagnostica vedi Hermes - Installazione e problemi comuni.

Dove si colloca nell’architettura

Hermes non parla direttamente con la radio. È un livello applicativo sopra l’integrazione ufficiale meshtastic/home-assistant, che è l’unica a possedere la connessione TCP/seriale/BLE al nodo.

flowchart TD
    A[Nodi mesh] -->|LoRa| B[Nodo gateway]
    B -->|TCP / USB / BLE| C[Integrazione Meshtastic ufficiale]
    C -->|evento meshtastic_api_text_message| D[Hermes]
    D --> E[Azioni Home Assistant]
    D --> F[servizio meshtastic.send_text]
    F -->|risposte e notifiche| B

Conseguenze pratiche di questa scelta:

  • una sola integrazione può tenere la connessione al nodo: non se ne affiancano due sullo stesso dispositivo;
  • il nodo gateway è quello fisicamente collegato a Home Assistant, mai quello da cui si invia. Sbagliare gateway è la causa più comune di “non arriva niente”;
  • se l’integrazione ufficiale non funziona, Hermes non può funzionare.

Quali dati prende da Meshtastic

Messaggi

Hermes ascolta l’evento meshtastic_api_text_message. Da ogni messaggio usa: testo, nodo mittente, canale o DM, gateway di arrivo, timestamp. Nient’altro del messaggio influenza cosa viene eseguito.

Database dei nodi (NodeDB)

Per ogni nodo visto sulla mesh legge:

CampoContenuto
node_numIdentificativo numerico del nodo
name / short_nameNome lungo e sigla dall’utente del nodo
hardwareModello hardware (hwModel)
latitude / longitudePosizione, letta anche in formato fixed-point (latitudeI), altrimenti molti nodi risultano senza posizione
batteryLivello batteria dalla telemetria
snrRapporto segnale/rumore dell’ultima ricezione
hops_awaySalti di distanza
last_heardUltimo contatto

Stato e configurazione della radio

Stato della connessione radio, versione firmware del solo gateway (le altre vanno lette dall’app Meshtastic), elenco canali, e i parametri di configurazione del nodo: regione, modem preset, hop limit, potenza di trasmissione, ruolo.

Come i dati arrivano dentro Home Assistant

Entità diagnostiche sul device della config entry:

  • Last command received: testo, nodo mittente e timestamp negli attributi
  • Commands executed: contatore (TOTAL_INCREASING)
  • Last error: ultimo errore o rifiuto di autorizzazione

Le card. La maggior parte delle informazioni non diventa entità: vive nella card Hermes (Status, Chat, Log, Devices, Map, Messages, Home Assistant, Settings) e in due card ridotte, Hermes summary e Hermes chat.

Storage. Chat e log sono conservati nello storage di Home Assistant, su disco e in chiaro, con tetti: 200 messaggi per conversazione, 40 conversazioni, 200 voci di log. Entrambi si possono svuotare dalla card.

Il percorso di un comando

  1. Il messaggio arriva dalla mesh e viene filtrato per gateway e canale/DM corretti.
  2. Il mittente deve essere nella lista dei nodi autorizzati; se non c’è, il messaggio viene scartato in silenzio (rispondere confermerebbe che dietro c’è un Home Assistant).
  3. Rate limit: default 6 comandi in 60 secondi per nodo.
  4. Matching della parola chiave: exact match o starts with, per default ignorando le maiuscole.
  5. Esecuzione dell’azione e/o composizione della risposta.
  6. Invio della risposta, spezzata in parti da ≤ 200 byte con intestazione (1/3), senza mai tagliare a metà un carattere multibyte. Un comando arrivato in privato riceve sempre risposta in privato.

I comandi si costruiscono scegliendo un’entità e cliccando pulsanti: Read inserisce un valore nella risposta, Do esegue qualcosa. Non si digitano mai nomi di servizio né template.


Sicurezza: leggere lo stato sì, pilotare con cautela

La regola che riassume tutto:

Un canale ti dice le cose, un messaggio diretto le cambia.

Perché il canale non è una superficie di comando

Su un canale l’unica protezione è la chiave condivisa. I messaggi portano un mittente, ma niente lo dimostra: chiunque abbia la chiave può inviare fingendosi qualsiasi nodo. La whitelist lì ferma gli errori e il traffico casuale, non chi vuole entrare davvero.

Su un messaggio diretto con PKC (firmware ≥ 2.5) il messaggio è cifrato per il destinatario e il mittente è verificato dal protocollo prima ancora di arrivare a Home Assistant. Solo lì la lista dei nodi autorizzati significa quello che dice.

Il raggio d’azione è la lista dei comandi

Un comando gira come Home Assistant stesso: nessun utente dietro, nessun controllo di permessi, nessuna conferma. Quindi la lista dei comandi è la lista dei permessi.

La domanda da farsi per ogni comando non è “mi fa comodo”, ma: accetterei che uno sconosciuto lo attivasse, il giorno in cui la chiave del canale trapela?

Due garanzie strutturali, ed è utile sapere fin dove arrivano:

  • Il mittente non fornisce mai un servizio, un’entità o un template. Tutto questo lo scrivi tu nella card. Dal messaggio arrivano solo la parola chiave e, quando il match lo consente, un numero, interpretato in senso stretto e verificato contro il range che il dispositivo accetta. Non c’è modo di far raggiungere a un messaggio qualcosa che non hai configurato.
  • Una risposta a un messaggio privato non viene mai pubblicata su un canale.

Cosa non mettere mai su un canale

  • aprire porte o cancelli, disinserire l’allarme
  • qualunque cosa irreversibile, costosa, o che continui mentre non sei in casa
  • qualunque risposta che riveli se la casa è vuota: presenza, posizione, “nessuno in casa” sono quelli che si dimenticano. Un comando di stato che risponde allarme: disinserito, nessuno in casa su un canale è un annuncio pubblico, ed è peggio di un interruttore della luce.

La configurazione consigliata: due istanze

Aggiungere l’integrazione due volte non costa nulla e ogni config entry è indipendente.

IstanzaModalitàComandi
StatocanaleSolo lettura: temperature, allarme inserito, batteria dei nodi, “sono ancora online”
Controllomessaggi direttiTutto ciò che agisce: luci, riscaldamento, cancelli, scene

Se tieni una sola istanza, usala in modalità messaggi diretti e considera il canale non una superficie di comando.

Impostazioni da rispettare

  • Mai la chiave di default. AQ== è pubblicata nella documentazione Meshtastic: un canale che la usa è pubblico. La card lo segnala.
  • Compila la lista dei nodi autorizzati su ogni istanza, anche su quella a canale: lì è debole, non inutile.
  • Lascia attivo il rate limit. Non ferma un attaccante, che può stare sotto soglia, ma impedisce a un nodo guasto o a un repeater che duplica pacchetti di rieseguire un comando centinaia di volte.
  • Imposta la keyword di help solo se accetti che la lista comandi sia leggibile. Risponde ai soli nodi autorizzati, ma su un canale “autorizzato” è un’affermazione debole.
  • Preferisci la risposta in privato per qualsiasi cosa riveli uno stato, anche se il comando è arrivato su un canale.

Rotazione delle chiavi e perdita di un nodo

Un nodo contiene le chiavi di tutti i canali su cui è. Un nodo perso, rubato, venduto o prestato è una copia di quelle chiavi in mano ad altri: cambia la chiave del canale su tutti i nodi rimasti. Finché non lo fai, la whitelist su quel canale non protegge nulla. Lo stesso vale per un nodo che riflashi e cedi: cancellalo prima.

Quello che Hermes non può proteggere

Niente di quanto sopra aiuta se è Home Assistant stesso a essere raggiungibile:

  • non esporre Home Assistant su Internet senza reverse proxy e autenticazione a più fattori;
  • tieni aggiornati core e integrazioni;
  • chiunque abbia un account admin di Home Assistant può cambiare ogni impostazione di Hermes, inclusi i nodi autorizzati.

In breve

Stato su canale. Controllo su messaggi diretti, con firmware PKC su entrambi i lati e whitelist. Mai la chiave di default. Dai per scontato che prima o poi la chiave del canale trapeli, e configura in modo che quel giorno l’unica cosa che qualcuno scopra sia la temperatura.


Collegamenti