Ricerca nel sito web

Come installare e proteggere il broker di messaggistica MQTT Mosquitto su Ubuntu 20.04


Su questa pagina

  1. Prerequisiti
  2. Passaggio 1 - Installa Mosquitto Server e Client
  3. Passaggio 2 - Configurare l'autenticazione della password MQTT
  4. Passaggio 3 - Testare il client Mosquitto
  5. Passaggio 4 - Installa SSL
  6. Passaggio 5 - Configura MQTT SSL
  7. Passaggio 6: configurazione del rinnovo SSL
  8. Passaggio 7 - Configura Websocket
  9. Conclusione

Mosquitto è un broker di messaggi open source che utilizza il protocollo MQTT (Message Queuing Telemetry Transport). Il protocollo è progettato per fornire una comunicazione leggera ai dispositivi Internet of Things (IoT). È comunemente utilizzato per il tracciamento GPS di veicoli, domotica, sensori ambientali e raccolta dati su larga scala.

Il protocollo MQTT funziona sopra il modello TCP/IP. Essendo leggero, il suo footprint di codice ridotto consente di creare applicazioni per dispositivi con risorse minime. Si basa sul modello di pubblicazione/sottoscrizione. In questo modello, il client si connette al server Mosquitto, che funge da broker per inviare informazioni ad altri client iscritti a un canale.

In questo tutorial, installerai Mosquitto e configurerai il broker per utilizzare SSL per proteggere le comunicazioni.

Prerequisiti

  • Un server Ubuntu 20.04 con un utente non root con privilegi sudo.
  • Un nome di dominio (myqtt.example.com) indirizzato al tuo server.

Passo 1 - Installa Mosquitto Server e Client

Ubuntu viene fornito con la vecchia versione 1.6 di Mosquitto. Per installare l'ultima versione, aggiungi il repository Mosquitto ufficiale.

$ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa

Installa il server Mosquitto e il client.

$ sudo apt install mosquitto mosquitto-clients

Controlla lo stato del server.

$ sudo systemctl status mosquitto
? mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-01-25 09:18:40 UTC; 25s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 119694 (mosquitto)
      Tasks: 1 (limit: 2274)
     Memory: 1.0M
     CGroup: /system.slice/mosquitto.service
             ??119694 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 25 09:18:39 <userid> systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 09:18:40 <userid> systemd[1]: Started Mosquitto MQTT Broker.

Passaggio 2: configurare l'autenticazione della password MQTT

Mosquitto viene fornito con un'utilità per generare un file di password chiamato mosquitto_passwd. Mosquitto memorizza tutte le configurazioni nella directory /etc/mosquitto.

Esegui il comando seguente per generare un file di password crittografato in /etc/mosquitto/passwd per il nome utente username. Inserisci una password a tua scelta.

$ sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Password:
Reenter password:

Successivamente, crea un file default.conf nella directory /etc/mosquitto/conf.d e aprilo per la modifica.

$ sudo nano /etc/mosquitto/conf.d/default.conf

Incollare le righe seguenti per specificare la posizione del file delle password. Se ometti il campo listener, si collegherà sempre in modo anonimo, indipendentemente dalla configurazione.

listener 1883
password_file /etc/mosquitto/passwd

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Riavvia il server Mosquitto per implementare la modifica.

$ sudo systemctl restart mosquitto

Passaggio 3: testare il client Mosquitto

A seconda del caso d'uso, puoi utilizzare il client Mosquitto per inviare e ricevere messaggi su diversi argomenti. Un cliente è un abbonato o un editore.

Il passaggio successivo consiste nell'iscriversi a un argomento. Nel protocollo MQTT, un argomento fa riferimento a una stringa utilizzata dal server/broker per filtrare i messaggi per i client connessi. Di seguito sono riportati alcuni argomenti di esempio che è possibile utilizzare in un'applicazione domotica.

  • home/luci/salotto_
  • casa/luci/cucina
  • home/luci/camera_da_letto
  • home/luci/cameretta_bambini

Per iscriverti a un argomento, esegui il comando mosquitto_sub -t seguito dall'argomento. Ad esempio, per iscriverti all'argomento home/lights/kitchen, esegui il seguente comando.

$ mosquitto_sub -u username -P YOUR_PASSWORD -t "home/lights/kitchen"

