介绍
MQTT是一个机器到机器的消息协议,旨在为物联网
设备提供轻量级发布/订阅通信,通常用于车辆车队的地理跟踪,家庭自动化,环境传感器网络和公用事业规模的数据收集。
Mosquitto是一个流行的MQTT服务器(或 broker,在MQTT语言中)具有很好的社区支持,易于安装和配置。
在本教程中,我们将安装Mosquitto,从Let's Encrypt获取SSL证书,并设置我们的经纪人使用SSL来保护我们的密码保护的MQTT通信。
前提条件
在开始本教程之前,您将需要:
- 一个 CentOS 7 服务器与一个非根, sudo 允许的用户,和一个基本的防火墙设置. 这(和更多)都被涵盖在 新 CentOS 7 服务器检查清单。
- 一个域名指向您的服务器,按 如何设置一个主机名称与 DigitalOcean。 这个教程将使用
mqtt.example.com
整个. - 可选,
nano
文本编辑器. 这个教程将使用nano
整个,你可以随时安装它与sudo yum -y 安装 nano
,或代替你最喜欢的文本编辑器。
步骤1:安装蚊子
默认情况下,CentOS 7没有蚊子
包,要安装它,我们首先会安装一个名为Extra Packages for Enterprise Linux或EPEL的额外软件存储库,这个存储库充满了额外的软件,可以在CentOS,Red Hat和其他面向企业的Linux发行版上安装。
与您的非根用户登录,并使用yum
包管理器来安装epel-release
包。
1sudo yum -y install epel-release
这将EPEL存储信息添加到我们的系统中。y
选项在整个过程中自动对几个提示回答是。
1sudo yum -y install mosquitto
该包配有简单的默认配置,所以让我们运行它来测试我们的安装。
1sudo systemctl start mosquitto
我们还需要启用该服务,以确保在我们重新启动系统时启动:
1sudo systemctl enable mosquitto
现在让我们来测试默认配置。mosquitto
包配备了一些命令行MQTT客户端,我们将使用其中一个来订阅我们的经纪人主题。
Topics 是您发布消息并订阅的标签,它们分为等级,因此您可以有传感器 / 外部 / 时间
和传感器 / 外部 / 湿度
,例如.您如何安排主题取决于您和您的需求。
登录你的服务器第二次,所以你有两个终端旁边. 在新的终端中,使用mosquitto_sub
订阅测试主题:
1[environment second]
2mosquitto_sub -h localhost -t test
-h
用于指定 MQTT 服务器的主机名称,而 -t
是主题名称. 点击 ENTER
后,您将不会看到输出,因为 mosquitto_sub
正在等待消息到达。
1mosquitto_pub -h localhost -t test -m "hello world"
mosquitto_pub
的选项与mosquitto_sub
相同,但这次我们使用额外的-m
选项来指定我们的消息。点击ENTER
,你应该看到 hello world 在另一个终端出现。
在第二个终端中输入CTRL+C
,以退出mosquitto_sub
,但保持与服务器的连接开放。
接下来,我们将使用Certbot,新的Let's Encrypt客户端,以SSL来保护我们的安装。
步骤 2 — 安装和运行 Let’s Encrypt 证书的 Certbot
Let's Encrypt 是一个新的服务,通过自动化 API 提供免费的 SSL 证书. 官方的 Let's Encrypt 客户端被称为 Certbot,它包含在我们在上一步安装的 EPEL 存储库中。
安装Yum
的Certbot。
1sudo yum -y install certbot
Certbot 需要回答由 Let's Encrypt API 发布的加密挑战,以证明我们控制了我们的域。它使用端口 80 (HTTP) 和/或
443' (HTTPS) 来实现这一目标。
使用防火墙-cmd
添加 HTTP 服务。
1sudo firewall-cmd --permanent --add-service=http
重新加载防火墙,以便更改生效。
1sudo firewall-cmd --reload
现在我们可以运行Certbot来获取我们的证书,我们将使用--standalone
选项告诉Certbot自己处理HTTP挑战请求,而--standalone-supported-challenges http-01
将通信限制到端口80
。
1sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com
在运行命令时,您将被要求输入电子邮件地址并同意服务条款. 这样做后,您应该看到一个消息,告诉您过程成功,您的证书存储在哪里。
现在我们需要确保Certbot在即将到期时自动更新它们。
步骤 3 – 设置 Certbot 自动更新
Let's Encrypt 的证书仅有效90天,以鼓励用户自动更新证书,我们需要设置一个定期运行命令,以检查证书的到期期,并自动更新。
要每天运行更新检查,我们将使用cron
,这是运行定期任务的标准系统服务,我们会告诉cron
通过打开和编辑名为crontab
的文件来做什么。
1sudo EDITOR=nano crontab -e
EDITOR=nano
将使 crontab 文件在 nano
编辑器中打开,如果您喜欢默认 vi
编辑器,则将其关闭。
您现在应该被提供默认的 crontab
,一个空的文件. 粘贴到下一行,然后保存和关闭文件。
1[label crontab]
215 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"
这个行的15 3 * * *
部分意味着每天下午3点15分运行以下命令
。Certbot的更新
命令会检查系统上安装的所有证书,并更新任何在不到30天内到期的证书。
系统ctl mosquitto重新启动
后,Mosquitto 将重新启动以获取新证书,但只有在证书被更新时。
现在自动更新证书已经设置,我们将回到配置Mosquitto以更安全。
第4步:设置MQTT密码
让我们将 Mosquitto 配置为使用密码。 Mosquitto 包含一个工具来生成一个名为mosquitto_passwd
的特殊密码文件. 此命令将提示您为指定用户名输入密码,并将结果放入/etc/mosquitto/passwd
。
1sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
现在我们将更换默认配置文件,并告诉Mosquitto使用此密码文件,以要求所有连接的登录。
1sudo rm /etc/mosquitto/mosquitto.conf
现在打开一个新的,白色配置。
1sudo nano /etc/mosquitto/mosquitto.conf
然后在下面的面包。
1[label /etc/mosquitto/mosquitto.conf]
2allow_anonymous false
3password_file /etc/mosquitto/passwd
allow_anonymous false
会禁用所有未经身份验证的连接,而password_file
行会告诉Mosquitto在哪里搜索用户和密码信息。
现在我们需要重新启动 Mosquitto 并测试我们的变化。
1sudo systemctl restart mosquitto
尝试发布没有密码的消息。
1mosquitto_pub -h localhost -t "test" -m "hello world"
该信息应该被拒绝:
1[secondary_label Output]
2Connection Refused: not authorised.
3Error: The connection was refused.
在我们再次尝试密码之前,再次切换到您的第二个终端窗口,并订阅测试
主题,这次使用用户名和密码:
1[environment second]
2mosquitto_sub -h localhost -t test -u "sammy" -P "password"
它应该连接并坐下来,等待消息. 您可以让这个终端打开并连接至教程的剩余时间,因为我们会定期发送测试消息。
现在用你的其他终端发布消息,再次使用用户名和密码:
1mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"
我们已经成功地将密码保护添加到Mosquitto。不幸的是,我们正在通过互联网发送未加密的密码。我们将通过向Mosquitto添加SSL加密来解决此问题。
步骤 5 – 配置 MQTT SSL
要启用SSL加密,我们需要告诉Mosquitto我们的Let's Encrypt证书存储在哪里。
1sudo nano /etc/mosquitto/mosquitto.conf
在文件的末尾插入以下内容,留下我们已经添加的两行:
1[label /etc/mosquitto/mosquitto.conf]
2. . .
3listener 1883 localhost
4
5listener 8883
6certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
7cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
8keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
我们将两个单独的倾听器
块添加到配置中。第一个倾听器1883 localhost
更新了默认的MQTT倾听器在端口1883上,这是我们迄今为止所连接的。1883
是默认的未加密MQTT端口。
Listener 8883
在端口8883
上设置了一个加密的倾听器,这是MQTT + SSL的标准端口,通常被称为MQTTS。接下来的三个行,certfile
,cafile
和keyfile
,都指向Mosquitto到相应的Let’s Encrypt文件来设置加密连接。
保存和退出文件。
在我们重新启动 Mosquitto 来加载新的 config 之前,我们需要在默认的 mosquitto
服务文件中修复一件事. 这是 systemd
用来确定如何运行 mosquitto
的文件。
1sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service
寻找一条说用户=蚊子
的行,然后删除它,然后保存并退出文件。
Mosquitto 仍将作为 mosquitto 用户运行,但当它首次启动时,它将具有 ** root** 权限,并将能够加载我们的 Let's Encrypt 证书(仅限于 ** root** 访问,出于安全原因)。
我们需要重新加载systemd
,这样它就会注意到我们对服务文件所做的更改。
1sudo systemctl daemon-reload
现在我们可以重新启动 Mosquitto 来更新设置。
1sudo systemctl restart mosquitto
更新防火墙以允许连接到端口8883
。
1sudo firewall-cmd --permanent --add-port=8883/tcp
然后重新加载防火墙。
1sudo firewall-cmd --reload
现在我们再次使用mosquitto_pub
进行测试,为SSL提供了几个不同的选项。
1mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"
请注意,我们正在使用完整的主机名称而不是localhost
。由于我们的SSL证书为mqtt.example.com
发行,如果我们尝试安全连接到localhost
,我们会收到一个错误,称主机名称不匹配证书主机名称(即使它们都指向相同的Mosquitto服务器)。
「--cafile /etc/ssl/certs/ca-bundle.crt」為「mosquitto_pub」啟用SSL,並告訴它要在哪裡尋找根證書。這些通常由您的作業系統安裝,因此路徑不同於Mac OS、Windows等。「mosquitto_pub」使用根證書來確認 Mosquitto 伺服器的證書是否正確由 Let's Encrypt 證書機構簽署。重要的是要注意「mosquitto_pub」和「mosquitto_sub」不會嘗試沒有此選項(或類似的「--capath」選項)的SSL連接,即使您連接到「8883」的標準安全端口。
如果测试顺利,我们将看到 hello再次 在其他mosquitto_sub
终端中出现,这意味着您的服务器已完全设置! 如果您想扩展MQTT协议以与websockets合作,您可以按照最后一步。
步骤 6 — 配置 MQTT 通过 Web 插件(可选)
为了使用JavaScript在网页浏览器中使用MQTT进行交谈,该协议被调整为通过标准网页连接器工作。
我们需要为我们的 Mosquitto 配置添加另一个倾听器
块。
1sudo nano /etc/mosquitto/mosquitto.conf
在文件的末尾,添加以下内容:
1[label /etc/mosquitto/mosquitto.conf]
2. . .
3listener 8083
4protocol websockets
5certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
6cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
7keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
这与前一个区块大多相同,除了端口号和协议网盘
行之外,MQTT网盘上没有官方的标准化端口,但8083
是最常见的。
保存和退出文件,然后重新启动 Mosquitto。
1sudo systemctl restart mosquitto
现在,打开防火墙中的端口8083
。
1sudo firewall-cmd --permanent --add-port=8083/tcp
最后一次重新加载防火墙
1sudo firewall-cmd --reload
要测试这个功能,我们将使用一个公共的,基于浏览器的 MQTT 客户端. 有一些在那里,但 mqtt-admin是简单和简单的。
如下填写连接信息:
- Protocol 应该是 ** wss** (代表 ** w** eb** s** ocket ** s** ecure)。
- Host 应该是您的Mosquitto服务器的域名,
mqtt.example.com
. - Port 应该是
8083
. - 用户 应该是您的Mosquitto用户名;在这里,我们使用了 ** sammy** .
- Password 应该是您选择的密码。
在按下 Save Settings 后,mqtt-admin
将连接到您的 Mosquitto 服务器. 在下一个屏幕上,请填写 ** 主题** 作为 ** 测试** ,输入任何消息为 ** Payload** ,然后按 ** Publish** 。
结论
我们现在已经设置了一个安全的,密码保护的MQTT服务器,从Let's Encrypt服务自动更新SSL证书,这将作为一个强大而安全的消息传输平台,无论您梦想的项目。
- OwnTracks,一个可在手机上安装的开源地理跟踪应用程序。OwnTracks会定期向您的MQTT服务器报告位置信息,然后您可以在地图上存储和显示,或者创建警报并根据您的位置激活物联网硬件。
- Node-RED是一个基于浏览器的图形界面,用于
连接
物联网。您可以将一个节点的输出拖动到另一个节点的输入,并可以通过各种协议之间的过滤器导航信息到数据库,等等。MKTT非常受Node-RED的支持。 - ESP8266是一款具有MTTQ功能的廉价WiFi
这些只是MQTT生态系统中的一些受欢迎的例子,有更多的硬件和软件在外面说话协议. 如果你已经有一个最喜欢的硬件平台,或软件语言,它可能有MQTT功能。