樹莓派安裝 Mosquitto 輕量級 MQTT Broker 教學,連接各種物聯網設備

安全加密 TLS 連線

在安全性的考量上,僅僅只有加上帳號密碼是不夠的,至少還要有安全加密的保護,才能達到基本的防禦效果,否則讓帳號與密碼以明碼的方式在網路上傳遞,跟沒有設定帳號密碼是差不多的。

以下是 Mosquitto 設定安全加密 TLS 連線的步驟。
Step 1
建立一個只有自己能讀取的目錄,隨後我們要在這個目錄中產生伺服器用的金鑰檔案。

mkdir myCA
chmod 700 myCA
cd myCA

Step 2
產生金鑰的過程可以參考 mosquitto-tls 的 man page,而更快速的方式是使用 generate-CA.sh 這一個已經寫好的指令稿:

wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh
bash generate-CA.sh

執行 generate-CA.sh 之後,會自動產生伺服器用的金鑰。

Step 3
將金鑰複製到 Mosquitto 的目錄之中:

sudo cp ca.crt /etc/mosquitto/ca_certificates/
sudo cp raspberrypi.crt raspberrypi.key /etc/mosquitto/certs/

Step 4
重新啟動 Mosquitto 服務:

service mosquitto restart

如果重新啟動 Mosquitto 服務時,/var/log/mosquitto/mosquitto.log 出現這樣的錯誤:

Error: Unable to load server key file "/etc/mosquitto/certs/raspberrypi.key". Check keyfile.

通常是因為檔案權限不足的問題,只要修改一下檔案的擁有者即可:

sudo chown mosquitto /etc/mosquitto/certs/raspberrypi.key

Step 5
檢查伺服器的金鑰是否正常運作:

mosquitto_sub -t '$SYS/broker/bytes/#' 
  -u gtwang -P secret123 
  --cafile ca.crt -v

$SYS/broker/bytes/# 這個主題每隔 10 秒會輸出統計資訊,類似這樣:

$SYS/broker/bytes/received 1008
$SYS/broker/bytes/sent 253
$SYS/broker/bytes/received 1092
$SYS/broker/bytes/sent 325

有收到訊息就表示正常。

Step 6
使用密碼配合 TLS 安全加密,訂閱 gtwang/test 主題:

mosquitto_sub -t gtwang/test -u gtwang -P secret123 
  --cafile ca.crt

使用密碼配合 TLS 安全加密,發送訊息至 gtwang/test 主題:

mosquitto_pub -t gtwang/test -u gtwang -P secret123 
  -m "Hello, world!" --cafile ca.crt

連接手機與電腦

在 Mosquitto 的 MQTT broker 伺服器架設好之後,任何支援 MQTT 協定的設備都可以直接連線進來傳送或是接收訊息,這裡我們以一台 Android 手機作為示範,將樹莓派上的訊息傳送至手機,並同時也可以將手機上的訊息傳回樹莓派。

在 Andorid 手機上有非常多 MQTT client 的 app,這次我選擇 IoT MQTT Dashboard 這一款支援加密的 MQTT client app 來做示範,而這個 app 在建立加密連線時需要讀取 BKS 格式的憑證檔案,所以我們要先把自己的 ca.crt 轉為 BKS 檔。

Step 1
bouncycastle.org 下載 bcprov-ext-jdk15on-156.jar

wget http://bouncycastle.org/download/bcprov-ext-jdk15on-156.jar

Step 2
ca.crt 轉換為 BKS 檔:

keytool -importcert -v -trustcacerts -file ca.crt 
  -alias IntermediateCA -keystore android.bks 
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider 
  -providerpath bcprov-ext-jdk15on-156.jar 
  -storetype BKS -storepass mysecret

其中 mysecret 可以換成自己的密碼。

Step 3
將 轉換好的 BKS 檔 android.bks 複製到 Android 手機上,然後開啟 IoT MQTT Dashboard 進行設定,填入樹莓派的基本資訊(左圖)。