Non chiudere la finestra esistente. Apri una nuova finestra di terminale per pubblicare un messaggio nell'argomento home/lights/kitchen utilizzando il seguente comando.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "ON" -t "home/lights/kitchen"

Torna alla prima finestra del terminale e riceverai il payload ON.

ON

Successivamente, invia il messaggio OFF sullo stesso argomento dal secondo terminale.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "OFF" -t "home/lights/kitchen"

Il primo terminale mostrerà il messaggio appena pubblicato.

ON
OFF

Se provi a inviare un commento non autenticato, fallirà. Ad esempio, prova il seguente comando.

$ mosquitto_sub -t "home/lights/sitting_room"
Connection error: Connection Refused: not authorised.

Non è consigliato, ma è necessario aggiungere la seguente riga al file /etc/mosquitto/conf.d/default.conf se si desidera eseguire i comandi senza autenticazione.

allow_anonymous true

Passaggio 4: installa SSL

Per installare un certificato SSL utilizzando Lets Encrypt, dobbiamo scaricare lo strumento Certbot. Useremo il programma di installazione del pacchetto Snapd per questo.

Installa il programma di installazione di Snap.

$ sudo apt install snapd

Assicurati che la tua versione di Snapd sia aggiornata.

$ sudo snap install core 
$ sudo snap refresh core

Installa Cerbot.

$ sudo snap install --classic certbot

Utilizzare il seguente comando per assicurarsi che il comando Certbot venga eseguito creando un collegamento simbolico alla directory /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Genera un certificato SSL.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m  -d mqtt.example.com

Il comando precedente scaricherà un certificato nella directory /etc/letsencrypt/live/mqtt.example.com sul tuo server.

Genera un certificato di gruppo Diffie-Hellman.

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Crea una directory radice Web di verifica per il rinnovo automatico di Lets Encrypt.

$ sudo mkdir -p /var/lib/letsencrypt

Crea un Cron Job per rinnovare l'SSL. Verrà eseguito ogni giorno per controllare il certificato e rinnovarlo se necessario. Per questo, per prima cosa, crea il file /etc/cron.daily/certbot-renew e aprilo per modificarlo.

$ sudo nano /etc/cron.daily/certbot-renew

Incolla il seguente codice.

#!/bin/sh
certbot renew --cert-name mqtt.example.com --webroot -w /var/lib/letsencrypt/

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Modificare le autorizzazioni sul file dell'attività per renderlo eseguibile.

$ sudo chmod +x /etc/cron.daily/certbot-renew

Passaggio 5: configurare MQTT SSL

Ora che abbiamo i certificati SSL pronti, dobbiamo fornire a Mosquitto l'accesso ad essi. Per questo, dobbiamo copiare i certificati in una posizione da cui Mosquitto possa accedervi.

$ sudo cp /etc/letsencrypt/live/mqtt.example.com/fullchain.pem /etc/mosquitto/certs/server.pem
$ sudo cp /etc/letsencrypt/live/mqtt.example.com/privkey.pem /etc/mosquitto/certs/server.key

Modificare la proprietà della directory /etc/mosquitto/certs all'utente mosquitto creato durante l'installazione.

$ sudo chown mosquitto: /etc/mosquitto/certs

Il passaggio successivo per abilitare la crittografia SSL per Mosquitto è specificare la posizione dei certificati SSL. Apri il file di configurazione per la modifica.

$ sudo nano /etc/mosquitto/conf.d/default.conf

Incolla il seguente codice alla fine del file.

. . .
listener 8883
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Salva il file premendo Ctrl + X e inserendo Y quando richiesto. Assicurati di lasciare una nuova riga finale alla fine del file.

La parte listener 8883 imposta il listener crittografato. È la porta standard per MQTT + SSL, denominata MQTTS. Le quattro righe successive specificano la posizione dei file SSL.

Riavvia Mosquitto per aggiornare le impostazioni.

$ sudo systemctl restart mosquitto

Sarà necessario aggiornare il firewall per consentire le connessioni alla porta 8883.

$ sudo ufw allow 8883

Successivamente, dobbiamo testare la funzionalità utilizzando il comando mosquitto_pub.

$ mosquitto_pub -h mqtt.example.com -t "home/lights/kitchen" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u username -P YOUR_PASSWORD

