ESP32 (28) – MQTT e SSL

luca 04/12/2017 0

Riprendiamo il tema sicurezza per i broker MQTT. In un precedente articolo, vi ho mostrato come gestire autenticazioneautorizzazione. La debolezza di tale configurazione è che le credenziali sono trasmesse in chiaro, è quindi possibile – se un attaccante può sniffare il traffico di rete – leggere utenza e password e quindi utilizzarle per impersonificare un client autorizzato.

Oggi vediamo come attivare la cifratura del canale di comunicazione tra client e broker utilizzando certificati SSL. Vi mostrerò inoltre come realizzare un programma per il chip esp32 che invii dati al broker su canale cifrato…

Certificato SSL

Per poter cifrare la comunicazione, dobbiamo fornire a mosquitto un certificato server.

Generiamo per prima cosa la chiave privata (algoritmo RSA, lunghezza 2048bit):

openssl genrsa -out mosquitto.key 2048

quindi creiamo il file CSR:

openssl req -new -out mosquitto.csr -key mosquitto.key

compiliamo i vari campi; il più importante è il common name che identificherà il certificato:

mq-ssl-001

Firmiamo quindi il file CSR con la nostra CA (o inviamolo ad una CA pubblica) per ottenere il certificato:

openssl ca -config openssl.cnf -extensions server_cert 
 -notext -in mosquitto.csr -out mosquitto.cer

mq-ssl-002

Creiamo la cartella ssl all’interno della cartella dove abbiamo installato mosquitto e copiamo in tale cartella certificato e chiave privata appena generati e il certificato della CA:

mq-ssl-003

Configurazione

Apriamo il file mosquitto.conf e inseriamo le seguenti righe:

mq-ssl-004

La prima riga cambia la porta su cui il server mosquitto è normalmente in ascolto (1883) in 8883, porta di default per le connessioni in SSL.

Le successive tre indicano a mosquitto il path dei certificati (server e CA) e la chiave privata relativa al certificato server. L’ultima – non obbligatoria – forza l’uso del protocollo TLS v1.2, il più sicuro attualmente disponibile.

Una volta configurato il server, possiamo eseguirlo (-v per la modalità verbosa):

mosquitto.exe -c mosquitto.conf -v

Per utilizzare gli strumenti mosquitto_pub e mosquitto_sub, dobbiamo specificare nuovi parametri:

mosquitto_sub.exe -p 8883 -t test --cafile .\ssl\ca.cer --insecure
mosquitto_pub.exe -p 8883 -m 20 -t test --cafile .\ssl\ca.cer --insecure

Con -p indichiamo la nuova porta utilizzata dal server, con –cafile indichiamo il percorso del certificato della CA che ha firmato il certificato esposto dal server mosquitto e infine con –insecure chiediamo ai due client di non verificare che il common name del certificato (nel mio esempio mymosquitto.local) corrisponda al nome del server.

Possiamo evitare l’utilizzo di –insecure generando un certificato che abbia come common name il nome esatto del computer che esegue il server mosquitto o – in alternativa – aggiungendo un alias DNS che colleghi il common name del certificato all’IP del server ed eseguendo i client con il parametro -h commonName

esp32

Tuan PM ha sviluppato una libreria (espmqtt) per il framework esp-idf che implementa un completo client MQTT. La libreria inoltre supporta connessioni sicure, possiamo quindi utilizzarla per collegarci al server mosquitto con TLS attivo.

mq-ssl-005

Copiamo il contenuto del repository Github della libreria nella cartella components del nostro progetto e includiamo il file header della libreria nel codice sorgente del nostro programma:

#include "mqtt.h"

La configurazione del client MQTT avviene tramite la struct mqtt_settings:

mqtt-001

I parametri principali sono:

  • il server (host) a cui collegarsi (si può utilizzare l’indirizzo IP o il nome DNS)
  • la porta (port) su cui il server è in ascolto (di default sono 1883 o 8883 se è abilitato SSL)
  • eventuali usernamepassword da utilizzare se il server richiede autenticazione
  • una o più funzioni di callback che la libreria espmqtt chiamerà al verificarsi dell’evento associato
La libreria espmqtt non effettua la copia dei parametri in una struttura interna. E’ quindi importante che la variabile di tipo mqtt_settings sia definita a livello globale, fuori dalle varie funzioni.

L’interazione con il client MQTT avviene implementando – nel proprio programma – una o più funzioni di callback.

Ad esempio la connessione e disconnessione dal server MQTT avviene in questo modo:

mqtt-002

Le funzioni connect_cbdisconnect_cb effettuano la connessione e la disconnessione dal server, mentre connected_cbdisconnected_cb vengono chiamate quando il relativo evento (connessione/disconnessione) avviene. Normalmente il nostro programma non andrà a ridefinire le funzioni principali, ma andrà ad implementare quelle relative agli eventi, per eseguire operazioni (ad esempio la sottoscrizione ad un topic) in contemporanea a tali eventi.

Preparata la configurazione del client MQTT, è possibile avviarlo con:

mqtt_start(&settings);

Una volta effettuata la connessione al server (evento connected_cb) è possibile sottoscrivere topics e togliere la sottoscrizione o inviare messaggi con:

void mqtt_subscribe(mqtt_client *client, const char *topic, uint8_t qos);
void mqtt_unsubscribe(mqtt_client *client, const char *topic);

e

void mqtt_publish(mqtt_client* client, const char *topic, 
  const char *data, int len, int qos, int retain);

Demo

Ho preparato un esempio che mostra l’interazione tra una scheda di sviluppo esp32 e mosquitto, configurato in SSL.

Ho collegato alla scheda di sviluppo un sensore HTU21D come spiegato in un mio precedente articolo per inviare, ogni 5 secondi, i dati di temperatura e umidità rilevati. Per visualizzare i dati ricevuti dal broker MQTT, ho utilizzato un comodo programma opensource, HelloIoT.

Codice sorgente del programma e configurazione di HelloIoT si trovano nel mio repository Github; di seguito un filmato che mostra il programma in esecuzione (sottotitoli in italiano disponibili):

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi