找回密碼
 立即註冊
    查看: 192|回覆: 0

    【MQTT 實作 3】Mosquitto 帳號與 ACL:設定、驗證、以及實測出來的三個陷阱

    [複製鏈接]

    !lvup!   100%

    386

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22006063
    發表於 2026-9-21 11:19:44 | 顯示全部樓層 |閱讀模式
    MQTT 是很多智慧家庭系統的中樞,而它預設沒有任何安全機制。

    更麻煩的是:設錯的時候它不會報錯。權限開太大不會有警告,權限開太小也不會有明顯的錯誤訊息 —— 只是某個服務安靜地收不到某些訊息。

    這篇從一份完整可貼的 mosquitto.conf 開始,做到「你能自己證明權限確實生效」。中間有三個地方跟網路上流傳的做法不一樣,那三個都是實際跑過才發現的。

    設錯的時候它不會報錯。

    做完這篇你會有什麼


    • 一份完整的 mosquitto.conf、一份完整的 ACL 檔,直接複製就能用
    • 每個服務一個帳號,各自只碰得到自己那塊
    • 一套真的能證明 ACL 生效的驗證方法(而不是看起來像生效)
    • 需要跨網段時的 TLS 設定,含自簽憑證的完整產生指令


    需要準備的東西


    • 一台能跑 Docker 的機器。下面用 192.168.1.20 當它的 IP
    • 這台機器上裝好 mosquitto 的命令列工具(下面第四步會用)


    ---

    第一步:先看清楚沒有防護會發生什麼

    MQTT 協定本身的設計是「誰都可以訂閱、誰都可以發布」。broker 不解讀內容,也不知道誰該看什麼。

    所以一台開放匿名連線的 broker,等於把這三件事一起送出去:


    • 訂閱 # 就看得到全部 —— 門窗感測器、人體感測器、門鎖狀態、每一盞燈的開關。連續看幾天就知道你家作息
    • 發布指令就能控制 —— 開燈、關警報、開車庫門。HA 那邊看起來就像是你自己按的
    • 發一則空訊息就能刪裝置 —— 往 homeassistant/sensor/xxx/config 發空的 retain 訊息,HA 裡那個實體立刻消失


    而且這三件事在 HA 的日誌裡都長得跟正常操作一模一樣。

    先確認你現在是哪一種狀態

    在任何一台同網段的電腦上,不帶帳號密碼試連一次:
    1. mosquitto_sub -h 192.168.1.20 -p 1883 -t '#' -v
    複製代碼

    你會看到什麼


    • Connection error: Connection Refused: not authorised. → 匿名連線已經關掉了,很好。繼續往下把 ACL 做完
    • 游標停住,接著開始刷出訊息 → 你的 broker 現在是完全開放的。往下走第二步
    • Error: Connection refused → 1883 沒人聽,broker 沒跑起來


    ---

    第二步:完整的 mosquitto.conf

    存成 /opt/mosquitto/config/mosquitto.conf。這份是可以直接用的完整檔,不是片段。
    1. # ========== 監聽 ==========
    2. # Mosquitto 2.0 起,沒有這一行的話 broker 只綁 127.0.0.1,
    3. # 外面完全連不進來,而且啟動日誌看起來一切正常。
    4. listener 1883
    5. protocol mqtt
    6. # ========== 驗證 ==========
    7. # 2.0 起只要寫了 listener,這個預設就是 false。
    8. # 明寫出來是為了讓讀設定檔的人不必去記預設值。
    9. allow_anonymous false
    10. password_file /mosquitto/config/passwd
    11. # ========== 授權 ==========
    12. # 注意:Mosquitto 2.1 起這個選項被標示為棄用(功能搬進 acl-file 外掛),
    13. # 但選項本身仍然可用,只是啟動時多一行警告。第八步有 2.1 的新做法。
    14. acl_file /mosquitto/config/acl
    15. # ========== 持久化 ==========
    16. # HA 的 MQTT Discovery 完全靠 retain 訊息,這一段不能省,
    17. # 不然 broker 重開之後 HA 裡的 MQTT 裝置會全部消失。
    18. persistence true
    19. persistence_location /mosquitto/data/
    20. autosave_interval 1800
    21. # ========== 日誌 ==========
    22. # log_dest stdout 是給 Docker 用的(docker logs 就看得到)。
    23. # 不跑容器的話改成 log_dest file /mosquitto/log/mosquitto.log
    24. log_dest stdout
    25. log_type error
    26. log_type warning
    27. log_type notice
    28. log_type information
    29. connection_messages true
    30. log_timestamp true
    31. # ========== 限制 ==========
    32. # 家用環境這三行通常不用動,寫出來是讓你知道有這些旋鈕。
    33. max_connections -1
    34. max_queued_messages 1000
    35. max_keepalive 300
    複製代碼

    docker-compose.yml(整份)

    存成 /opt/mosquitto/docker-compose.yml:
    1. services:
    2.   mosquitto:
    3.     image: eclipse-mosquitto:2.0.22
    4.     container_name: mosquitto
    5.     restart: unless-stopped
    6.     ports:
    7.       - "1883:1883"
    8.     volumes:
    9.       - ./config:/mosquitto/config
    10.       - ./data:/mosquitto/data
    11.       - ./log:/mosquitto/log
    12.     environment:
    13.       - TZ=Asia/Taipei
    複製代碼

    ⚠ 版號寫死,不要用 latest

    目前 eclipse-mosquitto:latest 和 eclipse-mosquitto:2 指向的都是 2.1.2,而 2.0 指向 2.0.22。2.1 改了幾個預設值(單一封包上限從 256MB 降到 2,000,000 位元組),也把 acl_file 標示為棄用。

    兩個版本都能用,問題在於「哪天它自己換了」。家用系統最難查的故障就是這種 —— 你什麼都沒改,但行為變了。版號寫死,升級由你決定時機。

    ---

    第三步:建立帳號,一個服務一個

    先想好你要幾個帳號。原則很簡單:每一個會連上 broker 的程式,一個帳號。共用帳號的話,其中一個被拿走等於全部被拿走,而且你從日誌看不出是哪一個出問題。

    典型的家庭配置:


    • homeassistant —— HA 本體,需要全部權限
    • zigbee2mqtt —— Zigbee 協調器
    • frigate —— 影像辨識
    • espdev —— 你自己做的裝置(如果有好幾台,可以再拆細)
    • monitor —— 唯讀帳號,給監控用


    建立:

    以下還有約 80% 的內容
    登入後即可閱讀完整教學

    登入繼續閱讀使用 Google 登入
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    延伸閱讀

    加入惟家 LINE 群 QR Code加入惟家 LINE 群

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-11-10 00:46 , Processed in 0.123930 second(s), 25 queries .

    快速回覆 返回頂部 返回列表