Come puoi vedere, abbiamo incluso alcuni parametri aggiuntivi, tra cui il numero di porta e il percorso dei certificati SSL. Ogni volta che devi usare SSL, dovrai sempre specificare il nome host completo, ad esempio mqtt.example.com invece di localhost altrimenti, darebbe un errore.

Dovrai anche aggiungere ogni volta la direttiva --capath. Dice al client Mosquitto di cercare i certificati root installati dal sistema operativo.

Passaggio 6: configurare il rinnovo SSL

Certbot rinnoverà automaticamente il tuo certificato prima che scada. Ma deve essere detto di copiare i certificati rinnovati nella directory /etc/mosquitto/certs e riavviare il servizio Mosquitto.

Lo faremo creando uno script di shell. Crea un file mosquitto-copy.sh nella directory /etc/letsencrypt/renewal-hooks/deploy.

$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Incolla il seguente codice al suo interno. Sostituisci il valore della variabile MY_DOMAIN con il tuo dominio. La variabile $ {RENEWED_LINEAGE} punta alla directory /etc/letsencrypt/live/mqtt.example.com durante il rinnovo.

# Set which domain this script will be run for
MY_DOMAIN=mqtt.example.com
# Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs

if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
	# Copy new certificate to Mosquitto directory
	cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
	cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key

	# Set ownership to Mosquitto
	chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Ensure permissions are restrictive
	chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Tell Mosquitto to reload certificates and configuration
	pkill -HUP -x mosquitto
fi

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Rendi il file eseguibile.

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Questo script verrà eseguito automaticamente a ogni rinnovo riuscito del certificato.

Se stai eseguendo Mosquitto e un server Web come Nginx, devi istruire Certbot per arrestare il server prima del rinnovo e riavviarlo una volta terminato. Per farlo, apri il file etc/letsencrypt/renewal/mqtt.example.com.conf.

$ sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf

Aggiungere le seguenti righe alla fine del file. Modifica i comandi in base al server web che stai utilizzando.

pre_hook = systemctl stop nginx
post_hook = systemctl start nginx

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Esegui un test Certbot per verificare.

$ sudo certbot renew --dry-run

Se non vedi errori, significa che è tutto impostato.

Passaggio 7: configurare i Websocket

Puoi configurare Mosquitto per utilizzare il protocollo MQTT dall'interno dei browser utilizzando Javascript utilizzando la funzionalità Websockets. Per abilitarlo, apri il file di configurazione.

$ sudo nano /etc/mosquitto/conf.d/default.conf

Incolla le seguenti righe alla fine del file.

. . .
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Se noti, è lo stesso blocco di quello che abbiamo usato per abilitare SSL ad eccezione dei campi del numero di porta e del protocollo. 8083 è la porta più comune utilizzata da MQTT per comunicare tramite WebSocket.

Riavvia il servizio Mosquitto.

$ sudo systemctl restart mosquitto

Apri la porta 8083.

$ sudo ufw allow 8083

Dobbiamo utilizzare un client MQTT basato su browser per testare la funzionalità WebSockets. Sono disponibili molti client, ma per il nostro scopo utilizzeremo il client HiveMQ Websocket. Avvia il client nel tuo browser e vedrai quanto segue.

Come mostrato nello screenshot qui sopra, compila i campi come mostrato.

  • L'host dovrebbe essere il dominio del tuo server Mosquitto, mqtt.example.com.
  • La porta dovrebbe essere 8083.
  • Il campo ClientID può essere lasciato così com'è.
  • Il nome utente dovrebbe essere il tuo nome utente Mosquitto.
  • La password deve essere la password che hai creato in precedenza.
  • Seleziona la casella SSL.

Premi il pulsante Connetti e il client HiveMQ sarà connesso al tuo server Mosquitto.

Una volta connesso, inserisci home/lights/kitchen come argomento, inserisci qualsiasi messaggio e premi Pubblica.

Il messaggio verrà visualizzato nella finestra del terminale mosquitto_sub a conferma della connessione riuscita.

Ciò dimostra che l'implementazione di Websocket ha esito positivo.

Conclusione

Questo conclude la nostra configurazione di un server MQTT sicuro, protetto da password e crittografato con SSL su una macchina basata su Ubuntu 20.04. Se hai domande, pubblicale nei commenti qui sotto.