Mqtt 是一种机对机的消息传递协议,旨在为物联网设备提供轻量级的发布/订阅通信。 它通常用于车辆的地理跟踪车队,家庭自动化,环境传感器网络,和公用事业规模的数据收集。
Mosquito 是一个流行的 MQTT 服务器(或者用 MQTT 的说法是代理) ,它有很好的社区支持,并且易于安装和配置。
在本教程中,我们将安装 mosquito,从 Let’s Encrypt 检索 SSL 证书,并将代理设置为使用 SSL 来保护受密码保护的 MQTT 通信。
在开始本教程之前,你需要:
设置了一个 CentOS 7服务器,该服务器具有一个非 root、支持 sudo 的用户和一个基本的防火墙。 新 CentOS 7服务器检查列表中包含了所有这些(以及更多)。 一个域名指向你的服务器,就像如何用 DigitalOcean 设置主机名一样。 本教程将在整个过程中使用 mqtt.example.com。 还可以选择使用纳米文本编辑器。 本教程将使用 nano 贯穿始终,你可以在任何时候用 sudo yum-y 安装 nano 安装它,或者替换你喜欢的文本编辑器。
缺省情况下 CentOS 7没有一个需要打包的蚊子。 为了安装它,我们将首先安装一个额外的 Linux 软件资源库,称为企业 Linux 的额外软件包,或者称为 EPEL。 这个存储库充满了可以很好地安装在 CentOS、 Red Hat 和其他面向企业的 Linux 发行版上的附加软件。
使用非 root 用户登录并使用 yum 包管理器安装 epel-release 包。
sudo yum -y install epel-release这将向我们的系统添加 EPEL 存储库信息。 Y 选项会自动对整个过程中的几个提示回答 yes。 现在我们可以安装蚊子包。
sudo yum -y install mosquitto这个包有一个简单的默认配置,所以让我们运行它来测试我们的安装。
sudo systemctl start mosquitto我们还需要启用该服务,以确保在重新启动系统时启动:
sudo systemctl enable mosquitto现在让我们测试默认配置。 Mosquito 包附带了一些命令行 MQTT 客户机。 我们将使用其中一个订阅我们代理的主题。
主题是发布邮件到并订阅的标签。 它们被安排成一个层次结构,例如,你可以有传感器 / 外部 / 温度和传感器 / 外部 / 湿度。 如何安排话题取决于你自己和你的需要。 在本教程中,我们将使用一个简单的测试主题来测试我们的配置更改。
第二次登录到您的服务器,这样您就有两个并排的终端。 在新的终端,使用蚊子子订阅测试主题:
mosquitto_sub -h localhost -t testH 用于指定 MQTT 服务器的主机名,-t 是主题名。 你会看到没有输出后,按下 ENTER,因为蚊子子正在等待消息到达。 切换回你的另一个终端并发布一条消息:
mosquitto_pub -h localhost -t test -m "hello world"蚊子到酒吧的选项是相同的蚊子到次,虽然这一次我们使用额外的-m 选项,以指定我们的信息。 点击回车,你应该会看到 hello world 在另一个终端弹出。 您已经发送了您的第一条 MQTT 消息!
在第二个终端输入 ctrl + c 以退出 mosquito 子,但保持到服务器的连接打开。 我们将在第5步中再次使用它进行另一个测试。
接下来,我们将使用 Certbot (新的 Let’s Encrypt 客户机)使用 SSL 保护我们的安装。
Let’s Encrypt 是一个通过自动化 API 提供免费 SSL 证书的新服务。 官方的 Let’s Encrypt 客户机名为 Certbot,它包含在我们在前面步骤中安装的 EPEL 存储库中。
用 yum 安装 Certbot。
sudo yum -y install certbotCertbot 需要回答 Let’s Encrypt API 发出的加密挑战,以证明我们控制了域。 它使用端口80(HTTP)和 / 或443(HTTPS)来实现这一点。 我们将只使用端口80,所以现在让我们允许在该端口上传入通信量。
使用 firewall-cmd 添加 HTTP 服务。
sudo firewall-cmd --permanent --add-service=http重新装载防火墙,使更改生效。
sudo firewall-cmd --reload我们现在可以运行 Certbot 来获得我们的证书。 我们将使用 – standalone 选项告诉 Certbot 自己处理 HTTP 挑战请求,而 – standalone-supported-challenges HTTP-01将通信限制在端口80。 D 用于指定希望获得证书的域,certonly 告诉 Certbot 只检索证书,而不需要执行任何其他配置步骤。
sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com在运行该命令时,系统将提示您输入一个电子邮件地址并同意服务条款。 这样做之后,您应该会看到一条消息,告诉您流程已经成功,以及证书存储在哪里。
我们已经获得了证书,现在我们需要确保 Certbot 在证书即将到期时自动更新它们。
Let’s Encrypt 的证书只有90天的有效期。 这是为了鼓励用户自动化他们的证书更新过程。 我们需要设置一个定期运行的命令来检查到期证书并自动更新它们。
为了每天运行续约检查,我们将使用 cron,这是一个用于运行周期性作业的标准系统服务。 我们通过打开和编辑一个名为 crontab 的文件告诉 cron 要做什么。
sudo EDITOR=nano crontab -e将在 nano 编辑器中打开 crontab 文件。 如果您喜欢使用缺省的 vi 编辑器,请关闭它。
现在应该显示默认的 crontab,一个空白文件。 粘贴下面的行,然后保存并关闭文件。
crontab 15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"这一行的153 * 部分表示“每天凌晨3:15运行以下命令”。 Certbot 的续订命令将检查系统上安装的所有证书,并更新任何设置为在30天内过期的证书。 – 非交互式告诉 Certbot 不要等待用户输入。
– post-hook“ systemctl restart mosquito”将重启 Mosquitto 以获得新的证书,但前提是证书必须更新。
现在已经设置了自动证书更新,我们将继续配置 mosquito 以使其更加安全。
让我们设置蚊子使用密码。 Mosquito 包含一个工具,可以生成一个名为 mosquito passwd 的特殊密码文件。 这个命令将提示您输入指定用户名的密码,并将结果放在 / etc /
mosquito / passwd 中。 sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy现在我们将替换默认的配置文件,并告诉 mosquito 使用这个密码文件要求所有连接都登录。 首先,删除现有的 mosquito. conf。
sudo rm /etc/mosquitto/mosquitto.conf现在打开一个新的空白配置。
sudo nano /etc/mosquitto/mosquitto.conf粘贴到下面。
/etc/mosquitto/mosquitto.conf allow_anonymous false password_file /etc/mosquitto/passwdAllow anonymous false 将禁用所有未经身份验证的连接,密码文件行告诉 Mosquitto 在哪里查找用户和密码信息。 保存并退出文件。
现在我们需要重新启动 mosquito 并测试我们的变化。
sudo systemctl restart mosquitto尝试在没有密码的情况下发布消息。
mosquitto_pub -h localhost -t "test" -m "hello world"这个信息应该被拒绝:
Output Connection Refused: not authorised. Error: The connection was refused.在我们再次尝试输入密码之前,请再次切换到第二个终端窗口,并订阅“测试”主题,这次使用用户名和密码:
mosquitto_sub -h localhost -t test -u "sammy" -P "password"它应该连接并静坐,等待信息。 在本教程的其余部分中,您可以保持这个终端处于开放状态并与其连接,因为我们将定期向其发送测试消息。
现在用另一个终端发布一条消息,同样使用用户名和密码:
mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"该消息应该按照步骤1进行传递。 我们已经成功地为蚊子增加了密码保护。 不幸的是,我们在互联网上发送未加密的密码。 我们接下来将通过在 Mosquitto 加入 SSL 加密来解决这个问题。
要启用 SSL 加密,我们需要告诉 mosquito 我们的 Let’s Encrypt 证书存储在哪里。 打开我们先前启动的配置文件。
sudo nano /etc/mosquitto/mosquitto.conf在文件末尾粘贴以下内容,保留我们已经添加的两行:
/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我们在配置中添加了两个独立的侦听器块。 第一个是侦听器1883 localhost,它在端口1883上更新缺省的 MQTT 侦听器,到目前为止我们一直连接到这个端口。 1883是标准的未加密 MQTT 端口。 该行的 localhost 部分指示 Mosquitto 只将该端口绑定到 localhost 接口,因此外部无法访问该端口。 外部请求无论如何都会被我们的防火墙阻止,但是显式的请求是好的。
监听器8883在8883端口设置了一个加密监听器。 这是 MQTT + SSL 的标准端口,通常称为 MQTTS。 接下来的三行代码 certfile、 cafile 和 keyfile 都将 mosquito 指向适当的 Let’s Encrypt 文件以设置加密连接。
保存并退出文件。
在重新启动 mosquito 以加载新配置之前,我们需要修复默认 mosquito 服务文件中的一个内容。 这是 systemd 用来确定如何运行蚊子的文件。 用你最喜欢的编辑器打开它。
sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service寻找一行,说用户蚊子和删除它,然后保存和退出文件。
Mosquito 仍将作为蚊子对用户运行,但当它第一次启动时,它将拥有 root 特权,并将能够加载我们的 Let’s Encrypt 证书(出于安全原因,这些证书仅限于 root 访问)。 加载证书后,它将下降到蚊子用户。
我们需要重新加载 systemd 本身,这样它就会注意到我们对服务文件所做的更改。
sudo systemctl daemon-reload现在我们可以重新启动 mosquito 来更新设置。
sudo systemctl restart mosquitto更新防火墙以允许连接到端口8883。
sudo firewall-cmd --permanent --add-port=8883/tcp重新装载防火墙。
sudo firewall-cmd --reload现在我们再次使用蚊子到酒吧进行测试,使用一些不同的 SSL 选项。
mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"注意,我们使用的是完整的主机名而不是本地主机。 因为我们的 SSL 证书是为 mqtt.example.com 服务器颁发的,如果我们尝试一个到本地主机的安全连接,我们会得到一个错误,说主机名与证书主机名不匹配(即使它们都指向同一个 mosquito 服务器)。
– cafile / etc / ssl / certs / ca-bundle. Crt 启用 SSL for mosquito to pub,并告诉它在哪里寻找根证书。 这些通常是由你的操作系统安装的,所以 Mac OS,Windows 等系统的路径是不同的。 蚊子酒吧使用加密根证书来验证蚊子酒吧服务器的证书是否由 Let’ s Encrypt 认证机构正确签署。 需要注意的是,如果没有这个选项(或类似的 capath 选项) ,mosquito to pub 和 mosquito to sub 将不会尝试 SSL 连接,即使您连接到标准的安全端口8883。
如果一切顺利的测试,我们将看到 hello 再次出现在其他次终端的蚊子。 这意味着您的服务器已经完全设置好了! 如果希望扩展 MQTT 协议以使用 websocket,可以按照最后一步操作。
为了在 web 浏览器中使用 JavaScript 来说明 MQTT,该协议被调整为可以在标准的 websocket 上工作。 如果你不需要这个功能,你可以跳过这一步。
我们需要添加一个更多的侦听器块到我们的蚊子配置。
sudo nano /etc/mosquitto/mosquitto.conf在文件的末尾,添加以下内容:
/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 websocket 行之外,这基本上与前一个块相同。 在 websockets 上没有 MQTT 的官方标准化端口,但8083是最常见的。
保存并退出文件,然后重新启动 mosquito。
sudo systemctl restart mosquitto现在,打开防火墙中的8083端口。
sudo firewall-cmd --permanent --add-port=8083/tcp再最后一次重新装载防火墙。
sudo firewall-cmd --reload为了测试这个功能,我们将使用一个公共的、基于浏览器的 MQTT 客户机。 现在已经有了一些,但是 mqtt-admin 非常简单和直接。 在浏览器中打开 mqtt-admin。 你会看到以下内容:
协议应该是 wss (即 web socket secure)。 主机应该是你的 mosquito 服务器的域名, mqtt.example.com。 端口应该是8083。 用户名应该是你的蚊子用户名,在这里,我们使用 sammy。 密码应该是您选择的密码。 Clientid 可以保留为默认值 mqtt-admin。 按下保存设置后,mqtt-admin 将连接到您的 mosquito 服务器。 在下一个屏幕中,填写 Topic 作为测试,输入任何有效负载的消息,然后按 Publish。 该信息将显示在蚊子子子终端。
现在,我们已经设置了一个安全的、受密码保护的 MQTT 服务器,该服务器具有来自 Let’s Encrypt 服务的自动更新 SSL 证书。 这将为您构想的任何项目提供一个健壮和安全的消息传递平台。 一些流行的软件和硬件可以很好地与 MQTT 协议协同工作,包括:
Owntracks,一个开源的地理追踪应用,你可以安装在你的手机上。 将定期向你的 MQTT 服务器报告位置信息,然后你可以将这些信息存储并显示在地图上,或者根据你的位置创建警报并激活物联网硬件。 Node-red 是一个基于浏览器的图形界面,用于“连接”物联网。 您可以将一个节点的输出拖动到另一个节点的输入,并且可以通过过滤器、在各种协议之间将信息路由到数据库中,等等。 Mqtt 非常好地支持 Node-RED。 Esp8266是一个便宜的带有 MQTT 功能的 wifi 微控制器。 你可以连接一个来发布一个主题的温度数据,或者订阅一个气压主题,当暴风雨来临时发出蜂鸣器! 这些只是 MQTT 生态系统中的一些流行示例。 还有更多的硬件和软件能够说明这个协议。 如果您已经有了最喜欢的硬件平台或软件语言,那么它可能具有 MQTT 功能。 让你的“东西”彼此交谈愉快!
https://www.zhangtaidong.cn/archives/66/