MQTT是一種機(jī)器到機(jī)器消息協(xié)議,旨在為“物聯(lián)網(wǎng)”設(shè)備提供輕量級(jí)發(fā)布/訂閱通信栓霜。 Mosquitto是一個(gè)受歡迎的MQTT服務(wù)器(或代理坦袍,在MQTT中的用法),具有良好的社區(qū)支持避乏,易于安裝和配置。在本教程中甘桑,我們將安裝Mosquitto拍皮,從Let's Encrypt檢索SSL證書歹叮,并設(shè)置我們的代理使用SSL來保護(hù)受密碼保護(hù)的MQTT通信。
介紹
MQTT是一種機(jī)器到機(jī)器消息協(xié)議铆帽,旨在為“物聯(lián)網(wǎng)”設(shè)備提供輕量級(jí)發(fā)布/訂閱通信咆耿。它通常用于車輛的地理跟蹤車隊(duì),家庭自動(dòng)化爹橱,環(huán)境傳感器網(wǎng)絡(luò)和公用事業(yè)規(guī)模的數(shù)據(jù)收集萨螺。 Mosquitto是一個(gè)受歡迎的MQTT服務(wù)器(或代理 ,在MQTT中的用法)愧驱,具有良好的社區(qū)支持慰技,易于安裝和配置。 在本教程中组砚,我們將安裝Mosquitto吻商,從Let's Encrypt檢索SSL證書,并設(shè)置我們的代理使用SSL來保護(hù)受密碼保護(hù)的MQTT通信糟红。
先決條件
在開始本教程之前艾帐,您需要:
具有非root,啟用sudo的用戶和基本防火墻的CentOS 7服務(wù)器盆偿。這個(gè)(和更多)在新的CentOS 7服務(wù)器清單中有所有柒爸。
指向您的服務(wù)器的域名,按照如何使用DigitalOcean設(shè)置主機(jī)名 事扭。本教程將使用mqtt.example.com揍鸟。
可選,
nano
文本編輯器句旱。 安裝您喜歡的文本編輯器。 本教程將使用nano
整個(gè)晰奖,你可以隨時(shí)安裝它與sudo yum -y install nano
谈撒。
第1步 - 安裝Mosquitto
默認(rèn)情況下,CentOS 7沒有mosquitto包匾南。要安裝它啃匿,我們將首先安裝一個(gè)名為Extra Packages for Enterprise Linux或EPEL的額外軟件存儲(chǔ)庫。這個(gè)存儲(chǔ)庫包含了在CentOS蛆楞,Red Hat和其他面向企業(yè)的Linux發(fā)行版上安裝的附加軟件溯乒。 使用非root用戶登錄,并使用yum軟件包管理器安裝epel-release軟件包豹爹。
sudo yum -y install epel-release
這將EPEL存儲(chǔ)庫信息添加到我們的系統(tǒng)裆悄。-y選項(xiàng)會(huì)在整個(gè)過程中自動(dòng)為yes回答幾個(gè)提示。 現(xiàn)在我們可以安裝mosquitto包臂聋。
sudo yum -y install mosquitto
該包有一個(gè)簡單的默認(rèn)配置光稼,所以讓我們運(yùn)行它來測試我們的安裝或南。
sudo systemctl start mosquitto
我們還需要啟用服務(wù),以確保它啟動(dòng)時(shí)艾君,我們重新啟動(dòng)系統(tǒng):
sudo systemctl enable mosquitto
現(xiàn)在讓我們測試默認(rèn)配置采够。mosquitto包附帶一些命令行MQTT客戶端。我們將使用其中一個(gè)訂閱我們的經(jīng)紀(jì)人的主題冰垄。 主題是您向其發(fā)布消息和訂閱的標(biāo)簽蹬癌。 它們被布置為層次結(jié)構(gòu),因此虹茶,例如逝薪,您可以具有sensors/outside/temp和sensors/outside/humidity 。如何安排主題取決于你和你的需要写烤。在本教程中翼闽,我們將使用一個(gè)簡單的測試主題來測試我們的配置更改。 第二次登錄到您的服務(wù)器洲炊,因此您有兩個(gè)端子并排感局。在新終端中,使用mosquitto_sub訂閱測試主題:
mosquitto_sub -h localhost -t test
-h用于指定MQTT服務(wù)器的主機(jī)名暂衡, -t是主題名询微。 由于mosquitto_sub正在等待消息到達(dá),因此在按ENTER后沒有輸出狂巢。切換回您的其他終端并發(fā)布消息:
mosquitto_pub -h localhost -t test -m "hello world"
mosquitto_pub的選項(xiàng)與mosquitto_pub相同撑毛,但是這次我們使用附加的-m選項(xiàng)來指定我們的消息。 按ENTER 唧领,你應(yīng)該看到hello world彈出在另一個(gè)終端藻雌。您發(fā)送了第一個(gè)MQTT消息! 在第二個(gè)終端中輸入CTRL+C 斩个,退出mosquitto_sub 胯杭,但保持與服務(wù)器的連接打開。我們將在第5步中再次使用它進(jìn)行另一個(gè)測試受啥。 接下來做个,我們將使用Certbot(新的Let's Encrypt客戶端)使用SSL保護(hù)我們的安裝。
第2步 - 安裝并運(yùn)行Certbot讓我們加密證書
Let's Encrypt是一項(xiàng)新服務(wù)滚局,通過自動(dòng)API提供免費(fèi)的SSL證書居暖。官方Let's Encrypt客戶端稱為Certbot,它包含在我們?cè)谏弦徊街邪惭b的EPEL存儲(chǔ)庫中藤肢。 用yum安裝Certbot太闺。
sudo yum -y install certbot
Certbot需要回答Let's Encrypt API發(fā)出的加密挑戰(zhàn),以證明我們控制我們的域嘁圈。它使用端口80
(HTTP)和/或443
(HTTPS)來完成此操作跟束。 我們只使用端口80
莺奸,所以讓我們?cè)试S在該端口上的傳入流量。 使用firewall-cmd
添加HTTP服務(wù)冀宴。
sudo firewall-cmd --permanent --add-service=http
重新加載防火墻灭贷,以使更改生效。
sudo firewall-cmd --reload
我們現(xiàn)在可以運(yùn)行Certbot獲取我們的證書略贮。我們將使用--standalone
選項(xiàng)告訴Certbot自己處理HTTP質(zhì)詢請(qǐng)求甚疟,以及--standalone-supported-challenges http-01
將通信限制為端口80
。 -d
用于指定您想要證書的域逃延,并且certonly
告知Certbot只是檢索證書览妖,而不執(zhí)行任何其他配置步驟。
sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com
運(yùn)行命令時(shí)揽祥,系統(tǒng)將提示您輸入電子郵件地址并同意服務(wù)條款讽膏。這樣做后,您應(yīng)該會(huì)看到一條消息拄丰,告訴您進(jìn)程成功以及您的證書存儲(chǔ)在何處府树。 我們有我們的證書。現(xiàn)在我們需要確保Certbot在它們即將到期時(shí)自動(dòng)更新它們料按。
第3步 - 設(shè)置Certbot自動(dòng)續(xù)訂
讓我們加密的證書只有九十天有效奄侠。這是為了鼓勵(lì)用戶自動(dòng)執(zhí)行證書續(xù)訂過程。我們需要設(shè)置一個(gè)定期運(yùn)行的命令來檢查到期的證書并自動(dòng)更新载矿。 為了每天運(yùn)行更新檢查垄潮,我們將使用cron
作為運(yùn)行周期性作業(yè)的標(biāo)準(zhǔn)系統(tǒng)服務(wù)。 我們通過打開和編輯名為crontab
的文件告訴cron
要做什么闷盔。
sudo EDITOR=nano crontab -e
EDITOR=nano
將使nano
編輯器中的crontab文件打開弯洗。 如果您希望使用默認(rèn)vi
編輯器,請(qǐng)將其關(guān)閉逢勾。 您現(xiàn)在應(yīng)該看到默認(rèn)的crontab
涂召,一個(gè)空白文件。粘貼到以下行敏沉,然后保存并關(guān)閉文件。
crontab
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"
該行的15 3 * * *
部分表示“每天上午3:15運(yùn)行以下命令”炎码。 Certbot的renew
命令將檢查系統(tǒng)上安裝的所有證書盟迟,并更新任何設(shè)置為在三十天內(nèi)到期的證書。 --noninteractive
告知Certbot不要等待用戶輸入潦闲。 --post-hook "systemctl restart mosquitto"
將重新啟動(dòng)Mosquitto以獲取新證書攒菠,但前提是證書已更新。 現(xiàn)在歉闰,自動(dòng)證書更新已設(shè)置辖众,我們將回到配置Mosquitto更安全卓起。
第4步 - 配置MQTT密碼
讓我們配置Mosquitto使用密碼。 Mosquitto包含一個(gè)實(shí)用程序來生成一個(gè)名為mosquitto_passwd
的特殊密碼文件凹炸。 此命令將提示您輸入指定用戶名的密碼戏阅,并將結(jié)果放在/etc/mosquitto/passwd
。
sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
現(xiàn)在我們將替換默認(rèn)配置文件啤它,并告訴Mosquitto使用此密碼文件要求所有連接登錄奕筐。首先,刪除現(xiàn)有的mosquitto.conf
变骡。
sudo rm /etc/mosquitto/mosquitto.conf
現(xiàn)在打開一個(gè)新的离赫,空白的配置。
sudo nano /etc/mosquitto/mosquitto.conf
粘貼在以下塌碌。
/etc/mosquitto/mosquitto.conf
allow_anonymous false
password_file /etc/mosquitto/passwd
allow_anonymous false
將禁用所有未驗(yàn)證的連接渊胸, password_file
行告訴Mosquitto在哪里查找用戶和密碼信息。保存并退出文件台妆。 現(xiàn)在我們需要重新啟動(dòng)Mosquitto并測試我們的更改翎猛。
sudo systemctl restart mosquitto
嘗試發(fā)布不帶密碼的郵件。
mosquitto_pub -h localhost -t "test" -m "hello world"
該郵件應(yīng)該被拒絕:
Connection Refused: not authorised.
Error: The connection was refused.
在我們?cè)俅螄L試使用密碼频丘,再次切換到您的第二個(gè)終端窗口办成,并訂閱'測試'主題,使用用戶名和密碼這次:
mosquitto_sub -h localhost -t test -u "sammy" -P "password"
它應(yīng)該連接和坐搂漠,等待消息迂卢。您可以將此終端保持打開并連接到本教程的其余部分,因?yàn)槲覀儗⒍ㄆ诎l(fā)送測試消息桐汤。 現(xiàn)在與您的其他終端發(fā)布消息而克,再次使用用戶名和密碼:
mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"
消息應(yīng)該通過,如第1步中所示怔毛。我們已成功添加密碼保護(hù)Mosquitto员萍。不幸的是,我們通過互聯(lián)網(wǎng)發(fā)送密碼未加密拣度。我們將通過添加SSL加密到Mosquitto來解決碎绎。
第5步 - 配置MQTT SSL
要啟用SSL加密,我們需要告訴Mosquitto我們的加密證書存儲(chǔ)在哪里抗果。打開我們以前啟動(dòng)的配置文件筋帖。
sudo nano /etc/mosquitto/mosquitto.conf
粘貼到文件末尾的下面,留下我們已經(jīng)添加的兩行:
/etc/mosquitto/mosquitto.conf
. . .
listener 1883 localhost
listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
我們?cè)谂渲弥刑砑恿藘蓚€(gè)獨(dú)立的listener
塊冤馏。 第一個(gè)日麸, listener 1883 localhost
更新端口1883
上的默認(rèn)MQTT監(jiān)聽器,這是我們一直連接到目前為止逮光。 1883
是標(biāo)準(zhǔn)的未加密MQTT端口代箭。 該行的localhost
部分指示Mosquitto僅將此端口綁定到localhost接口墩划,因此無法從外部訪問。外部請(qǐng)求將被我們的防火墻阻止嗡综,但是很好明確乙帮。 listener 8883
在端口8883
上設(shè)置加密的監(jiān)聽器。 這是MQTT + SSL的標(biāo)準(zhǔn)端口蛤高,通常稱為MQTTS蚣旱。 接下來的三行, certfile
戴陡, cafile
和keyfile
塞绿,都將Mosquitto指向相應(yīng)的Let's Encrypt文件來設(shè)置加密連接。 保存并退出文件恤批。 在我們重新啟動(dòng)Mosquitto加載新的配置之前异吻,我們需要修復(fù)默認(rèn)mosquitto
服務(wù)文件中的一件事。 這是systemd
用來確定如何運(yùn)行mosquitto
喜庞。在您喜歡的編輯器中打開它诀浪。
sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service
查找一條表示User=mosquitto
并將其刪除的行嘴脾,然后保存并退出該文件纲堵。 Mosquitto仍將作為mosquitto用戶運(yùn)行,但是當(dāng)它首次啟動(dòng)時(shí)余佛,它將具有root權(quán)限晰房,并且將能夠加載我們的Let's Encrypt證書(出于安全原因求摇,它被限制為root訪問權(quán)限)。 加載證書后殊者,它將下載到蚊子用戶与境。 我們需要重新加載systemd
本身,所以它注意到我們對(duì)服務(wù)文件所做的更改猖吴。
sudo systemctl daemon-reload
現(xiàn)在我們可以重新啟動(dòng)Mosquitto更新設(shè)置摔刁。
sudo systemctl restart mosquitto
更新防火墻以允許連接到端口8883
。
sudo firewall-cmd --permanent --add-port=8883/tcp
并重新加載防火墻海蔽。
sudo firewall-cmd --reload
現(xiàn)在我們?cè)俅问褂?code>mosquitto_pub測試共屈,有幾個(gè)不同的SSL選項(xiàng)。
mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"
請(qǐng)注意党窜,我們使用完整的主機(jī)名而不是localhost
拗引。 因?yàn)槲覀兊腟SL證書是針對(duì)mqtt.example.com
發(fā)出的,如果我們嘗試到localhost
的安全連接刑然,我們會(huì)收到一個(gè)錯(cuò)誤,指出主機(jī)名與證書主機(jī)名不匹配(即使它們都指向同一個(gè)Mosquitto服務(wù)器)暇务。 --cafile /etc/ssl/certs/ca-bundle.crt
為--cafile /etc/ssl/certs/ca-bundle.crt
啟用S??SL泼掠,并告知它在哪里查找根證書怔软。 這些通常由操作系統(tǒng)安裝,因此對(duì)于Mac OS择镇,Windows等挡逼, mosquitto_pub
使用根證書來驗(yàn)證Mosquitto服務(wù)器的證書是否由Let's Encrypt證書頒發(fā)機(jī)構(gòu)正確簽名。 請(qǐng)注意腻豌,即使您連接到8883
的標(biāo)準(zhǔn)安全端口家坎, mosquitto_pub
和mosquitto_sub
也不會(huì)嘗試使用此選項(xiàng)(或類似的--capath
選項(xiàng))的SSL連接。 如果一切順利的測試吝梅,我們會(huì)看到你好再次出現(xiàn)在另一個(gè)mosquitto_sub
終端虱疏。這意味著您的服務(wù)器已完全設(shè)置!如果你想擴(kuò)展MQTT協(xié)議來使用websockets苏携,你可以按照最后一步做瞪。
第6步 - 通過WebSocket配置MQTT(可選)
為了使用Web瀏覽器中的JavaScript來講MQTT,協(xié)議適用于在標(biāo)準(zhǔn)websockets上工作右冻。如果您不需要此功能装蓬,則可以跳過此步驟。 我們需要添加一個(gè)listener
塊到我們的Mosquitto配置纱扭。
sudo nano /etc/mosquitto/mosquitto.conf
在文件的末尾牍帚,添加以下內(nèi)容:
/etc/mosquitto/mosquitto.conf
. . .
listener 8083
protocol websockets
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
這protocol websockets
與上一個(gè)塊相同,除了端口號(hào)和protocol websockets
行乳蛾。 沒有用于MQTT的官方標(biāo)準(zhǔn)化端口通過websockets暗赶,但8083
是最常見的。 保存并退出文件屡久,然后重新啟動(dòng)Mosquitto忆首。
sudo systemctl restart mosquitto
現(xiàn)在,打開防火墻中的端口8083
被环。
sudo firewall-cmd --permanent --add-port=8083/tcp
并且最后一次重新加載防火墻糙及。
sudo firewall-cmd --reload
為了測試這個(gè)功能,我們將使用一個(gè)基于瀏覽器的公共MQTT客戶端筛欢。有幾個(gè)浸锨,但是mqtt-admin是簡單和直接。 在瀏覽器中打開mqtt-admin 版姑。您將看到以下內(nèi)容:
按如下所示填寫連接信息:
- 協(xié)議應(yīng)該是wss (這代表web的ocket s ecure)柱搜。
-
主機(jī)應(yīng)該是您的Mosquitto服務(wù)器的域,
mqtt.example.com
剥险。 -
端口應(yīng)為
8083
聪蘸。 - 用戶應(yīng)該是您的Mosquitto用戶名; 在這里,我們使用sammy 。
- 密碼應(yīng)該是您選擇的密碼健爬。
- ClientId可以保留默認(rèn)值mqtt-admin 控乾。
按下保存設(shè)置后 , mqtt-admin
將連接到您的Mosquitto服務(wù)器娜遵。 在下一個(gè)屏幕中蜕衡,填寫Topic作為測試 ,輸入任何有關(guān)Payload的消息设拟,然后按發(fā)布 慨仿。 該消息將顯示在mosquitto_sub
終端中。
結(jié)論
我們現(xiàn)在已經(jīng)設(shè)置了一個(gè)安全的纳胧,密碼保護(hù)的MQTT服務(wù)器镰吆,使用來自Let's Encrypt服務(wù)的自動(dòng)更新SSL證書。這將作為一個(gè)強(qiáng)大和安全的消息平臺(tái)躲雅,用于任何項(xiàng)目你夢想鼎姊。一些流行的軟件和硬件與MQTT協(xié)議工作良好包括:
- OwnTracks是一個(gè)開源的地理跟蹤應(yīng)用,您可以在手機(jī)上安裝相赁。 OwnTracks將定期向MQTT服務(wù)器報(bào)告位置信息相寇,然后您可以將其存儲(chǔ)和顯示在地圖上,或根據(jù)您的位置創(chuàng)建警報(bào)并激活物聯(lián)網(wǎng)硬件钮科。
- Node-RED是一個(gè)基于瀏覽器的圖形界面唤衫,用于將物聯(lián)網(wǎng)“布線”在一起。您將一個(gè)節(jié)點(diǎn)的輸出拖動(dòng)到另一個(gè)節(jié)點(diǎn)的輸入绵脯,并可以通過過濾器佳励,在各種協(xié)議之間將信息路由到數(shù)據(jù)庫等。 MQTT得到了Node-RED的很好的支持蛆挫。
- ESP8266是一個(gè)具有MQTT功能的便宜的wifi微控制器赃承。你可以連接一個(gè)發(fā)布溫度數(shù)據(jù)到一個(gè)主題,或者訂閱氣壓壓力主題悴侵,并在暴風(fēng)雨來臨時(shí)發(fā)出蜂鳴聲瞧剖!
這些只是MQTT生態(tài)系統(tǒng)中的幾個(gè)流行示例。有更多的硬件和軟件在那里說的協(xié)議可免。如果你已經(jīng)有一個(gè)喜歡的硬件平臺(tái)或軟件語言抓于,它可能有MQTT功能。有樂趣讓你的“東西”彼此交談浇借!