Server 欄位就填入樹莓派的 IP 位址(可用 ifconfig 指令查詢),連接埠(Port)預設是 1883,Username 與 Password 就是剛剛上面新增的Mosquitto 帳號與密碼,將 SSL 打勾之後,並填入剛剛產生的 BKS 檔,還有 BKS 檔的密碼。

Android 手機 MQTT Dashboard

設定好 MQTT 伺服器之後,新增一個 Subscribe 設定,也就是訂閱一個主題,這裡我以 gtwang/test 這個主題做示範。

Step 4
在樹莓派中執行以下指令,送出兩則測試訊息。

mosquitto_pub -t gtwang/test -u gtwang -P secret123 
  -m "Hello, world!" --cafile ca.crt
mosquitto_pub -t gtwang/test -u gtwang -P secret123 
  -m "This is a test." --cafile ca.crt

Step 5
查看 Android 手機上的 MQTT Dashboard 訊息,正常的話這樣就可以收到從樹莓派發送出來的兩則訊息了。

Android 手機 MQTT Dashboard

Step 6
讓 Android 手機發布訊息至樹莓派中,在 MQTT Dashboard 中新增一個 Publish 設定,發送訊息至 gtwang/test 主題。

這時候在樹莓派中就可以使用 Mosquitto 的 client 接收這個來自於 Android 手機的訊息。

Mosquitto client

這裡我們是將 Android 手機發送的訊息也送進 gtwang/test 主題中,而 Android 手機本身也是這個主題的訊息訂閱者,所以自己也會收到這則訊息,如果不想讓自己也收到訊息的話,可以更換訊息的主題(例如 gtwang/test2),要如何設計訊息的主題就要看實際的需求而定。

基本上不管訊息要從哪個設備發送,以及從哪個設備接收,只要依循 MQTT 的協定、設定好訊息主題,任何設備都可以非常容易地互相溝通,因此 MQTT 在物聯網的應用上可以說是相當有發展性的技術。

參考資料:instructablesRockingD LabsPrimal Cortex’s WeblogIOT BYTES智慧生活科技專業社群StackOverflow

樹莓派, 物聯網
  1. df

    安全加密 TLS 連線:
    STEP5步驟:出現以下訊息
    Error: Problem setting TLS options.

  2. Jennifer

    可否請教一下 我在安裝時出現以下情況 Err http://mirrordirector.raspbian.org/raspbian/ jessie/main mosquitto armhf 1.3.4-2+deb8u1
    Could not resolve ‘mirrordirector.raspbian.org’
    E: Failed to fetch http://mirrordirector.raspbian.org/raspbian/pool/main/m/mosquitto/mosquitto_1.3.4-2+deb8u1_armhf.deb Could not resolve ‘mirrordirector.raspbian.org’

    E: Unable to fetch some archives, maybe run apt-get update or try with –fix-missing?
    root@ittraining:~# apt-get update
    Err http://archive.raspberrypi.org jessie InRelease

    Err http://mirrordirector.raspbian.org jessie InRelease

    Err http://archive.raspberrypi.org jessie Release.gpg
    Could not resolve ‘archive.raspberrypi.org’
    Err http://mirrordirector.raspbian.org jessie Release.gpg
    Could not resolve ‘mirrordirector.raspbian.org’
    Reading package lists… Done
    W: Failed to fetch http://mirrordirector.raspbian.org/raspbian/dists/jessie/InRelease

    W: Failed to fetch http://archive.raspberrypi.org/debian/dists/jessie/InRelease

    W: Failed to fetch http://archive.raspberrypi.org/debian/dists/jessie/Release.gpg Could not resolve ‘archive.raspberrypi.org’

    W: Failed to fetch http://mirrordirector.raspbian.org/raspbian/dists/jessie/Release.gpg Could not resolve ‘mirrordirector.raspbian.org’

    W: Some index files failed to download. They have been ignored, or old ones used instead.

  3. Eric Lin

    請問:

    手機MQTT(樹莓派)MCU,
    請問上述如何實現?

    謝謝.

Leave a Reply